feat(skills): introduce Mem0 skill graph with dedicated CLI and Vercel AI SDK skills (#4725)
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but not
|
||||
limited to compiled object code, generated documentation, and
|
||||
conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work.
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2024 Mem0.ai
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,102 @@
|
||||
# Mem0 CLI Skill for Claude
|
||||
|
||||
Manage memories from the terminal using the [Mem0 CLI](https://docs.mem0.ai/cli). This skill teaches Claude how to use every `mem0` command, flag, and output mode -- for both the Node.js and Python implementations.
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
When installed, Claude can:
|
||||
|
||||
- **Run mem0 commands** correctly in your terminal (add, search, list, get, update, delete, import, config, init, status, entity, event)
|
||||
- **Construct complex invocations** with the right flags, scoping, filters, and output formats
|
||||
- **Pipe and script** mem0 commands in shell workflows, CI/CD pipelines, and agent loops
|
||||
- **Debug issues** like missing API keys, entity scoping conflicts, and async processing delays
|
||||
|
||||
## Installation
|
||||
|
||||
### CLI (Claude Code, OpenCode, OpenClaw, or any tool that supports skills)
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-cli
|
||||
```
|
||||
|
||||
### Claude.ai
|
||||
|
||||
1. Download this `skills/mem0-cli` folder as a ZIP
|
||||
2. Go to **Settings > Capabilities > Skills**
|
||||
3. Click **Upload skill** and select the ZIP
|
||||
|
||||
### Claude API (Skills API)
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.anthropic.com/v1/skills \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "mem0-cli", "source": "https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli"}'
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A Mem0 Platform API key ([Get one here](https://app.mem0.ai/dashboard/api-keys))
|
||||
- **Node.js 18+** or **Python 3.10+**
|
||||
- Install the CLI:
|
||||
|
||||
```bash
|
||||
# Node.js
|
||||
npm install -g @mem0/cli
|
||||
|
||||
# Python
|
||||
pip install mem0-cli
|
||||
```
|
||||
|
||||
- Set the environment variable:
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY="m0-your-api-key"
|
||||
```
|
||||
|
||||
Or run `mem0 init` for the interactive setup wizard.
|
||||
|
||||
## Quick Start
|
||||
|
||||
After installing, just ask Claude:
|
||||
|
||||
- "Add a memory for user alice that she prefers dark mode"
|
||||
- "Search alice's memories for dietary preferences"
|
||||
- "List all memories and output as JSON"
|
||||
- "Delete all memories for user bob"
|
||||
- "Set up mem0 CLI in my CI pipeline"
|
||||
- "Pipe the output of my script into mem0 add"
|
||||
|
||||
## What's Inside
|
||||
|
||||
```text
|
||||
skills/mem0-cli/
|
||||
├── SKILL.md # Skill definition and instructions
|
||||
├── README.md # This file
|
||||
├── LICENSE # Apache-2.0
|
||||
└── references/ # Documentation (loaded on demand)
|
||||
├── command-reference.md # Every command, flag, option, and example
|
||||
├── configuration.md # Config file, env vars, precedence, init wizard
|
||||
└── workflows.md # Piping, scripting, CI/CD, agent mode recipes
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [Mem0 Platform Dashboard](https://app.mem0.ai)
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 CLI Docs](https://docs.mem0.ai/cli)
|
||||
- [Mem0 GitHub](https://github.com/mem0ai/mem0)
|
||||
|
||||
## Skill Graph
|
||||
|
||||
This skill is part of the **Mem0 skill graph** -- three interconnected skills for different interfaces to the Mem0 platform:
|
||||
|
||||
| Skill | Purpose | Link |
|
||||
|-------|---------|------|
|
||||
| **mem0** | Python/TypeScript SDK, REST API, framework integrations | [local](../mem0/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0) |
|
||||
| **mem0-cli** (this skill) | Terminal commands for memory operations | [local](./SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli) |
|
||||
| **mem0-vercel-ai-sdk** | Vercel AI SDK provider with automatic memory | [local](../mem0-vercel-ai-sdk/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk) |
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,154 @@
|
||||
---
|
||||
name: mem0-cli
|
||||
description: >
|
||||
Mem0 CLI -- the command-line interface for mem0 memory operations.
|
||||
TRIGGER when: user mentions "mem0 cli", "mem0 command line", "@mem0/cli",
|
||||
"mem0-cli", "pip install mem0-cli", "npm install -g @mem0/cli", or is running
|
||||
mem0 commands in a terminal/shell (mem0 add, mem0 search, mem0 list, mem0 get,
|
||||
mem0 init, mem0 config, mem0 import). Also triggers when query includes CLI flags
|
||||
like --user-id, --output, --json, --agent, or describes bash/zsh/terminal/shell usage.
|
||||
DO NOT TRIGGER when: user asks about programmatic SDK integration in Python/TS
|
||||
code (use mem0 skill), or Vercel AI SDK provider (use mem0-vercel-ai-sdk skill).
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: mem0ai
|
||||
version: "1.0.0"
|
||||
category: ai-memory
|
||||
tags: "cli, terminal, memory, ai, command-line"
|
||||
compatibility: Node.js 18+ (npm install -g @mem0/cli) or Python 3.10+ (pip install mem0-cli), MEM0_API_KEY env var
|
||||
---
|
||||
|
||||
# Mem0 CLI
|
||||
|
||||
The official command-line interface for the Mem0 memory platform. Add, search, list, update, and delete memories from the terminal -- for developers, AI agents, and CI/CD pipelines.
|
||||
|
||||
## Install
|
||||
|
||||
**Node.js (npm):**
|
||||
```bash
|
||||
npm install -g @mem0/cli
|
||||
```
|
||||
|
||||
**Python (pip):**
|
||||
```bash
|
||||
pip install mem0-cli
|
||||
```
|
||||
|
||||
Both packages install a `mem0` binary with identical commands, options, and output formats.
|
||||
|
||||
## Setup
|
||||
|
||||
**Interactive wizard:**
|
||||
```bash
|
||||
mem0 init
|
||||
```
|
||||
|
||||
**Or set the environment variable directly:**
|
||||
```bash
|
||||
export MEM0_API_KEY="m0-xxx"
|
||||
```
|
||||
|
||||
Get an API key at: https://app.mem0.ai/dashboard/api-keys
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Add a memory
|
||||
```bash
|
||||
mem0 add "I prefer dark mode" --user-id alice
|
||||
```
|
||||
|
||||
### Search memories
|
||||
```bash
|
||||
mem0 search "preferences" --user-id alice
|
||||
```
|
||||
|
||||
### List all memories for a user
|
||||
```bash
|
||||
mem0 list --user-id alice
|
||||
```
|
||||
|
||||
### Get a specific memory
|
||||
```bash
|
||||
mem0 get <memory-id>
|
||||
```
|
||||
|
||||
### Update a memory
|
||||
```bash
|
||||
mem0 update <memory-id> "new text"
|
||||
```
|
||||
|
||||
### Delete a single memory
|
||||
```bash
|
||||
mem0 delete <memory-id>
|
||||
```
|
||||
|
||||
### Delete all memories for a user
|
||||
```bash
|
||||
mem0 delete --all --user-id alice --force
|
||||
```
|
||||
|
||||
## Agent / JSON Mode
|
||||
|
||||
Use `--json` or `--agent` to get structured output suitable for LLM consumption. Every command wraps its response in a standard envelope:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"command": "search",
|
||||
"duration_ms": 245,
|
||||
"scope": { "user_id": "alice" },
|
||||
"count": 3,
|
||||
"error": null,
|
||||
"data": [
|
||||
{ "id": "mem-abc", "memory": "User prefers dark mode", "score": 0.92 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
On error:
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"command": "search",
|
||||
"error": "Authentication failed. Your API key may be invalid or expired.",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
The `--agent` flag is an alias for `--json`. Both write spinners and progress to stderr so stdout is always clean, parseable JSON.
|
||||
|
||||
## Node and Python Parity
|
||||
|
||||
Both the Node.js (`@mem0/cli`) and Python (`mem0-cli`) CLIs are implemented from the same specification (`cli-spec.json`). They share:
|
||||
|
||||
- Identical command names, arguments, and flags
|
||||
- Identical output formats (text, json, table, quiet)
|
||||
- Identical entity ID resolution, graph tri-state, filter building
|
||||
- Identical error messages and exit codes
|
||||
|
||||
Choose whichever runtime you already have installed. The behavior is the same.
|
||||
|
||||
## Common Edge Cases
|
||||
|
||||
- **Async processing delay:** After `mem0 add`, memories process asynchronously. Wait 2-3 seconds before searching for newly added content. Use `mem0 event list` to check processing status.
|
||||
- **`--all` vs `--entity` delete modes:** `mem0 delete --all -u alice` deletes all memories for user alice. `mem0 delete --entity -u alice` deletes the entity itself AND all its memories (cascade). These are mutually exclusive modes.
|
||||
- **Entity ID resolution:** If you pass any explicit scope flag (e.g. `--user-id`), the CLI uses ONLY the explicit IDs and ignores config defaults. If no scope flags are given, all configured defaults apply.
|
||||
- **Stdin detection:** When no text argument is provided and input is piped (not a TTY), the CLI reads from stdin. Works with `add`, `search`, and `update`.
|
||||
- **Graph tri-state:** `--no-graph` takes precedence over `--graph`, which takes precedence over the config default (`defaults.enable_graph`).
|
||||
|
||||
## References
|
||||
|
||||
Load these on demand for deeper detail:
|
||||
|
||||
| Topic | File |
|
||||
|-------|------|
|
||||
| Command reference (all commands, flags, options, examples) | [references/command-reference.md](references/command-reference.md) |
|
||||
| Configuration (config file, env vars, precedence, init wizard) | [references/configuration.md](references/configuration.md) |
|
||||
| Workflows (piping, scripting, CI/CD, agent mode recipes) | [references/workflows.md](references/workflows.md) |
|
||||
|
||||
## Related Mem0 Skills
|
||||
|
||||
| Skill | When to use | Link |
|
||||
|-------|-------------|------|
|
||||
| mem0 | Python/TypeScript SDK, REST API, framework integrations | [local](../mem0/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0) |
|
||||
| mem0-vercel-ai-sdk | Vercel AI SDK provider with automatic memory | [local](../mem0-vercel-ai-sdk/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk) |
|
||||
@@ -0,0 +1,690 @@
|
||||
# Mem0 CLI Command Reference
|
||||
|
||||
Complete reference for every command, argument, flag, and output mode in the mem0 CLI. Both the Node.js (`@mem0/cli`) and Python (`mem0-cli`) implementations are identical in behavior.
|
||||
|
||||
---
|
||||
|
||||
## Global Options
|
||||
|
||||
These options are available on every command:
|
||||
|
||||
| Flag | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `--json` / `--agent` | boolean | Agent mode: wrap all output in a structured JSON envelope on stdout. Spinners and progress go to stderr. |
|
||||
| `-o, --output <format>` | string | Output format. Supported values vary per command (see matrix below). |
|
||||
| `--api-key <key>` | string | Override the API key for this invocation. Takes precedence over env var and config file. |
|
||||
| `--base-url <url>` | string | Override the API base URL (default: `https://api.mem0.ai`). |
|
||||
| `--version` | boolean | Print version and exit. |
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
### `mem0 init`
|
||||
|
||||
Interactive setup wizard. Configures API key and default user ID.
|
||||
|
||||
**Usage:** `mem0 init [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `--api-key <key>` | string | - | API key (skip interactive prompt). |
|
||||
| `-u, --user-id <id>` | string | - | Default user ID (skip interactive prompt). |
|
||||
| `--email <addr>` | string | - | Login via email verification code instead of API key. |
|
||||
| `--code <code>` | string | - | Verification code (use with `--email` for fully non-interactive login). |
|
||||
| `--force` | boolean | false | Overwrite existing config without confirmation. |
|
||||
|
||||
**Behavior:**
|
||||
|
||||
- If `~/.mem0/config.json` already exists with an API key, warns and asks for confirmation (or errors in non-TTY unless `--force` is set).
|
||||
- **Email login flow** (`--email`): sends a 6-digit code to the email via `POST /api/v1/auth/email_code/`. If `--code` is also given, verifies immediately. On success, saves API key, org_id, and project_id. Cannot be combined with `--api-key`.
|
||||
- **API key flow**: if both `--api-key` and `--user-id` are given, runs fully non-interactively. Otherwise prompts for missing values.
|
||||
- In non-TTY without sufficient flags, prints a usage hint and exits with error.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 init
|
||||
mem0 init --api-key m0-xxx --user-id alice
|
||||
mem0 init --api-key m0-xxx --user-id alice --force
|
||||
mem0 init --email alice@company.com
|
||||
mem0 init --email alice@company.com --code 482901
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 add`
|
||||
|
||||
Add a memory from text, messages, file, or stdin.
|
||||
|
||||
**Usage:** `mem0 add [text] [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `text` | string | No | Text content to add as a memory. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-u, --user-id <id>` | string | - | Scope to user. |
|
||||
| `--agent-id <id>` | string | - | Scope to agent. |
|
||||
| `--app-id <id>` | string | - | Scope to app. |
|
||||
| `--run-id <id>` | string | - | Scope to run. |
|
||||
| `--messages <json>` | string | - | Conversation messages as JSON array (e.g. `'[{"role":"user","content":"..."}]'`). |
|
||||
| `-f, --file <path>` | path | - | Read messages from a JSON file. |
|
||||
| `-m, --metadata <json>` | string | - | Custom metadata as JSON object (e.g. `'{"source":"cli"}'`). |
|
||||
| `--immutable` | boolean | false | Prevent future updates to this memory. |
|
||||
| `--no-infer` | boolean | false | Skip inference; store the text verbatim. |
|
||||
| `--expires <date>` | string | - | Expiration date in `YYYY-MM-DD` format. |
|
||||
| `--categories <cats>` | string | - | Categories as JSON array or comma-separated string. |
|
||||
| `--graph` | boolean | false | Enable graph memory extraction for this call. |
|
||||
| `--no-graph` | boolean | false | Disable graph memory extraction for this call. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`, `quiet`. |
|
||||
|
||||
**Input priority:** `--file` > `--messages` > text argument > stdin (if piped and no text).
|
||||
|
||||
Text content is wrapped as `[{"role": "user", "content": "<text>"}]` before sending to the API. Messages from `--messages` or `--file` are sent as-is.
|
||||
|
||||
**Output events:** The API returns results with an `event` field per memory:
|
||||
|
||||
| Event | Meaning |
|
||||
|-------|---------|
|
||||
| `ADD` | New memory created |
|
||||
| `UPDATE` | Existing memory updated (deduplication) |
|
||||
| `DELETE` | Existing memory removed (contradiction) |
|
||||
| `NOOP` | No change needed |
|
||||
| `PENDING` | Processing asynchronously in background |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 add "I prefer dark mode" --user-id alice
|
||||
mem0 add "allergic to nuts" -u alice -m '{"source":"onboarding"}'
|
||||
mem0 add --messages '[{"role":"user","content":"I like Python"}]' -u alice
|
||||
mem0 add --file conversation.json -u alice -o json
|
||||
echo "I prefer dark mode" | mem0 add -u alice
|
||||
mem0 add "temporary note" -u alice --expires 2025-12-31
|
||||
mem0 add "important fact" -u alice --immutable
|
||||
mem0 add "uses vim" -u alice --categories "tools,preferences"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 search`
|
||||
|
||||
Search memories by semantic query.
|
||||
|
||||
**Usage:** `mem0 search <query> [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `query` | string | Yes | The search query. Falls back to stdin if piped. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-u, --user-id <id>` | string | - | Filter by user. |
|
||||
| `--agent-id <id>` | string | - | Filter by agent. |
|
||||
| `--app-id <id>` | string | - | Filter by app. |
|
||||
| `--run-id <id>` | string | - | Filter by run. |
|
||||
| `-k, --top-k, --limit <n>` | integer | 10 | Maximum number of results to return. |
|
||||
| `--threshold <score>` | float | 0.3 | Minimum similarity score (0.0 to 1.0). |
|
||||
| `--rerank` | boolean | false | Enable reranking for improved relevance (Platform only). |
|
||||
| `--keyword` | boolean | false | Use keyword search instead of semantic. |
|
||||
| `--filter <json>` | string | - | Advanced filter expression as JSON (AND/OR operators). |
|
||||
| `--fields <list>` | string | - | Comma-separated list of fields to return. |
|
||||
| `--graph` | boolean | false | Enable graph in search. |
|
||||
| `--no-graph` | boolean | false | Disable graph in search. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`, `table`. |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 search "preferences" --user-id alice
|
||||
mem0 search "tools" -u alice -o json -k 5
|
||||
mem0 search "dietary restrictions" -u alice --threshold 0.5
|
||||
mem0 search "project setup" -u alice --rerank
|
||||
mem0 search "preferences" -u alice --filter '{"categories":{"contains":"food"}}'
|
||||
echo "preferences" | mem0 search -u alice
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 get`
|
||||
|
||||
Get a specific memory by ID.
|
||||
|
||||
**Usage:** `mem0 get <memory_id> [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `memory_id` | string | Yes | The UUID of the memory to retrieve. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`. |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 get abc-123-def-456
|
||||
mem0 get abc-123-def-456 -o json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 list`
|
||||
|
||||
List memories with optional filters and pagination.
|
||||
|
||||
**Usage:** `mem0 list [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-u, --user-id <id>` | string | - | Filter by user. |
|
||||
| `--agent-id <id>` | string | - | Filter by agent. |
|
||||
| `--app-id <id>` | string | - | Filter by app. |
|
||||
| `--run-id <id>` | string | - | Filter by run. |
|
||||
| `--page <n>` | integer | 1 | Page number. |
|
||||
| `--page-size <n>` | integer | 100 | Results per page. |
|
||||
| `--category <name>` | string | - | Filter by category. |
|
||||
| `--after <date>` | string | - | Created after (YYYY-MM-DD). |
|
||||
| `--before <date>` | string | - | Created before (YYYY-MM-DD). |
|
||||
| `--graph` | boolean | false | Enable graph in listing. |
|
||||
| `--no-graph` | boolean | false | Disable graph in listing. |
|
||||
| `-o, --output <fmt>` | string | `table` | Output format: `text`, `json`, `table`. |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 list -u alice
|
||||
mem0 list --category prefs --after 2024-01-01 -o json
|
||||
mem0 list -u alice --page 2 --page-size 50
|
||||
mem0 list --before 2024-06-01 -o table
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 update`
|
||||
|
||||
Update a memory's text or metadata.
|
||||
|
||||
**Usage:** `mem0 update <memory_id> [text] [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `memory_id` | string | Yes | The UUID of the memory to update. |
|
||||
| `text` | string | No | New memory text. Falls back to stdin if piped and no `--metadata`. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-m, --metadata <json>` | string | - | Update metadata as JSON object. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`, `quiet`. |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 update abc-123 "new text"
|
||||
mem0 update abc-123 --metadata '{"priority":"high"}'
|
||||
mem0 update abc-123 "new text" -m '{"priority":"high"}'
|
||||
echo "new text" | mem0 update abc-123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 delete`
|
||||
|
||||
Delete a memory, all memories matching a scope, or an entity. This command has three mutually exclusive modes.
|
||||
|
||||
**Usage:** `mem0 delete [memory_id] [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `memory_id` | string | No | Memory ID to delete (omit when using `--all` or `--entity`). |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `--all` | boolean | false | Delete all memories matching scope filters. |
|
||||
| `--entity` | boolean | false | Delete the entity itself and all its memories (cascade). |
|
||||
| `--project` | boolean | false | With `--all`: delete ALL memories project-wide (sends wildcard IDs). |
|
||||
| `--dry-run` | boolean | false | Show what would be deleted without actually deleting. |
|
||||
| `--force` | boolean | false | Skip confirmation prompt. |
|
||||
| `-u, --user-id <id>` | string | - | Scope to user. |
|
||||
| `--agent-id <id>` | string | - | Scope to agent. |
|
||||
| `--app-id <id>` | string | - | Scope to app. |
|
||||
| `--run-id <id>` | string | - | Scope to run. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`, `quiet`. |
|
||||
|
||||
**Three modes (mutually exclusive):**
|
||||
|
||||
1. **Single memory:** `mem0 delete <memory_id>` -- deletes one memory by its UUID.
|
||||
2. **Bulk delete:** `mem0 delete --all [scope flags]` -- deletes all memories matching the scope. Add `--project` to wipe all memories project-wide (sends wildcard `*` entity IDs).
|
||||
3. **Entity cascade:** `mem0 delete --entity [scope flags]` -- deletes the entity itself AND all its memories.
|
||||
|
||||
You cannot combine `<memory_id>` with `--all` or `--entity`, and you cannot combine `--all` with `--entity`. If none of these are provided, the command prints a usage hint and exits with an error.
|
||||
|
||||
**Dry-run behavior:**
|
||||
- Single: fetches the memory, displays it, prints "No changes made."
|
||||
- `--all`: lists matching memories with count, prints "No changes made."
|
||||
- `--entity`: shows the affected scope without deleting.
|
||||
|
||||
**Confirmation:** Without `--force`, all destructive modes prompt `[y/N]`. With `--all --project`, the prompt explicitly warns about project-wide deletion.
|
||||
|
||||
**`--all --project` behavior:** Sends `DELETE /v1/memories/` with `user_id=*&agent_id=*&app_id=*&run_id=*`. The API returns an async response. The CLI prints "Deletion started. Memories will be removed in the background."
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 delete abc-123-def-456
|
||||
mem0 delete --all -u alice --force
|
||||
mem0 delete --all --project --force
|
||||
mem0 delete --entity -u alice --force
|
||||
mem0 delete abc-123 --dry-run
|
||||
mem0 delete --all -u alice --dry-run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 import`
|
||||
|
||||
Import memories from a JSON file.
|
||||
|
||||
**Usage:** `mem0 import <file_path> [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `file_path` | string | Yes | Path to a JSON file containing memories. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-u, --user-id <id>` | string | - | Override user ID for all imported items. |
|
||||
| `--agent-id <id>` | string | - | Override agent ID for all imported items. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`. |
|
||||
|
||||
**File format:** A JSON array (or single object) where each item has a `memory`, `text`, or `content` field for the text, plus optional `user_id`, `agent_id`, and `metadata` fields. CLI-provided `--user-id` and `--agent-id` override per-item values.
|
||||
|
||||
**Import format example:**
|
||||
```json
|
||||
[
|
||||
{ "memory": "Prefers dark mode", "user_id": "alice" },
|
||||
{ "text": "Allergic to nuts", "metadata": { "source": "intake" } },
|
||||
{ "content": "Uses VS Code" }
|
||||
]
|
||||
```
|
||||
|
||||
**Behavior:** Iterates through items, calling the add API for each. Displays progress and reports `added` and `failed` counts on completion.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 import memories.json --user-id alice
|
||||
mem0 import data.json -u alice -o json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 config show`
|
||||
|
||||
Display current configuration with secrets redacted.
|
||||
|
||||
**Usage:** `mem0 config show [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`. |
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 config show
|
||||
mem0 config show -o json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 config get`
|
||||
|
||||
Get a single configuration value.
|
||||
|
||||
**Usage:** `mem0 config get <key>`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `key` | string | Yes | Dotted config key (e.g. `platform.api_key`, `defaults.user_id`). |
|
||||
|
||||
**Valid keys:** `platform.api_key`, `platform.base_url`, `defaults.user_id`, `defaults.agent_id`, `defaults.app_id`, `defaults.run_id`, `defaults.enable_graph`.
|
||||
|
||||
API key values are always redacted in output.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 config get platform.api_key
|
||||
mem0 config get defaults.user_id
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 config set`
|
||||
|
||||
Set a configuration value.
|
||||
|
||||
**Usage:** `mem0 config set <key> <value>`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `key` | string | Yes | Dotted config key (e.g. `defaults.user_id`). |
|
||||
| `value` | string | Yes | Value to set. |
|
||||
|
||||
**Type coercion:** Boolean fields accept `true`/`1`/`yes` (case-insensitive) as true, anything else as false.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 config set defaults.user_id alice
|
||||
mem0 config set platform.base_url https://api.mem0.ai
|
||||
mem0 config set defaults.enable_graph true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 config clear`
|
||||
|
||||
Clear the configuration file. Removes `~/.mem0/config.json`.
|
||||
|
||||
**Usage:** `mem0 config clear`
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 config clear
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 entity list`
|
||||
|
||||
List all entities of a given type.
|
||||
|
||||
**Usage:** `mem0 entity list <entity_type> [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Choices | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `entity_type` | string | Yes | `users`, `agents`, `apps`, `runs` | Entity type to list. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `table` | Output format: `table`, `json`. |
|
||||
|
||||
**Behavior:** Calls `GET /v1/entities/` (returns all types), then filters client-side using the type map (`users` -> `user`, `agents` -> `agent`, etc.). Displays a table with "Name / ID" and "Created" columns.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 entity list users
|
||||
mem0 entity list agents -o json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 entity delete`
|
||||
|
||||
Delete an entity and ALL its memories (cascade).
|
||||
|
||||
**Usage:** `mem0 entity delete [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-u, --user-id <id>` | string | - | User ID of the entity to delete. |
|
||||
| `--agent-id <id>` | string | - | Agent ID of the entity to delete. |
|
||||
| `--app-id <id>` | string | - | App ID of the entity to delete. |
|
||||
| `--run-id <id>` | string | - | Run ID of the entity to delete. |
|
||||
| `--dry-run` | boolean | false | Show what would be deleted without deleting. |
|
||||
| `--force` | boolean | false | Skip confirmation prompt. |
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`, `quiet`. |
|
||||
|
||||
At least one entity ID is required. Errors if none provided.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 entity delete --user-id alice --force
|
||||
mem0 entity delete --user-id alice --dry-run
|
||||
mem0 entity delete --agent-id bot1 --force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 event list`
|
||||
|
||||
List recent background processing events.
|
||||
|
||||
**Usage:** `mem0 event list [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `table` | Output format: `text` (table), `json`. |
|
||||
|
||||
**Behavior:** Fetches all events for the project. Displays a table with columns: Event ID (first 8 chars), Type, Status (color-coded), Latency, Created. Status values: `PENDING`, `SUCCEEDED`, `FAILED`, `PROCESSING`.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 event list
|
||||
mem0 event list --output json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 event status`
|
||||
|
||||
Get the status and results of a specific background event.
|
||||
|
||||
**Usage:** `mem0 event status <event_id> [OPTIONS]`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `event_id` | string | Yes | Event ID to inspect. |
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`. |
|
||||
|
||||
**Behavior:** Fetches the event by ID. Displays: Event ID, Type, Status, Latency, Created, Updated, and a list of result memories.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 event status evt-abc-123
|
||||
mem0 event status evt-abc-123 --output json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mem0 status`
|
||||
|
||||
Check connectivity and authentication.
|
||||
|
||||
**Usage:** `mem0 status [OPTIONS]`
|
||||
|
||||
**Options:**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `-o, --output <fmt>` | string | `text` | Output format: `text`, `json`. |
|
||||
|
||||
**Behavior:** Calls `GET /v1/ping/` to validate connectivity and authentication. Displays connection status, backend type, and base URL.
|
||||
|
||||
**JSON output:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"command": "status",
|
||||
"duration_ms": 112,
|
||||
"data": {
|
||||
"connected": true,
|
||||
"backend": "platform",
|
||||
"base_url": "https://api.mem0.ai"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
mem0 status
|
||||
mem0 status -o json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Agent Mode Envelope Format
|
||||
|
||||
When `--json` or `--agent` is passed, every command wraps its output in a consistent JSON envelope on stdout:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"command": "<command_name>",
|
||||
"duration_ms": 245,
|
||||
"scope": { "user_id": "alice", "agent_id": null },
|
||||
"count": 10,
|
||||
"error": null,
|
||||
"data": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
- `status`: `"success"` or `"error"`.
|
||||
- `command`: The command name (e.g. `"search"`, `"add"`, `"list"`).
|
||||
- `duration_ms`: Elapsed time in milliseconds (optional).
|
||||
- `scope`: Active entity scope, omitted if empty (optional).
|
||||
- `count`: Number of results, where applicable (optional).
|
||||
- `error`: Error message string, or `null` on success.
|
||||
- `data`: Command-specific response data, or `null` on error.
|
||||
|
||||
**Sanitized data fields per command in agent mode:**
|
||||
|
||||
| Command | `data` shape |
|
||||
|---------|-------------|
|
||||
| `add` | `[{id, memory, event}]` or `[{status, event_id}]` for PENDING |
|
||||
| `search` | `[{id, memory, score, created_at, categories}]` |
|
||||
| `list` | `[{id, memory, created_at, categories}]` |
|
||||
| `get` | `{id, memory, created_at, updated_at, categories, metadata}` |
|
||||
| `update` | `{id, memory}` |
|
||||
| `delete` | Raw API response |
|
||||
| `entity list` | `[{name, type, count}]` |
|
||||
| `event list` | `[{id, event_type, status, latency, created_at}]` |
|
||||
| `event status` | `{id, event_type, status, latency, created_at, updated_at, results}` |
|
||||
| `status` | `{connected, backend, base_url}` |
|
||||
| `config show` | Config object (keys redacted) |
|
||||
| `import` | `{added, failed, duration_s}` |
|
||||
|
||||
**Error envelope:**
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"command": "search",
|
||||
"error": "Authentication failed. Your API key may be invalid or expired.",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Entity ID Resolution
|
||||
|
||||
**Rule:** If **any** explicit entity ID is provided via CLI flags (`--user-id`, `--agent-id`, `--app-id`, `--run-id`), the CLI uses only the explicitly provided IDs. It does NOT mix in defaults from config for the other entity types.
|
||||
|
||||
If **no** explicit IDs are given, all configured defaults from config file and env vars apply.
|
||||
|
||||
**Rationale:** If a user passes `--user-id alice` and the config also has `agent_id=bot1`, they want only Alice's memories -- not the intersection of Alice AND bot1.
|
||||
|
||||
```
|
||||
if any(user_id, agent_id, app_id, run_id) were passed as flags:
|
||||
use only the explicitly provided IDs (others = null)
|
||||
else:
|
||||
use all configured defaults
|
||||
```
|
||||
|
||||
This applies to commands with `resolveIds: true`: `add`, `search`, `list`, `delete`, `import`.
|
||||
|
||||
---
|
||||
|
||||
## Graph Tri-State
|
||||
|
||||
The `enable_graph` parameter follows a three-level precedence:
|
||||
|
||||
```
|
||||
--no-graph (explicit disable) > --graph (explicit enable) > config default
|
||||
```
|
||||
|
||||
If `--no-graph` is passed, graph is disabled regardless of other settings. If `--graph` is passed (without `--no-graph`), graph is enabled. If neither is passed, the config value `defaults.enable_graph` is used.
|
||||
|
||||
This applies to commands with `resolveGraph: true`: `add`, `search`, `list`.
|
||||
|
||||
---
|
||||
|
||||
## Filter Building
|
||||
|
||||
For `search` and `list`, entity IDs and additional filters are composed into the API filter structure:
|
||||
|
||||
1. If the user provides a pre-built filter via `--filter` containing `AND` or `OR` keys, it is passed through to the API as-is.
|
||||
2. Otherwise, the CLI builds an array of AND conditions:
|
||||
- Each entity ID becomes a condition: `{"user_id": "alice"}`, etc.
|
||||
- Category filters: `{"categories": {"contains": "<category>"}}`.
|
||||
- Date filters: `{"created_at": {"gte": "YYYY-MM-DD"}}` and/or `{"created_at": {"lte": "YYYY-MM-DD"}}`.
|
||||
3. If exactly 1 condition: sent as a single object (no wrapping).
|
||||
4. If 2+ conditions: wrapped as `{"AND": [condition1, condition2, ...]}`.
|
||||
5. If 0 conditions: no filter sent.
|
||||
|
||||
---
|
||||
|
||||
## Output Mode Support Matrix
|
||||
|
||||
| Command | `text` | `json` | `table` | `quiet` | Default |
|
||||
|---------|--------|--------|---------|---------|---------|
|
||||
| `add` | Y | Y | - | Y | `text` |
|
||||
| `search` | Y | Y | Y | - | `text` |
|
||||
| `get` | Y | Y | - | - | `text` |
|
||||
| `list` | Y | Y | Y | - | `table` |
|
||||
| `update` | Y | Y | - | Y | `text` |
|
||||
| `delete` | Y | Y | - | Y | `text` |
|
||||
| `import` | Y | Y | - | - | `text` |
|
||||
| `config show` | Y | Y | - | - | `text` |
|
||||
| `config get` | raw | - | - | - | raw |
|
||||
| `config set` | msg | - | - | - | msg |
|
||||
| `entity list` | - | Y | Y | - | `table` |
|
||||
| `entity delete` | Y | Y | - | Y | `text` |
|
||||
| `event list` | Y (table) | Y | - | - | `table` |
|
||||
| `event status` | Y | Y | - | - | `text` |
|
||||
| `status` | Y | Y | - | - | `text` |
|
||||
|
||||
All commands additionally support agent mode (`--json`/`--agent`) which overrides the output format with the JSON envelope.
|
||||
@@ -0,0 +1,244 @@
|
||||
# Mem0 CLI Configuration
|
||||
|
||||
Everything about configuring the mem0 CLI: config file format, environment variables, the init wizard, and precedence rules.
|
||||
|
||||
---
|
||||
|
||||
## Config File Location
|
||||
|
||||
| Path | Permissions | Description |
|
||||
|------|-------------|-------------|
|
||||
| `~/.mem0/` | `0700` (owner rwx) | Config directory. Created automatically by `mem0 init`. |
|
||||
| `~/.mem0/config.json` | `0600` (owner rw) | Config file. Contains API key, defaults, and platform settings. |
|
||||
|
||||
The restricted permissions ensure API keys are not world-readable.
|
||||
|
||||
---
|
||||
|
||||
## Config File Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"defaults": {
|
||||
"user_id": "",
|
||||
"agent_id": "",
|
||||
"app_id": "",
|
||||
"run_id": "",
|
||||
"enable_graph": false
|
||||
},
|
||||
"platform": {
|
||||
"api_key": "",
|
||||
"base_url": "https://api.mem0.ai"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Field Reference
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
|-------|------|---------|-------------|
|
||||
| `version` | integer | `1` | Config schema version. |
|
||||
| `defaults.user_id` | string | `""` | Default user ID for scoping commands. |
|
||||
| `defaults.agent_id` | string | `""` | Default agent ID for scoping commands. |
|
||||
| `defaults.app_id` | string | `""` | Default app ID for scoping commands. |
|
||||
| `defaults.run_id` | string | `""` | Default run ID for scoping commands. |
|
||||
| `defaults.enable_graph` | boolean | `false` | Default graph memory extraction toggle. |
|
||||
| `platform.api_key` | string | `""` | API key for the Mem0 Platform. |
|
||||
| `platform.base_url` | string | `"https://api.mem0.ai"` | Base URL for API requests. |
|
||||
|
||||
---
|
||||
|
||||
## `mem0 init` Wizard
|
||||
|
||||
The `init` command provides two authentication flows:
|
||||
|
||||
### API Key Flow (default)
|
||||
|
||||
```bash
|
||||
# Fully interactive:
|
||||
mem0 init
|
||||
|
||||
# Fully non-interactive:
|
||||
mem0 init --api-key m0-xxx --user-id alice
|
||||
```
|
||||
|
||||
**Interactive mode steps:**
|
||||
|
||||
1. Displays the mem0 banner.
|
||||
2. Checks for existing config. If found with an API key, asks for confirmation to overwrite.
|
||||
3. Prompts for API key (input masked with `*` characters; supports backspace and Ctrl+U to clear).
|
||||
4. Prompts for default user ID (default value: `mem0-cli`).
|
||||
5. Validates the connection by calling the status endpoint.
|
||||
6. Saves config to `~/.mem0/config.json` with `0600` permissions.
|
||||
7. Prints success message.
|
||||
|
||||
**Non-interactive mode:** When both `--api-key` and `--user-id` are provided, skips all prompts and saves directly. When running in a non-TTY without both flags, prints an error:
|
||||
|
||||
```
|
||||
Non-interactive terminal detected and missing required flags.
|
||||
Usage: mem0 init --api-key <key> --user-id <id>
|
||||
```
|
||||
|
||||
### Email Login Flow
|
||||
|
||||
```bash
|
||||
# Interactive (prompts for code):
|
||||
mem0 init --email alice@company.com
|
||||
|
||||
# Fully non-interactive:
|
||||
mem0 init --email alice@company.com --code 482901
|
||||
```
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. Sends a 6-digit verification code to the email via `POST /api/v1/auth/email_code/`.
|
||||
2. If `--code` is provided, verifies immediately. Otherwise prompts for the code.
|
||||
3. On success: receives API key, org_id, and project_id from the server.
|
||||
4. Saves to config. Creates a new account if the email is not registered.
|
||||
|
||||
Cannot be combined with `--api-key`.
|
||||
|
||||
### Force Overwrite
|
||||
|
||||
If `~/.mem0/config.json` already exists with an API key, `mem0 init` warns and asks for confirmation. Use `--force` to skip:
|
||||
|
||||
```bash
|
||||
mem0 init --api-key m0-new-key --user-id alice --force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `mem0 config` Subcommands
|
||||
|
||||
### `mem0 config show`
|
||||
|
||||
Displays the current configuration as a formatted table (text mode) or JSON envelope (json mode). API keys are always redacted.
|
||||
|
||||
```bash
|
||||
mem0 config show
|
||||
mem0 config show -o json
|
||||
```
|
||||
|
||||
### `mem0 config get <key>`
|
||||
|
||||
Reads a single configuration value. The key uses dotted notation.
|
||||
|
||||
```bash
|
||||
mem0 config get platform.api_key # prints: m0-x...xxxx (redacted)
|
||||
mem0 config get defaults.user_id # prints: alice
|
||||
mem0 config get defaults.enable_graph # prints: false
|
||||
```
|
||||
|
||||
**Valid keys:**
|
||||
- `platform.api_key`
|
||||
- `platform.base_url`
|
||||
- `defaults.user_id`
|
||||
- `defaults.agent_id`
|
||||
- `defaults.app_id`
|
||||
- `defaults.run_id`
|
||||
- `defaults.enable_graph`
|
||||
|
||||
Unknown keys print an error message.
|
||||
|
||||
### `mem0 config set <key> <value>`
|
||||
|
||||
Sets a configuration value and saves the config file.
|
||||
|
||||
```bash
|
||||
mem0 config set defaults.user_id alice
|
||||
mem0 config set platform.base_url https://api.mem0.ai
|
||||
mem0 config set defaults.enable_graph true
|
||||
```
|
||||
|
||||
**Type coercion:**
|
||||
- Boolean fields accept `true`, `1`, `yes` (case-insensitive) as true. Anything else is false.
|
||||
- Integer fields are parsed with `parseInt`.
|
||||
- String fields are stored as-is.
|
||||
|
||||
### `mem0 config clear`
|
||||
|
||||
Removes the config file (`~/.mem0/config.json`).
|
||||
|
||||
```bash
|
||||
mem0 config clear
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Environment variables override config file values but are overridden by CLI flags.
|
||||
|
||||
| Variable | Config Path | Type | Default |
|
||||
|----------|-------------|------|---------|
|
||||
| `MEM0_API_KEY` | `platform.api_key` | string | `""` |
|
||||
| `MEM0_BASE_URL` | `platform.base_url` | string | `"https://api.mem0.ai"` |
|
||||
| `MEM0_USER_ID` | `defaults.user_id` | string | `""` |
|
||||
| `MEM0_AGENT_ID` | `defaults.agent_id` | string | `""` |
|
||||
| `MEM0_APP_ID` | `defaults.app_id` | string | `""` |
|
||||
| `MEM0_RUN_ID` | `defaults.run_id` | string | `""` |
|
||||
| `MEM0_ENABLE_GRAPH` | `defaults.enable_graph` | boolean | `false` |
|
||||
|
||||
### Boolean Parsing for `MEM0_ENABLE_GRAPH`
|
||||
|
||||
Accepted truthy values (case-insensitive): `"true"`, `"1"`, `"yes"`. Everything else is treated as `false`.
|
||||
|
||||
```bash
|
||||
export MEM0_ENABLE_GRAPH=true # enabled
|
||||
export MEM0_ENABLE_GRAPH=1 # enabled
|
||||
export MEM0_ENABLE_GRAPH=yes # enabled
|
||||
export MEM0_ENABLE_GRAPH=false # disabled
|
||||
export MEM0_ENABLE_GRAPH=0 # disabled
|
||||
export MEM0_ENABLE_GRAPH="" # disabled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Precedence
|
||||
|
||||
Configuration values are resolved in this order (highest priority first):
|
||||
|
||||
```
|
||||
1. CLI flags --api-key, --user-id, --base-url, --graph, --no-graph, etc.
|
||||
2. Environment vars MEM0_API_KEY, MEM0_USER_ID, MEM0_ENABLE_GRAPH, etc.
|
||||
3. Config file ~/.mem0/config.json
|
||||
4. Defaults Hardcoded defaults (empty strings, false, https://api.mem0.ai)
|
||||
```
|
||||
|
||||
**Example:** If your config file has `user_id: "bob"`, the env var `MEM0_USER_ID=charlie` is set, and you pass `--user-id alice` on the command line, the effective user_id is `alice`.
|
||||
|
||||
---
|
||||
|
||||
## API Key Redaction Rules
|
||||
|
||||
Whenever an API key is displayed (in `config show`, `config get`, status output, etc.), it is redacted:
|
||||
|
||||
| Condition | Output |
|
||||
|-----------|--------|
|
||||
| Empty string | `(not set)` |
|
||||
| Length <= 8 | First 2 characters + `***` |
|
||||
| Length > 8 | First 4 characters + `...` + last 4 characters |
|
||||
|
||||
**Examples:**
|
||||
- `""` -> `(not set)`
|
||||
- `"m0-abc"` -> `m0***`
|
||||
- `"m0-abcdefghijklmnop"` -> `m0-a...mnop`
|
||||
|
||||
The redaction function is named `redact_key` (Python) / `redactKey` (Node).
|
||||
|
||||
---
|
||||
|
||||
## Dotted Key Map
|
||||
|
||||
The `config get` and `config set` commands use dotted key paths. Here is the full mapping:
|
||||
|
||||
| Dotted Key | Section | Field |
|
||||
|------------|---------|-------|
|
||||
| `platform.api_key` | platform | api_key |
|
||||
| `platform.base_url` | platform | base_url |
|
||||
| `defaults.user_id` | defaults | user_id |
|
||||
| `defaults.agent_id` | defaults | agent_id |
|
||||
| `defaults.app_id` | defaults | app_id |
|
||||
| `defaults.run_id` | defaults | run_id |
|
||||
| `defaults.enable_graph` | defaults | enable_graph |
|
||||
@@ -0,0 +1,439 @@
|
||||
# Mem0 CLI Workflows
|
||||
|
||||
Practical recipes for using the mem0 CLI in scripts, pipelines, and agent loops.
|
||||
|
||||
---
|
||||
|
||||
## Piping Content via Stdin
|
||||
|
||||
The CLI reads from stdin when no text argument is provided and input is piped (not a TTY). This works with `add`, `search`, and `update`.
|
||||
|
||||
**Stdin detection method:**
|
||||
- Python: `not sys.stdin.isatty()`
|
||||
- Node: `!process.stdin.isTTY`
|
||||
|
||||
### Add from pipe
|
||||
|
||||
```bash
|
||||
echo "I prefer dark mode" | mem0 add --user-id alice
|
||||
```
|
||||
|
||||
### Pipe multi-line content
|
||||
|
||||
```bash
|
||||
cat <<EOF | mem0 add --user-id alice
|
||||
The user prefers dark mode in all applications.
|
||||
They also like monospace fonts for code editing.
|
||||
EOF
|
||||
```
|
||||
|
||||
### Pipe from another command
|
||||
|
||||
```bash
|
||||
git log --oneline -5 | mem0 add --user-id ci-bot --metadata '{"source":"git"}'
|
||||
```
|
||||
|
||||
### Search from pipe
|
||||
|
||||
```bash
|
||||
echo "preferences" | mem0 search --user-id alice
|
||||
```
|
||||
|
||||
### Update from pipe
|
||||
|
||||
```bash
|
||||
echo "Updated: prefers dark mode AND high contrast" | mem0 update abc-123-def-456
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Import
|
||||
|
||||
Use `mem0 import` to bulk-load memories from a JSON file.
|
||||
|
||||
### Basic import
|
||||
|
||||
```bash
|
||||
mem0 import memories.json --user-id alice
|
||||
```
|
||||
|
||||
### File format
|
||||
|
||||
The file should be a JSON array where each item has a `memory`, `text`, or `content` field:
|
||||
|
||||
```json
|
||||
[
|
||||
{ "memory": "Prefers dark mode" },
|
||||
{ "text": "Allergic to nuts", "metadata": { "source": "intake-form" } },
|
||||
{ "content": "Uses VS Code", "user_id": "bob" }
|
||||
]
|
||||
```
|
||||
|
||||
CLI-provided `--user-id` overrides per-item `user_id` values.
|
||||
|
||||
### Import with JSON output
|
||||
|
||||
```bash
|
||||
mem0 import data.json --user-id alice -o json
|
||||
```
|
||||
|
||||
Output:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"command": "import",
|
||||
"data": { "added": 42, "failed": 0, "duration_s": 3.14 },
|
||||
"duration_ms": 3140
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Agent Mode for LLM Consumption
|
||||
|
||||
Use `--json` or `--agent` to get structured JSON output suitable for LLM tool calling or agent frameworks. Spinners and progress always go to stderr, keeping stdout clean.
|
||||
|
||||
### Search with agent mode
|
||||
|
||||
```bash
|
||||
mem0 search "preferences" --user-id alice --agent
|
||||
```
|
||||
|
||||
Output (stdout):
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"command": "search",
|
||||
"duration_ms": 187,
|
||||
"scope": { "user_id": "alice" },
|
||||
"count": 2,
|
||||
"error": null,
|
||||
"data": [
|
||||
{ "id": "mem-abc", "memory": "User prefers dark mode", "score": 0.95, "created_at": "2025-01-15T10:00:00Z", "categories": ["preferences"] },
|
||||
{ "id": "mem-def", "memory": "User likes monospace fonts", "score": 0.82, "created_at": "2025-01-15T10:01:00Z", "categories": ["preferences"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Add with agent mode
|
||||
|
||||
```bash
|
||||
mem0 add "Uses Python 3.12" --user-id alice --json
|
||||
```
|
||||
|
||||
### Error handling in agent mode
|
||||
|
||||
Errors also return valid JSON with `"status": "error"`:
|
||||
|
||||
```bash
|
||||
mem0 search "test" --user-id alice --api-key invalid --agent
|
||||
```
|
||||
|
||||
Output:
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"command": "search",
|
||||
"error": "Authentication failed. Your API key may be invalid or expired.",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JSON Output + jq
|
||||
|
||||
Use `--output json` (or `-o json`) for raw JSON output, then pipe to `jq` for processing.
|
||||
|
||||
### Extract just memory text
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice --output json | jq '.[] | .memory'
|
||||
```
|
||||
|
||||
### Get memory IDs
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice -o json | jq '.[].id'
|
||||
```
|
||||
|
||||
### Count memories
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice -o json | jq 'length'
|
||||
```
|
||||
|
||||
### Filter by category in jq
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice -o json | jq '[.[] | select(.categories[]? == "preferences")]'
|
||||
```
|
||||
|
||||
### Extract search scores
|
||||
|
||||
```bash
|
||||
mem0 search "tools" --user-id alice -o json | jq '.[] | {memory, score}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
### Delete multiple memories by ID
|
||||
|
||||
```bash
|
||||
# Get IDs, then delete each one
|
||||
mem0 list --user-id alice -o json | jq -r '.[].id' | while read id; do
|
||||
mem0 delete "$id" --force
|
||||
done
|
||||
```
|
||||
|
||||
### Bulk add from a text file (one memory per line)
|
||||
|
||||
```bash
|
||||
while IFS= read -r line; do
|
||||
mem0 add "$line" --user-id alice
|
||||
done < memories.txt
|
||||
```
|
||||
|
||||
### Copy memories between users
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice -o json | jq -r '.[].memory' | while IFS= read -r mem; do
|
||||
mem0 add "$mem" --user-id bob
|
||||
done
|
||||
```
|
||||
|
||||
### Export all memories to a file
|
||||
|
||||
```bash
|
||||
mem0 list --user-id alice -o json > alice_memories.json
|
||||
```
|
||||
|
||||
### Paginate through all results
|
||||
|
||||
```bash
|
||||
page=1
|
||||
while true; do
|
||||
result=$(mem0 list --user-id alice -o json --page "$page" --page-size 100)
|
||||
count=$(echo "$result" | jq 'length')
|
||||
if [ "$count" -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
echo "$result"
|
||||
page=$((page + 1))
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD Patterns
|
||||
|
||||
### Store build context as a memory
|
||||
|
||||
```bash
|
||||
mem0 add "Build #${BUILD_NUMBER} deployed ${APP_VERSION} to ${ENVIRONMENT} at $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--agent-id "ci-bot" \
|
||||
--metadata "{\"build_number\":\"${BUILD_NUMBER}\",\"version\":\"${APP_VERSION}\",\"env\":\"${ENVIRONMENT}\"}"
|
||||
```
|
||||
|
||||
### Retrieve deployment history
|
||||
|
||||
```bash
|
||||
mem0 search "deployment to production" --agent-id ci-bot -o json -k 10
|
||||
```
|
||||
|
||||
### Check CLI connectivity in CI
|
||||
|
||||
```bash
|
||||
if mem0 status -o json | jq -e '.data.connected' > /dev/null 2>&1; then
|
||||
echo "mem0 is connected"
|
||||
else
|
||||
echo "mem0 connection failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Non-interactive init in CI
|
||||
|
||||
```bash
|
||||
mem0 init --api-key "$MEM0_API_KEY" --user-id ci-bot --force
|
||||
```
|
||||
|
||||
Or simply use the environment variable (no init needed):
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY="$MEM0_API_KEY"
|
||||
mem0 add "CI run started" --user-id ci-bot
|
||||
```
|
||||
|
||||
### Store test results
|
||||
|
||||
```bash
|
||||
test_summary=$(cat test-results.txt | head -20)
|
||||
mem0 add "$test_summary" --agent-id ci-bot --metadata '{"type":"test-results"}' --categories "ci,testing"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stdin Detection Details
|
||||
|
||||
The CLI reads from stdin only when ALL of these conditions are met:
|
||||
|
||||
1. No text argument was provided on the command line.
|
||||
2. For `add`: no `--messages` and no `--file` flag.
|
||||
3. For `update`: no `--metadata` flag.
|
||||
4. stdin is piped (not a TTY).
|
||||
|
||||
**This means:**
|
||||
- `mem0 add --user-id alice` in an interactive terminal will NOT hang waiting for input. It will print a usage error.
|
||||
- `echo "text" | mem0 add --user-id alice` will read "text" from stdin.
|
||||
- `mem0 add "explicit text" --user-id alice` will use the explicit text, even if stdin is piped.
|
||||
|
||||
**Reading method:**
|
||||
- Python: `sys.stdin.read().strip()`
|
||||
- Node: `fs.readFileSync(0, "utf-8").trim()`
|
||||
|
||||
---
|
||||
|
||||
## Common Shell Patterns
|
||||
|
||||
### Error handling with exit codes
|
||||
|
||||
```bash
|
||||
set -e # Exit on error
|
||||
|
||||
# This will exit the script if the API key is invalid
|
||||
mem0 status > /dev/null 2>&1
|
||||
|
||||
# Add with error check
|
||||
if mem0 add "test memory" --user-id alice 2>/dev/null; then
|
||||
echo "Memory added successfully"
|
||||
else
|
||||
echo "Failed to add memory" >&2
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Capture memory ID from add
|
||||
|
||||
```bash
|
||||
# Use agent mode to get structured output
|
||||
result=$(mem0 add "new fact" --user-id alice --agent 2>/dev/null)
|
||||
memory_id=$(echo "$result" | jq -r '.data[0].id // empty')
|
||||
if [ -n "$memory_id" ]; then
|
||||
echo "Created memory: $memory_id"
|
||||
fi
|
||||
```
|
||||
|
||||
### Conditional memory addition
|
||||
|
||||
```bash
|
||||
# Only add if search returns no results
|
||||
count=$(mem0 search "dark mode" --user-id alice --agent 2>/dev/null | jq '.count // 0')
|
||||
if [ "$count" -eq 0 ]; then
|
||||
mem0 add "User prefers dark mode" --user-id alice
|
||||
fi
|
||||
```
|
||||
|
||||
### Quiet mode for scripts
|
||||
|
||||
```bash
|
||||
# Suppress all output except errors
|
||||
mem0 add "background note" --user-id alice --output quiet 2>/dev/null
|
||||
mem0 delete --all --user-id temp-user --force --output quiet 2>/dev/null
|
||||
```
|
||||
|
||||
### Using environment variables for scope
|
||||
|
||||
```bash
|
||||
export MEM0_USER_ID="alice"
|
||||
export MEM0_API_KEY="m0-xxx"
|
||||
|
||||
# All commands now default to user alice, no --user-id needed
|
||||
mem0 add "prefers dark mode"
|
||||
mem0 search "preferences"
|
||||
mem0 list
|
||||
```
|
||||
|
||||
### Timeout handling
|
||||
|
||||
The CLI uses a 30-second timeout for all API requests. For long-running scripts, handle timeouts:
|
||||
|
||||
```bash
|
||||
if ! mem0 search "query" --user-id alice -o json 2>/dev/null; then
|
||||
echo "Request failed or timed out" >&2
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Processing Delay Workaround
|
||||
|
||||
Memories are processed asynchronously after `mem0 add`. If you need to search for a newly added memory immediately, add a short delay:
|
||||
|
||||
```bash
|
||||
mem0 add "new preference" --user-id alice
|
||||
sleep 3
|
||||
mem0 search "new preference" --user-id alice
|
||||
```
|
||||
|
||||
Or use the event system to poll for completion:
|
||||
|
||||
```bash
|
||||
# Add and capture event ID from agent output
|
||||
result=$(mem0 add "new preference" --user-id alice --agent 2>/dev/null)
|
||||
event_id=$(echo "$result" | jq -r '.data[0].event_id // empty')
|
||||
|
||||
if [ -n "$event_id" ]; then
|
||||
# Poll until processing completes
|
||||
while true; do
|
||||
status=$(mem0 event status "$event_id" --agent 2>/dev/null | jq -r '.data.status')
|
||||
if [ "$status" = "SUCCEEDED" ] || [ "$status" = "FAILED" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multi-User Agent Pattern
|
||||
|
||||
For AI agents managing memories across multiple users:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# agent_memory.sh -- manage memories for the current conversation
|
||||
|
||||
USER_ID="$1"
|
||||
ACTION="$2"
|
||||
shift 2
|
||||
|
||||
case "$ACTION" in
|
||||
recall)
|
||||
mem0 search "$*" --user-id "$USER_ID" --agent 2>/dev/null
|
||||
;;
|
||||
remember)
|
||||
mem0 add "$*" --user-id "$USER_ID" --agent 2>/dev/null
|
||||
;;
|
||||
forget)
|
||||
mem0 delete --all --user-id "$USER_ID" --force --agent 2>/dev/null
|
||||
;;
|
||||
history)
|
||||
mem0 list --user-id "$USER_ID" --agent 2>/dev/null
|
||||
;;
|
||||
*)
|
||||
echo '{"status":"error","error":"Unknown action: '"$ACTION"'"}' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
Usage:
|
||||
```bash
|
||||
./agent_memory.sh alice recall "dietary preferences"
|
||||
./agent_memory.sh alice remember "allergic to shellfish"
|
||||
./agent_memory.sh alice history
|
||||
```
|
||||
@@ -0,0 +1,189 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but not
|
||||
limited to compiled object code, generated documentation, and
|
||||
conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work.
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2024 Mem0.ai
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,87 @@
|
||||
# Mem0 Vercel AI SDK Skill for Claude
|
||||
|
||||
Add persistent memory to any Vercel AI SDK application using [@mem0/vercel-ai-provider](https://www.npmjs.com/package/@mem0/vercel-ai-provider).
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
When installed, Claude can:
|
||||
|
||||
- **Set up `@mem0/vercel-ai-provider`** in your TypeScript or Next.js project
|
||||
- **Generate working code** using the wrapped model (`createMem0`) or standalone utilities (`retrieveMemories`, `addMemories`, etc.)
|
||||
- **Configure multi-provider setups** (OpenAI, Anthropic, Google, Groq, Cohere)
|
||||
- **Integrate memory** into streaming responses, structured output, and API routes
|
||||
|
||||
## Installation
|
||||
|
||||
### CLI (Claude Code, OpenCode, OpenClaw, or any tool that supports skills)
|
||||
|
||||
```bash
|
||||
npx skills add https://github.com/mem0ai/mem0 --skill mem0-vercel-ai-sdk
|
||||
```
|
||||
|
||||
### Claude.ai
|
||||
|
||||
1. Download this `skills/mem0-vercel-ai-sdk` folder as a ZIP
|
||||
2. Go to **Settings > Capabilities > Skills**
|
||||
3. Click **Upload skill** and select the ZIP
|
||||
|
||||
### Claude API (Skills API)
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.anthropic.com/v1/skills \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "mem0-vercel-ai-sdk", "source": "https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk"}'
|
||||
```
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js 18+**
|
||||
- **Vercel AI SDK v5** (`ai` package version 5.x)
|
||||
- A Mem0 Platform API key ([Get one here](https://app.mem0.ai/dashboard/api-keys))
|
||||
- An LLM provider API key (OpenAI, Anthropic, Google, Groq, or Cohere)
|
||||
- Set environment variables:
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY="m0-xxx"
|
||||
export OPENAI_API_KEY="sk-xxx" # or your chosen provider's key
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
After installing, just ask Claude:
|
||||
|
||||
- "Add memory to my Vercel AI SDK app"
|
||||
- "Set up mem0 with streamText in my Next.js API route"
|
||||
- "Use retrieveMemories with Anthropic instead of the wrapped model"
|
||||
- "Show me how to use graph memories with the Vercel AI provider"
|
||||
- "Help me store conversation history with addMemories"
|
||||
|
||||
## What's Inside
|
||||
|
||||
```text
|
||||
skills/mem0-vercel-ai-sdk/
|
||||
├── SKILL.md # Skill definition and instructions
|
||||
├── README.md # This file
|
||||
├── LICENSE # Apache-2.0
|
||||
└── references/ # Documentation (loaded on demand)
|
||||
├── provider-api.md # createMem0, Mem0Provider, types, config
|
||||
├── memory-utilities.md # addMemories, retrieveMemories, getMemories, searchMemories
|
||||
└── usage-patterns.md # Working examples: streaming, Next.js, multi-provider, graph
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [Mem0 Platform Dashboard](https://app.mem0.ai)
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 GitHub](https://github.com/mem0ai/mem0)
|
||||
- [@mem0/vercel-ai-provider on npm](https://www.npmjs.com/package/@mem0/vercel-ai-provider)
|
||||
- [Vercel AI SDK Documentation](https://ai-sdk.dev/docs)
|
||||
|
||||
## Skill Graph
|
||||
|
||||
This skill is part of the Mem0 skill graph. The three Mem0 skills (mem0, mem0-cli, mem0-vercel-ai-sdk) each cover a different interface to the same Mem0 Platform API.
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,193 @@
|
||||
---
|
||||
name: mem0-vercel-ai-sdk
|
||||
description: >
|
||||
Mem0 provider for Vercel AI SDK (@mem0/vercel-ai-provider).
|
||||
TRIGGER when: user mentions "vercel ai sdk", "@mem0/vercel-ai-provider",
|
||||
"createMem0", "retrieveMemories", "addMemories", "getMemories",
|
||||
"searchMemories", "mem0 vercel", "AI SDK provider", "AI SDK memory",
|
||||
or is using generateText/streamText with mem0. Also triggers for Next.js
|
||||
apps needing memory-augmented AI.
|
||||
DO NOT TRIGGER when: user asks about direct Python/TS SDK calls without Vercel
|
||||
(use mem0 skill), or CLI terminal commands (use mem0-cli skill).
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: mem0ai
|
||||
version: "1.0.0"
|
||||
category: ai-memory
|
||||
tags: "vercel, ai-sdk, memory, nextjs, typescript, provider"
|
||||
compatibility: Node.js 18+, npm install @mem0/vercel-ai-provider, Vercel AI SDK v5 (ai package), MEM0_API_KEY + LLM provider API key
|
||||
---
|
||||
|
||||
# Mem0 Vercel AI SDK Provider
|
||||
|
||||
Memory-enhanced AI provider for Vercel AI SDK. Automatically retrieves and stores memories during LLM calls.
|
||||
|
||||
## Step 1: Install
|
||||
|
||||
```bash
|
||||
npm install @mem0/vercel-ai-provider ai
|
||||
```
|
||||
|
||||
## Step 2: Set up environment variables
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY="m0-xxx"
|
||||
export OPENAI_API_KEY="sk-xxx" # or ANTHROPIC_API_KEY, GOOGLE_API_KEY, etc.
|
||||
```
|
||||
|
||||
Get a Mem0 API key at: https://app.mem0.ai/dashboard/api-keys
|
||||
|
||||
## Pattern 1: Wrapped Model
|
||||
|
||||
The wrapped model approach is the simplest. `createMem0` returns a provider that wraps any supported LLM with automatic memory retrieval and storage.
|
||||
|
||||
```typescript
|
||||
import { generateText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "Recommend a restaurant",
|
||||
});
|
||||
```
|
||||
|
||||
What happens under the hood:
|
||||
1. The prompt is sent to Mem0 search (`POST /v2/memories/search/`) to retrieve relevant memories
|
||||
2. Retrieved memories are injected as a system message at the start of the prompt
|
||||
3. The underlying LLM (e.g., OpenAI gpt-4-turbo) generates a response using the enriched prompt
|
||||
4. The conversation is stored back to Mem0 (`POST /v1/memories/`) as a fire-and-forget async call (no await)
|
||||
|
||||
## Pattern 2: Standalone Utilities
|
||||
|
||||
Use standalone utilities when you want full control over the memory retrieve/store cycle, or you want to use a provider that is already configured separately.
|
||||
|
||||
```typescript
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { generateText } from "ai";
|
||||
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const prompt = "Recommend a restaurant";
|
||||
|
||||
// Retrieve memories -- returns a formatted system prompt string
|
||||
const memories = await retrieveMemories(prompt, {
|
||||
user_id: "alice",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
});
|
||||
|
||||
// Generate using any provider with injected memories
|
||||
const { text } = await generateText({
|
||||
model: openai("gpt-4-turbo"),
|
||||
prompt,
|
||||
system: memories,
|
||||
});
|
||||
|
||||
// Optionally store the conversation back
|
||||
await addMemories(
|
||||
[
|
||||
{ role: "user", content: [{ type: "text", text: prompt }] },
|
||||
{ role: "assistant", content: [{ type: "text", text }] },
|
||||
],
|
||||
{ user_id: "alice", mem0ApiKey: "m0-xxx" }
|
||||
);
|
||||
```
|
||||
|
||||
## Pattern 3: Streaming
|
||||
|
||||
Use `streamText` for streaming responses with memory augmentation:
|
||||
|
||||
```typescript
|
||||
import { streamText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
const result = streamText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "What should I cook for dinner?",
|
||||
});
|
||||
|
||||
for await (const chunk of result.textStream) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
```
|
||||
|
||||
The wrapped model handles memory retrieval before streaming begins and stores the conversation after.
|
||||
|
||||
## Supported Providers
|
||||
|
||||
| Provider | Config value | Required env var |
|
||||
|----------|-------------|------------------|
|
||||
| OpenAI (default) | `"openai"` | `OPENAI_API_KEY` |
|
||||
| Anthropic | `"anthropic"` | `ANTHROPIC_API_KEY` |
|
||||
| Google | `"google"` | `GOOGLE_GENERATIVE_AI_API_KEY` |
|
||||
| Groq | `"groq"` | `GROQ_API_KEY` |
|
||||
| Cohere | `"cohere"` | `COHERE_API_KEY` |
|
||||
|
||||
Select a provider when creating the Mem0 instance:
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({ provider: "anthropic" });
|
||||
const { text } = await generateText({
|
||||
model: mem0("claude-sonnet-4-20250514", { user_id: "alice" }),
|
||||
prompt: "Hello!",
|
||||
});
|
||||
```
|
||||
|
||||
## How It Works Internally
|
||||
|
||||
### Wrapped model flow
|
||||
|
||||
```
|
||||
User prompt
|
||||
--> searchInternalMemories (POST /v2/memories/search/)
|
||||
--> memories injected as system message at start of prompt
|
||||
--> underlying LLM generates response (doGenerate or doStream)
|
||||
--> processMemories fires addMemories as fire-and-forget (no await)
|
||||
--> response returned to caller
|
||||
```
|
||||
|
||||
### Standalone flow
|
||||
|
||||
```
|
||||
User controls each step:
|
||||
1. retrieveMemories / getMemories / searchMemories -> fetch memories
|
||||
2. inject into system prompt manually
|
||||
3. call generateText / streamText with any provider
|
||||
4. addMemories -> store new conversation to Mem0
|
||||
```
|
||||
|
||||
## Key Differences Between the 4 Utility Functions
|
||||
|
||||
| Function | Returns | Use when |
|
||||
|----------|---------|----------|
|
||||
| `retrieveMemories` | Formatted system prompt **string** | Injecting directly into `system` parameter |
|
||||
| `getMemories` | Raw memory **array** (or full response if `enable_graph`) | Processing memories programmatically |
|
||||
| `searchMemories` | Full search **response** (results + relations) | Need relations, scores, metadata |
|
||||
| `addMemories` | API response | Storing new messages to Mem0 |
|
||||
|
||||
All four accept `LanguageModelV2Prompt | string` as the first argument and optional `Mem0ConfigSettings` as the second.
|
||||
|
||||
## Common Edge Cases and Tips
|
||||
|
||||
- **Always provide `user_id`** (or `agent_id`/`app_id`/`run_id`) for consistent memory retrieval. Without an entity identifier, memories cannot be scoped.
|
||||
- **Standalone utilities require explicit API key**: pass `mem0ApiKey` in the config object, or set the `MEM0_API_KEY` environment variable.
|
||||
- **Graph memories**: set `enable_graph: true` in the config to retrieve graph relations alongside text memories. When enabled, `getMemories` returns the full response (with `results` and `relations`), not just the array.
|
||||
- **This uses Vercel AI SDK v5** (LanguageModelV2 / ProviderV2 interfaces). It is not compatible with AI SDK v3 or v4.
|
||||
- **`processMemories` fires `addMemories` as fire-and-forget** (`.then()` without `await`). Memory storage happens asynchronously and does not block the LLM response.
|
||||
- **The `"gemini"` alias** exists in the provider switch but is NOT in the `supportedProviders` list. Use `"google"` instead.
|
||||
- **Custom host**: set `host` in the config to point to a different Mem0 API endpoint (default: `https://api.mem0.ai`).
|
||||
|
||||
## References
|
||||
|
||||
| Topic | File |
|
||||
|-------|------|
|
||||
| Provider API (`createMem0`, `Mem0Provider`, types) | [local](references/provider-api.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk/references/provider-api.md) |
|
||||
| Memory utilities (`addMemories`, `retrieveMemories`, etc.) | [local](references/memory-utilities.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk/references/memory-utilities.md) |
|
||||
| Usage patterns and examples | [local](references/usage-patterns.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk/references/usage-patterns.md) |
|
||||
|
||||
## Related Mem0 Skills
|
||||
|
||||
| Skill | When to use | Link |
|
||||
|-------|-------------|------|
|
||||
| mem0 | Python/TypeScript SDK, REST API, framework integrations | [local](../mem0/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0) |
|
||||
| mem0-cli | Terminal commands, scripting, CI/CD, agent tool loops | [local](../mem0-cli/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli) |
|
||||
@@ -0,0 +1,284 @@
|
||||
# Memory Utilities Reference
|
||||
|
||||
Complete reference for standalone utility functions exported from `@mem0/vercel-ai-provider`. These functions give you manual control over memory retrieval and storage, independent of the wrapped model pattern.
|
||||
|
||||
Source: `vercel-ai-sdk/src/mem0-utils.ts`
|
||||
|
||||
## `addMemories(messages, config?)`
|
||||
|
||||
Stores messages to Mem0 as new memories.
|
||||
|
||||
```typescript
|
||||
import { addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
await addMemories(
|
||||
[
|
||||
{ role: "user", content: [{ type: "text", text: "I love Italian food" }] },
|
||||
{ role: "assistant", content: [{ type: "text", text: "Noted! I'll remember that." }] },
|
||||
],
|
||||
{ user_id: "alice", mem0ApiKey: "m0-xxx" }
|
||||
);
|
||||
```
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
async function addMemories(
|
||||
messages: LanguageModelV2Prompt | string,
|
||||
config?: Mem0ConfigSettings
|
||||
): Promise<any>;
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `messages` | `LanguageModelV2Prompt \| string` | Messages to store. If a string, wrapped as `[{ role: "user", content: string }]` |
|
||||
| `config` | `Mem0ConfigSettings` | Optional. Must include entity scope (`user_id`, etc.) and API key |
|
||||
|
||||
**Behavior:**
|
||||
1. If `messages` is a string, wraps it as a single user message
|
||||
2. Otherwise, converts `LanguageModelV2Prompt` to Mem0 format via `convertToMem0Format` (handles multimodal content)
|
||||
3. Calls `POST /v1/memories/` with the converted messages and config
|
||||
|
||||
**Returns:** The API response from Mem0 (memory operation result).
|
||||
|
||||
---
|
||||
|
||||
## `retrieveMemories(prompt, config?)`
|
||||
|
||||
Retrieves memories and returns a **formatted system prompt string** ready to inject into a `system` parameter.
|
||||
|
||||
```typescript
|
||||
import { retrieveMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const systemPrompt = await retrieveMemories("What restaurants do I like?", {
|
||||
user_id: "alice",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
});
|
||||
// Returns: "System Message: These are the memories I have stored... Memory: User loves Italian food\n\n ..."
|
||||
```
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
async function retrieveMemories(
|
||||
prompt: LanguageModelV2Prompt | string,
|
||||
config?: Mem0ConfigSettings
|
||||
): Promise<string>;
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `prompt` | `LanguageModelV2Prompt \| string` | The query to search memories for |
|
||||
| `config` | `Mem0ConfigSettings` | Optional. Entity scope and API key |
|
||||
|
||||
**Behavior:**
|
||||
1. Flattens the prompt to a plain string (extracts text from `LanguageModelV2Prompt` parts)
|
||||
2. Calls `searchInternalMemories` (`POST /v2/memories/search/`)
|
||||
3. Formats each memory as `"Memory: {memory.memory}\n\n"`
|
||||
4. If `enable_graph: true`, also appends graph relations as `"Relation: {source} -> {relationship} -> {target}\n\n"`
|
||||
5. Wraps everything in a system prompt preamble
|
||||
|
||||
**Returns:** A **string** containing the formatted system prompt with embedded memories. Returns `""` (empty string) if no memories found.
|
||||
|
||||
**Output format:**
|
||||
```
|
||||
System Message: These are the memories I have stored. Give more weightage to the question by users and try to answer that first. You have to modify your answer based on the memories I have provided. If the memories are irrelevant you can ignore them. Also don't reply to this section of the prompt, or the memories, they are only for your reference. The System prompt starts after text System Message:
|
||||
|
||||
Memory: User loves Italian food
|
||||
|
||||
Memory: User is vegetarian
|
||||
|
||||
HERE ARE THE GRAPHS RELATIONS FOR THE PREFERENCES OF THE USER:
|
||||
|
||||
Relation: Alice -> likes -> Italian cuisine
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `getMemories(prompt, config?)`
|
||||
|
||||
Retrieves memories and returns the **raw memory array** (or full response if graph is enabled).
|
||||
|
||||
```typescript
|
||||
import { getMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const memories = await getMemories("What are my preferences?", {
|
||||
user_id: "alice",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
});
|
||||
// Returns: [{ memory: "User loves Italian food", id: "...", ... }, ...]
|
||||
|
||||
// With graph enabled:
|
||||
const graphMemories = await getMemories("What are my preferences?", {
|
||||
user_id: "alice",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
enable_graph: true,
|
||||
});
|
||||
// Returns: { results: [...], relations: [...] }
|
||||
```
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
async function getMemories(
|
||||
prompt: LanguageModelV2Prompt | string,
|
||||
config?: Mem0ConfigSettings
|
||||
): Promise<any>;
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `prompt` | `LanguageModelV2Prompt \| string` | The query to search memories for |
|
||||
| `config` | `Mem0ConfigSettings` | Optional. Entity scope and API key |
|
||||
|
||||
**Behavior:**
|
||||
1. Flattens the prompt to a plain string
|
||||
2. Calls `searchInternalMemories` (`POST /v2/memories/search/`)
|
||||
3. If `enable_graph` is **not** set: returns `memories.results` (the array of memory objects)
|
||||
4. If `enable_graph` is set: returns the full response object (with both `results` and `relations`)
|
||||
|
||||
**Returns:** Memory object array, or full response object when graph is enabled.
|
||||
|
||||
---
|
||||
|
||||
## `searchMemories(prompt, config?)`
|
||||
|
||||
Retrieves the **full search API response** including results, relations, scores, and metadata.
|
||||
|
||||
```typescript
|
||||
import { searchMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const response = await searchMemories("cooking preferences", {
|
||||
user_id: "alice",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
});
|
||||
// Returns: { results: [{ memory: "...", score: 0.95, ... }], relations: [...] }
|
||||
```
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
async function searchMemories(
|
||||
prompt: LanguageModelV2Prompt | string,
|
||||
config?: Mem0ConfigSettings
|
||||
): Promise<any>;
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `prompt` | `LanguageModelV2Prompt \| string` | The query to search memories for |
|
||||
| `config` | `Mem0ConfigSettings` | Optional. Entity scope and API key |
|
||||
|
||||
**Behavior:**
|
||||
1. Flattens the prompt to a plain string
|
||||
2. Calls `searchInternalMemories` (`POST /v2/memories/search/`)
|
||||
3. Returns the full response without any filtering
|
||||
|
||||
**Returns:** The complete API response object. On error, returns `[]`.
|
||||
|
||||
**Note:** Unlike `getMemories`, this always returns the full response regardless of `enable_graph` setting.
|
||||
|
||||
---
|
||||
|
||||
## When to Use Which Function
|
||||
|
||||
| Function | Returns | Use when |
|
||||
|----------|---------|----------|
|
||||
| `retrieveMemories` | Formatted system prompt **string** | Injecting directly into a `system` parameter for `generateText`/`streamText` |
|
||||
| `getMemories` | Memory **array** (or full response if `enable_graph`) | Processing memories programmatically (filtering, transforming, counting) |
|
||||
| `searchMemories` | Full API **response** (results + relations) | Need relations, similarity scores, or complete metadata regardless of graph setting |
|
||||
| `addMemories` | API response | Storing new conversation messages as memories |
|
||||
|
||||
## Internal: `searchInternalMemories(query, config?, top_k?)`
|
||||
|
||||
Not exported. Used by all retrieval functions.
|
||||
|
||||
```typescript
|
||||
async function searchInternalMemories(
|
||||
query: string,
|
||||
config?: Mem0ConfigSettings,
|
||||
top_k: number = 5
|
||||
): Promise<any>;
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
1. Builds an `OR` filter from entity identifiers (`user_id`, `app_id`, `agent_id`, `run_id`)
|
||||
2. Resolves org/project identifiers (`org_id` takes precedence over `org_name`)
|
||||
3. Loads the API key from `config.mem0ApiKey` or `MEM0_API_KEY` env var
|
||||
4. Calls `POST {host}/v2/memories/search/` with:
|
||||
- `query`: the search string
|
||||
- `filters`: the OR filter object
|
||||
- `top_k`: from config or default 5
|
||||
- `version`: `"v2"`
|
||||
- `output_format`: `"v1.1"`
|
||||
- All other config fields spread into the request body
|
||||
|
||||
**Default host:** `https://api.mem0.ai`
|
||||
|
||||
## Internal: `convertToMem0Format(messages)`
|
||||
|
||||
Not exported. Used by `addMemories` to convert `LanguageModelV2Prompt` messages to Mem0's format.
|
||||
|
||||
**Multimodal content mapping:**
|
||||
|
||||
| Input type | Input format | Output type | Output format |
|
||||
|-----------|-------------|-------------|---------------|
|
||||
| Text | `{ type: "text", text: "..." }` | Plain string | `{ role, content: "..." }` |
|
||||
| Image | `{ type: "image_url", image_url: { url } }` or `{ type: "image", ... }` | Image URL | `{ role, content: { type: "image_url", image_url: { url } } }` |
|
||||
| PDF file | `{ type: "file", data: url, mediaType: "application/pdf" }` | PDF URL | `{ role, content: { type: "pdf_url", pdf_url: { url } } }` |
|
||||
| Markdown file | `{ type: "file", data: url, mediaType: "text/markdown" }` or `"application/mdx"` | MDX URL | `{ role, content: { type: "mdx_url", mdx_url: { url } } }` |
|
||||
| Image file | `{ type: "file", data: url, mediaType: "image/*" }` | Image URL | `{ role, content: { type: "image_url", image_url: { url } } }` |
|
||||
| MDX content | `{ type: "mdx_url", mdx_url: { url } }` or `{ type: "mdx", ... }` | MDX URL | `{ role, content: { type: "mdx_url", mdx_url: { url } } }` |
|
||||
| PDF content | `{ type: "pdf_url", pdf_url: { url } }` or `{ type: "pdf", ... }` | PDF URL | `{ role, content: { type: "pdf_url", pdf_url: { url } } }` |
|
||||
|
||||
The function handles three message content shapes:
|
||||
1. **String content**: passed through directly
|
||||
2. **Array content**: each element mapped individually, nulls filtered out
|
||||
3. **Single object content**: mapped as a single element
|
||||
|
||||
## Internal: `flattenPrompt(prompt)`
|
||||
|
||||
Not exported. Extracts plain text from `LanguageModelV2Prompt` for use as a search query.
|
||||
|
||||
- Iterates over prompt parts, extracting text from `user` role messages
|
||||
- For `text` type content: extracts `.text`
|
||||
- For `file` type content: returns descriptive placeholders (`[PDF document]`, `[Markdown document]`, `[Image]`, `[File attachment]`)
|
||||
- For other content types: returns `[multimodal content]`
|
||||
- Joins all parts with spaces
|
||||
|
||||
## `Mem0ConfigSettings` Fields Reference
|
||||
|
||||
All fields are optional. Used across all utility functions.
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
|-------|------|---------|-------------|
|
||||
| `user_id` | `string` | -- | Scope memories to a user |
|
||||
| `app_id` | `string` | -- | Scope memories to an application |
|
||||
| `agent_id` | `string` | -- | Scope memories to an agent |
|
||||
| `run_id` | `string` | -- | Scope memories to a session/run |
|
||||
| `org_name` | `string` | -- | Organization name (fallback if `org_id` not set) |
|
||||
| `project_name` | `string` | -- | Project name (fallback if `org_id` not set) |
|
||||
| `org_id` | `string` | -- | Organization ID (takes precedence) |
|
||||
| `project_id` | `string` | -- | Project ID |
|
||||
| `metadata` | `Record<string, any>` | -- | Custom metadata |
|
||||
| `filters` | `Record<string, any>` | -- | Custom search filters |
|
||||
| `infer` | `boolean` | -- | Enable inference |
|
||||
| `page` | `number` | -- | Pagination page number |
|
||||
| `page_size` | `number` | -- | Results per page |
|
||||
| `mem0ApiKey` | `string` | `MEM0_API_KEY` env | Mem0 API key |
|
||||
| `top_k` | `number` | `5` | Number of memories to retrieve |
|
||||
| `threshold` | `number` | -- | Minimum similarity score |
|
||||
| `rerank` | `boolean` | -- | Enable re-ranking |
|
||||
| `enable_graph` | `boolean` | -- | Enable graph memory (relations) |
|
||||
| `host` | `string` | `https://api.mem0.ai` | Custom API host |
|
||||
| `output_format` | `string` | -- | Output format version |
|
||||
| `filter_memories` | `boolean` | -- | Enable memory filtering |
|
||||
| `async_mode` | `boolean` | -- | Enable async processing |
|
||||
@@ -0,0 +1,239 @@
|
||||
# Provider API Reference
|
||||
|
||||
Complete reference for the `@mem0/vercel-ai-provider` provider layer. Source: `vercel-ai-sdk/src/`.
|
||||
|
||||
## `createMem0(options?)`
|
||||
|
||||
Factory function that creates a `Mem0Provider` instance. This is the primary entry point for the wrapped model approach.
|
||||
|
||||
```typescript
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0(); // defaults: provider "openai"
|
||||
const mem0 = createMem0({ provider: "anthropic" }); // use Anthropic as LLM backend
|
||||
```
|
||||
|
||||
**Signature:**
|
||||
|
||||
```typescript
|
||||
function createMem0(options?: Mem0ProviderSettings): Mem0Provider;
|
||||
```
|
||||
|
||||
When called with no arguments, defaults to `{ provider: "openai" }`.
|
||||
|
||||
**Returns:** `Mem0Provider` -- a callable function that also exposes `.chat()`, `.completion()`, and `.languageModel()` methods.
|
||||
|
||||
## `Mem0Provider` Interface
|
||||
|
||||
Implements `ProviderV2` from `@ai-sdk/provider`.
|
||||
|
||||
```typescript
|
||||
interface Mem0Provider extends ProviderV2 {
|
||||
// Call directly as a function
|
||||
(modelId: Mem0ChatModelId, settings?: Mem0ChatSettings): LanguageModelV2;
|
||||
|
||||
// Or use named methods
|
||||
chat(modelId: Mem0ChatModelId, settings?: Mem0ChatSettings): LanguageModelV2;
|
||||
completion(modelId: Mem0ChatModelId, settings?: Mem0ChatSettings): LanguageModelV2;
|
||||
languageModel(modelId: Mem0ChatModelId, settings?: Mem0ChatSettings): LanguageModelV2;
|
||||
}
|
||||
```
|
||||
|
||||
- **Direct call** (`mem0("gpt-4-turbo", {...})`): creates a generic language model (neither chat nor completion mode forced).
|
||||
- **`chat()`**: creates a model with `modelType: "chat"` (note: in the current source, the chat constructor sets `modelType: "completion"` -- this appears to be a bug; functionally equivalent to `completion()` at present).
|
||||
- **`completion()`**: creates a model with `modelType: "completion"`.
|
||||
- **`languageModel()`**: alias for the generic model (same as direct call).
|
||||
|
||||
All three return a `Mem0GenericLanguageModel` instance implementing `LanguageModelV2`.
|
||||
|
||||
## `Mem0ProviderSettings` Interface
|
||||
|
||||
Configuration passed to `createMem0()`.
|
||||
|
||||
```typescript
|
||||
interface Mem0ProviderSettings {
|
||||
baseURL?: string; // Base URL for the LLM provider (default: "http://api.openai.com")
|
||||
headers?: Record<string, string>; // Custom headers for LLM requests
|
||||
provider?: string; // LLM provider name (default: "openai")
|
||||
mem0ApiKey?: string; // Mem0 Platform API key (or use MEM0_API_KEY env var)
|
||||
apiKey?: string; // LLM provider API key (e.g., OpenAI key)
|
||||
mem0Config?: Mem0Config; // Default Mem0 config (user_id, etc.) applied to all calls
|
||||
config?: LLMProviderSettings; // Provider-specific settings (OpenAI, Anthropic, etc.)
|
||||
fetch?: typeof fetch; // Custom fetch implementation (for testing/middleware)
|
||||
generateId?: () => string; // Custom ID generator (internal use)
|
||||
name?: string; // Provider instance name
|
||||
modelType?: "completion" | "chat"; // Force model type
|
||||
}
|
||||
```
|
||||
|
||||
### Key fields explained
|
||||
|
||||
| Field | Purpose | Example |
|
||||
|-------|---------|---------|
|
||||
| `provider` | Which LLM backend to use | `"openai"`, `"anthropic"`, `"google"`, `"groq"`, `"cohere"` |
|
||||
| `mem0ApiKey` | Mem0 Platform API key | `"m0-xxx"` |
|
||||
| `apiKey` | LLM provider API key | `"sk-xxx"` (OpenAI), `"sk-ant-xxx"` (Anthropic) |
|
||||
| `mem0Config` | Default Mem0 settings for all calls | `{ user_id: "alice", enable_graph: true }` |
|
||||
| `config` | Provider-specific SDK settings | `{ organization: "org-xxx" }` for OpenAI |
|
||||
| `baseURL` | Override LLM provider base URL | `"https://my-proxy.example.com"` |
|
||||
|
||||
## `mem0` Singleton
|
||||
|
||||
A pre-configured instance using default settings (OpenAI provider, no API keys set -- relies on env vars).
|
||||
|
||||
```typescript
|
||||
import { mem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "Hello",
|
||||
});
|
||||
```
|
||||
|
||||
Equivalent to `createMem0()` with no arguments.
|
||||
|
||||
## `Mem0ConfigSettings` Interface
|
||||
|
||||
Configuration for memory operations. Used as `Mem0ChatSettings` (per-call) or `Mem0Config` (provider-level default). All fields are optional.
|
||||
|
||||
```typescript
|
||||
interface Mem0ConfigSettings {
|
||||
user_id?: string; // Scope memories to a specific user
|
||||
app_id?: string; // Scope memories to an application
|
||||
agent_id?: string; // Scope memories to an agent
|
||||
run_id?: string; // Scope memories to a specific run/session
|
||||
org_name?: string; // Organization name (used if org_id not set)
|
||||
project_name?: string; // Project name (used if org_id not set)
|
||||
org_id?: string; // Organization ID (takes precedence over org_name)
|
||||
project_id?: string; // Project ID (takes precedence over project_name)
|
||||
metadata?: Record<string, any>; // Custom metadata attached to memories
|
||||
filters?: Record<string, any>; // Custom filters for memory search
|
||||
infer?: boolean; // Enable inference during memory operations
|
||||
page?: number; // Pagination: page number
|
||||
page_size?: number; // Pagination: results per page
|
||||
mem0ApiKey?: string; // Mem0 API key (overrides provider-level key)
|
||||
top_k?: number; // Number of memories to retrieve (default: 5)
|
||||
threshold?: number; // Minimum similarity score for retrieval
|
||||
rerank?: boolean; // Enable re-ranking of search results
|
||||
enable_graph?: boolean; // Enable graph memory (returns relations)
|
||||
host?: string; // Custom Mem0 API host (default: "https://api.mem0.ai")
|
||||
output_format?: string; // Output format version
|
||||
filter_memories?: boolean; // Enable memory filtering
|
||||
async_mode?: boolean; // Enable async processing of memory operations
|
||||
}
|
||||
```
|
||||
|
||||
## `Mem0ChatConfig` Type
|
||||
|
||||
Combined type used internally by the language model. Merges memory config with provider config.
|
||||
|
||||
```typescript
|
||||
interface Mem0ChatConfig extends Mem0ConfigSettings, Mem0ProviderSettings {}
|
||||
```
|
||||
|
||||
This means a `Mem0ChatConfig` has all fields from both `Mem0ConfigSettings` and `Mem0ProviderSettings`.
|
||||
|
||||
## `Mem0ChatSettings` Type
|
||||
|
||||
Alias for `Mem0ConfigSettings`. Passed as the second argument when creating a model:
|
||||
|
||||
```typescript
|
||||
mem0("gpt-4-turbo", { user_id: "alice", enable_graph: true })
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// This object is Mem0ChatSettings
|
||||
```
|
||||
|
||||
## `LLMProviderSettings` Type
|
||||
|
||||
Union of provider-specific settings. Extends all supported provider setting interfaces:
|
||||
|
||||
```typescript
|
||||
interface LLMProviderSettings extends
|
||||
OpenAIProviderSettings,
|
||||
AnthropicProviderSettings,
|
||||
CohereProviderSettings,
|
||||
GroqProviderSettings {}
|
||||
```
|
||||
|
||||
Pass via the `config` field of `Mem0ProviderSettings` to forward settings to the underlying LLM provider SDK.
|
||||
|
||||
## Provider Selection: `Mem0ClassSelector`
|
||||
|
||||
Internal class that maps the `provider` string to the correct AI SDK provider.
|
||||
|
||||
```typescript
|
||||
class Mem0ClassSelector {
|
||||
static supportedProviders = ["openai", "anthropic", "cohere", "groq", "google"];
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** The `"gemini"` alias exists in the provider switch statement (maps to `createGoogleGenerativeAI`) but is **NOT** in the `supportedProviders` list. The constructor validates against `supportedProviders`, so using `"gemini"` will throw `"Model not supported: gemini"`. Use `"google"` instead.
|
||||
|
||||
### Provider mapping
|
||||
|
||||
| Config value | SDK used | Factory function |
|
||||
|-------------|----------|------------------|
|
||||
| `"openai"` | `@ai-sdk/openai` | `createOpenAI` |
|
||||
| `"anthropic"` | `@ai-sdk/anthropic` | `createAnthropic` |
|
||||
| `"cohere"` | `@ai-sdk/cohere` | `createCohere` |
|
||||
| `"groq"` | `@ai-sdk/groq` | `createGroq` |
|
||||
| `"google"` | `@ai-sdk/google` | `createGoogleGenerativeAI` |
|
||||
|
||||
## `Mem0` Facade Class
|
||||
|
||||
An alternative exported class that creates models directly without the callable-function pattern.
|
||||
|
||||
```typescript
|
||||
import { Mem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = new Mem0({ provider: "openai" });
|
||||
const chatModel = mem0.chat("gpt-4-turbo", { user_id: "alice" });
|
||||
const completionModel = mem0.completion("gpt-3.5-turbo-instruct");
|
||||
```
|
||||
|
||||
The facade defaults its base URL to `"http://127.0.0.1:11434/api"` (Ollama-style) rather than `"http://api.openai.com"`. It always uses `"openai"` as the provider for created models.
|
||||
|
||||
**Methods:**
|
||||
- `chat(modelId, settings?)` -- creates a model with `modelType: "chat"`
|
||||
- `completion(modelId, settings?)` -- creates a model with `modelType: "completion"`
|
||||
|
||||
## `Mem0GenericLanguageModel` Class
|
||||
|
||||
The core class implementing `LanguageModelV2`. Created by `createMem0` or the `Mem0` facade.
|
||||
|
||||
```typescript
|
||||
class Mem0GenericLanguageModel implements LanguageModelV2 {
|
||||
readonly specificationVersion = "v2";
|
||||
readonly defaultObjectGenerationMode = "json";
|
||||
readonly supportsImageUrls = false;
|
||||
readonly supportedUrls: Record<string, RegExp[]> = { '*': [/.*/] };
|
||||
|
||||
provider: string; // e.g., "openai"
|
||||
modelId: string; // e.g., "gpt-4-turbo"
|
||||
settings: Mem0ChatSettings;
|
||||
config: Mem0ChatConfig;
|
||||
|
||||
async doGenerate(options: LanguageModelV2CallOptions): Promise<...>;
|
||||
async doStream(options: LanguageModelV2CallOptions): Promise<...>;
|
||||
}
|
||||
```
|
||||
|
||||
Both `doGenerate` and `doStream` follow the same internal flow:
|
||||
|
||||
1. Build `Mem0ConfigSettings` from `config.mem0Config` merged with `settings`
|
||||
2. Call `processMemories`:
|
||||
- Fire `addMemories` as fire-and-forget (no await, `.then().catch()`)
|
||||
- Await `getMemories` to retrieve relevant memories
|
||||
- Format memories as a system message and prepend to the prompt
|
||||
3. Create the underlying LLM model via `Mem0ClassSelector`
|
||||
4. Delegate to the underlying model's `doGenerate` or `doStream`
|
||||
5. Return the result
|
||||
|
||||
## Type: `Mem0ChatModelId`
|
||||
|
||||
```typescript
|
||||
type Mem0ChatModelId = string & NonNullable<unknown>;
|
||||
```
|
||||
|
||||
Any non-null string. The model ID is passed through to the underlying provider (e.g., `"gpt-4-turbo"`, `"claude-sonnet-4-20250514"`, `"gemini-pro"`).
|
||||
@@ -0,0 +1,431 @@
|
||||
# Usage Patterns and Examples
|
||||
|
||||
Working examples for `@mem0/vercel-ai-provider`. All examples assume environment variables `MEM0_API_KEY` and the relevant LLM provider API key are set.
|
||||
|
||||
## 1. Wrapped Model with generateText (Basic)
|
||||
|
||||
The simplest way to add memory to any LLM call.
|
||||
|
||||
```typescript
|
||||
import { generateText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "Recommend a restaurant based on my preferences",
|
||||
});
|
||||
|
||||
console.log(text);
|
||||
```
|
||||
|
||||
Memories are automatically retrieved before the call and stored after.
|
||||
|
||||
## 2. Wrapped Model with streamText (Streaming)
|
||||
|
||||
Stream responses with automatic memory augmentation.
|
||||
|
||||
```typescript
|
||||
import { streamText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
const result = streamText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "What should I cook for dinner tonight?",
|
||||
});
|
||||
|
||||
for await (const chunk of result.textStream) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
```
|
||||
|
||||
Memory retrieval happens before streaming begins. The conversation is stored to Mem0 as a fire-and-forget call (non-blocking).
|
||||
|
||||
## 3. Standalone Utilities with OpenAI
|
||||
|
||||
Full control over the memory lifecycle using standalone functions with OpenAI.
|
||||
|
||||
```typescript
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { generateText } from "ai";
|
||||
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const userId = "alice";
|
||||
const prompt = "Suggest a weekend trip";
|
||||
|
||||
// Step 1: Retrieve memories as a formatted system prompt
|
||||
const memories = await retrieveMemories(prompt, {
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
// Step 2: Generate with the memories injected as system context
|
||||
const { text } = await generateText({
|
||||
model: openai("gpt-4-turbo"),
|
||||
prompt,
|
||||
system: memories,
|
||||
});
|
||||
|
||||
console.log(text);
|
||||
|
||||
// Step 3: Store the conversation as new memories
|
||||
await addMemories(
|
||||
[
|
||||
{ role: "user", content: [{ type: "text", text: prompt }] },
|
||||
{ role: "assistant", content: [{ type: "text", text }] },
|
||||
],
|
||||
{ user_id: userId }
|
||||
);
|
||||
```
|
||||
|
||||
## 4. Standalone Utilities with Anthropic
|
||||
|
||||
Same pattern, different LLM provider.
|
||||
|
||||
```typescript
|
||||
import { anthropic } from "@ai-sdk/anthropic";
|
||||
import { generateText } from "ai";
|
||||
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const prompt = "Help me plan my exercise routine";
|
||||
const config = { user_id: "bob" };
|
||||
|
||||
const memories = await retrieveMemories(prompt, config);
|
||||
|
||||
const { text } = await generateText({
|
||||
model: anthropic("claude-sonnet-4-20250514"),
|
||||
prompt,
|
||||
system: memories,
|
||||
});
|
||||
|
||||
await addMemories(
|
||||
[
|
||||
{ role: "user", content: [{ type: "text", text: prompt }] },
|
||||
{ role: "assistant", content: [{ type: "text", text }] },
|
||||
],
|
||||
config
|
||||
);
|
||||
```
|
||||
|
||||
## 5. Structured Output with generateObject
|
||||
|
||||
Use with `generateObject` for typed, structured responses enriched with memory.
|
||||
|
||||
```typescript
|
||||
import { generateObject } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
import { z } from "zod";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
const { object } = await generateObject({
|
||||
model: mem0("gpt-4-turbo", { user_id: "alice" }),
|
||||
prompt: "Suggest a meal plan for today",
|
||||
schema: z.object({
|
||||
breakfast: z.string(),
|
||||
lunch: z.string(),
|
||||
dinner: z.string(),
|
||||
snacks: z.array(z.string()),
|
||||
notes: z.string().describe("Personalization notes based on known preferences"),
|
||||
}),
|
||||
});
|
||||
|
||||
console.log(object);
|
||||
// { breakfast: "Avocado toast (you mentioned loving it)", lunch: "...", ... }
|
||||
```
|
||||
|
||||
The `defaultObjectGenerationMode` is `"json"`, so structured output works out of the box.
|
||||
|
||||
## 6. Graph Memory Enabled
|
||||
|
||||
Retrieve both text memories and entity relationship graphs.
|
||||
|
||||
```typescript
|
||||
import { generateText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", {
|
||||
user_id: "alice",
|
||||
enable_graph: true,
|
||||
}),
|
||||
prompt: "What connections do you know about between my friends?",
|
||||
});
|
||||
|
||||
console.log(text);
|
||||
```
|
||||
|
||||
With `enable_graph: true`, the system prompt includes both:
|
||||
- **Text memories**: `"Memory: Alice is friends with Bob"`
|
||||
- **Graph relations**: `"Relation: Alice -> friends_with -> Bob"`
|
||||
|
||||
### Using graph with standalone utilities
|
||||
|
||||
```typescript
|
||||
import { getMemories, searchMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
// getMemories with graph returns the full response
|
||||
const graphResult = await getMemories("my social connections", {
|
||||
user_id: "alice",
|
||||
enable_graph: true,
|
||||
});
|
||||
console.log(graphResult.results); // memory objects
|
||||
console.log(graphResult.relations); // graph relations
|
||||
|
||||
// searchMemories always returns the full response
|
||||
const fullResponse = await searchMemories("my social connections", {
|
||||
user_id: "alice",
|
||||
});
|
||||
console.log(fullResponse.results);
|
||||
console.log(fullResponse.relations);
|
||||
```
|
||||
|
||||
## 7. Multi-Provider Setup
|
||||
|
||||
Configure different LLM providers with the wrapped model.
|
||||
|
||||
### OpenAI (default)
|
||||
|
||||
```typescript
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0(); // defaults to "openai"
|
||||
const model = mem0("gpt-4-turbo", { user_id: "alice" });
|
||||
```
|
||||
|
||||
### Anthropic
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({ provider: "anthropic" });
|
||||
const model = mem0("claude-sonnet-4-20250514", { user_id: "alice" });
|
||||
```
|
||||
|
||||
### Google
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({ provider: "google" });
|
||||
const model = mem0("gemini-2.0-flash", { user_id: "alice" });
|
||||
```
|
||||
|
||||
### Groq
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({ provider: "groq" });
|
||||
const model = mem0("llama-3.3-70b-versatile", { user_id: "alice" });
|
||||
```
|
||||
|
||||
### Cohere
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({ provider: "cohere" });
|
||||
const model = mem0("command-r-plus", { user_id: "alice" });
|
||||
```
|
||||
|
||||
### With explicit API keys (no env vars)
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({
|
||||
provider: "openai",
|
||||
apiKey: "sk-xxx", // OpenAI API key
|
||||
mem0ApiKey: "m0-xxx", // Mem0 API key
|
||||
});
|
||||
```
|
||||
|
||||
## 8. Next.js API Route Integration
|
||||
|
||||
A POST handler that uses the wrapped model in a Next.js App Router API route.
|
||||
|
||||
```typescript
|
||||
// app/api/chat/route.ts
|
||||
import { streamText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { messages, userId } = await req.json();
|
||||
|
||||
const lastMessage = messages[messages.length - 1];
|
||||
|
||||
const result = streamText({
|
||||
model: mem0("gpt-4-turbo", { user_id: userId }),
|
||||
prompt: lastMessage.content,
|
||||
});
|
||||
|
||||
return result.toDataStreamResponse();
|
||||
}
|
||||
```
|
||||
|
||||
### With standalone utilities for more control
|
||||
|
||||
```typescript
|
||||
// app/api/chat/route.ts
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { streamText } from "ai";
|
||||
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { messages, userId } = await req.json();
|
||||
const lastMessage = messages[messages.length - 1];
|
||||
|
||||
// Retrieve relevant memories
|
||||
const memories = await retrieveMemories(lastMessage.content, {
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
// Stream the response
|
||||
const result = streamText({
|
||||
model: openai("gpt-4-turbo"),
|
||||
prompt: lastMessage.content,
|
||||
system: memories,
|
||||
});
|
||||
|
||||
// Store conversation in the background (fire-and-forget)
|
||||
result.text.then(async (text) => {
|
||||
await addMemories(
|
||||
[
|
||||
{ role: "user", content: [{ type: "text", text: lastMessage.content }] },
|
||||
{ role: "assistant", content: [{ type: "text", text }] },
|
||||
],
|
||||
{ user_id: userId }
|
||||
);
|
||||
});
|
||||
|
||||
return result.toDataStreamResponse();
|
||||
}
|
||||
```
|
||||
|
||||
## 9. How Memory Processing Works Internally
|
||||
|
||||
### Wrapped model flow (doGenerate / doStream)
|
||||
|
||||
```
|
||||
1. doGenerate(options) or doStream(options) is called
|
||||
2. processMemories(messagesPrompts, mem0Config):
|
||||
a. addMemories(messagesPrompts, mem0Config)
|
||||
--> fire-and-forget: .then().catch(), NO await
|
||||
--> POST /v1/memories/ with converted messages
|
||||
b. await getMemories(messagesPrompts, mem0Config)
|
||||
--> POST /v2/memories/search/ with flattened prompt
|
||||
--> returns memory array (or {results, relations} if enable_graph)
|
||||
c. Format memories into system message string
|
||||
d. Prepend system message to messagesPrompts array
|
||||
e. Return { memories, messagesPrompts }
|
||||
3. Create underlying LLM via Mem0ClassSelector.createProvider()
|
||||
4. Call model.doGenerate(updatedOptions) or model.doStream(updatedOptions)
|
||||
5. Return result
|
||||
```
|
||||
|
||||
**Critical detail:** The `addMemories` call in step 2a is **NON-BLOCKING**. It uses `.then().catch()` without `await`, meaning:
|
||||
- Memory storage happens asynchronously in the background
|
||||
- The LLM response is not delayed by the memory write
|
||||
- If the memory write fails, it logs an error but does not affect the response
|
||||
- There is a brief window where the latest conversation is not yet stored
|
||||
|
||||
### Memory injection format
|
||||
|
||||
The memories are injected as a system message at position 0 of the prompt array:
|
||||
|
||||
```typescript
|
||||
{
|
||||
role: "system",
|
||||
content: "System Message: These are the memories I have stored. Give more weightage to the question by users and try to answer that first. You have to modify your answer based on the memories I have provided. If the memories are irrelevant you can ignore them. Also don't reply to this section of the prompt, or the memories, they are only for your reference. The System prompt starts after text System Message: \n\n Memory: ... \n\n Memory: ... \n\n"
|
||||
}
|
||||
```
|
||||
|
||||
## 10. Custom Configuration
|
||||
|
||||
### Custom Mem0 API host
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({
|
||||
mem0Config: {
|
||||
host: "https://my-mem0-instance.example.com",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Or with standalone utilities:
|
||||
|
||||
```typescript
|
||||
const memories = await retrieveMemories(prompt, {
|
||||
user_id: "alice",
|
||||
host: "https://my-mem0-instance.example.com",
|
||||
});
|
||||
```
|
||||
|
||||
### Organization and project scoping
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0();
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", {
|
||||
user_id: "alice",
|
||||
org_id: "org-123",
|
||||
project_id: "proj-456",
|
||||
}),
|
||||
prompt: "Hello",
|
||||
});
|
||||
```
|
||||
|
||||
Note: `org_id` takes precedence over `org_name`. If `org_id` is set, `org_name` and `project_name` are not sent in the request.
|
||||
|
||||
### Memory filtering and ranking
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0();
|
||||
const model = mem0("gpt-4-turbo", {
|
||||
user_id: "alice",
|
||||
top_k: 10, // retrieve up to 10 memories (default: 5)
|
||||
threshold: 0.8, // only memories with score >= 0.8
|
||||
rerank: true, // enable re-ranking of results
|
||||
filter_memories: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Provider-specific configuration
|
||||
|
||||
Pass SDK-specific settings via the `config` field:
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({
|
||||
provider: "openai",
|
||||
config: {
|
||||
organization: "org-xxx",
|
||||
project: "proj-xxx",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Default Mem0 config for all calls
|
||||
|
||||
Set defaults at the provider level that apply to every model created:
|
||||
|
||||
```typescript
|
||||
const mem0 = createMem0({
|
||||
mem0Config: {
|
||||
user_id: "alice",
|
||||
enable_graph: true,
|
||||
top_k: 10,
|
||||
},
|
||||
});
|
||||
|
||||
// These calls inherit user_id, enable_graph, and top_k from mem0Config
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo"),
|
||||
prompt: "Hello",
|
||||
});
|
||||
```
|
||||
|
||||
Per-call settings (passed as the second argument to `mem0()`) are merged on top of `mem0Config`, so you can override specific fields:
|
||||
|
||||
```typescript
|
||||
// Override user_id for this specific call
|
||||
const model = mem0("gpt-4-turbo", { user_id: "bob" });
|
||||
```
|
||||
|
||||
The merge order is: `config.mem0Config` (provider defaults) < `settings` (per-call overrides).
|
||||
+10
-4
@@ -1,13 +1,15 @@
|
||||
# Mem0 Skill for Claude
|
||||
|
||||
Add persistent memory to any AI application in minutes using [Mem0 Platform](https://app.mem0.ai).
|
||||
Add persistent memory to any AI application in minutes using [Mem0 Platform](https://app.mem0.ai) or the open-source self-hosted SDK.
|
||||
|
||||
> **Part of the Mem0 Skill Graph:** See also [mem0-cli](../mem0-cli/SKILL.md) (terminal) and [mem0-vercel-ai-sdk](../mem0-vercel-ai-sdk/SKILL.md) (Vercel AI SDK).
|
||||
|
||||
## What This Skill Does
|
||||
|
||||
When installed, Claude can:
|
||||
|
||||
- **Set up Mem0** in your Python or TypeScript project
|
||||
- **Integrate memory** into your existing AI app (LangChain, CrewAI, Vercel AI, OpenAI Agents, LangGraph, LlamaIndex, etc.)
|
||||
- **Set up Mem0** in your Python or TypeScript project (Platform or OSS)
|
||||
- **Integrate memory** into your existing AI app (LangChain, CrewAI, OpenAI Agents, LangGraph, LlamaIndex, etc.)
|
||||
- **Generate working code** using real API references and tested patterns
|
||||
- **Search live docs** on demand for the latest Mem0 documentation
|
||||
|
||||
@@ -61,6 +63,10 @@ skills/mem0/
|
||||
├── SKILL.md # Skill definition and instructions
|
||||
├── README.md # This file
|
||||
├── LICENSE # Apache-2.0
|
||||
├── client/ # Language-specific SDK references (Platform + OSS)
|
||||
│ ├── python.md # Python SDK (MemoryClient + Memory OSS)
|
||||
│ ├── node.md # TypeScript SDK (MemoryClient + Memory OSS)
|
||||
│ └── differences.md # Python vs TypeScript comparison
|
||||
├── scripts/
|
||||
│ └── mem0_doc_search.py # Search live Mem0 docs on demand
|
||||
└── references/ # Documentation (loaded on demand)
|
||||
@@ -69,7 +75,7 @@ skills/mem0/
|
||||
├── api-reference.md # REST endpoints, filters, memory object
|
||||
├── architecture.md # Processing pipeline, lifecycle, scoping, performance
|
||||
├── features.md # Retrieval, graph, categories, MCP, webhooks, multimodal
|
||||
├── integration-patterns.md # LangChain, CrewAI, Vercel AI, LangGraph, LlamaIndex, etc.
|
||||
├── integration-patterns.md # LangChain, CrewAI, OpenAI Agents, LangGraph, LlamaIndex, etc.
|
||||
└── use-cases.md # 7 real-world patterns with Python + TypeScript code
|
||||
```
|
||||
|
||||
|
||||
+41
-15
@@ -1,25 +1,34 @@
|
||||
---
|
||||
name: mem0
|
||||
description: >
|
||||
Integrate Mem0 Platform into AI applications for persistent memory, personalization, and semantic search.
|
||||
Use this skill when the user mentions "mem0", "memory layer", "remember user preferences",
|
||||
"persistent context", "personalization", or needs to add long-term memory to chatbots, agents,
|
||||
or AI apps. Covers Python and TypeScript SDKs, framework integrations (LangChain, CrewAI,
|
||||
Vercel AI SDK, OpenAI Agents SDK, Pipecat), and the full Platform API. Use even when the user
|
||||
doesn't explicitly say "mem0" but describes needing conversation memory, user context retention,
|
||||
or knowledge retrieval across sessions.
|
||||
Mem0 Platform SDK for adding persistent memory to AI applications.
|
||||
TRIGGER when: user mentions "mem0", "MemoryClient", "memory layer",
|
||||
"remember user preferences", "persistent context", "personalization",
|
||||
or needs to add long-term memory to chatbots, agents, or AI apps.
|
||||
Covers Python SDK (mem0ai), TypeScript SDK (mem0ai), and framework integrations
|
||||
(LangChain, CrewAI, OpenAI Agents SDK, Pipecat, LlamaIndex, AutoGen, LangGraph).
|
||||
Also covers the open-source self-hosted Memory class.
|
||||
This is the DEFAULT mem0 skill for ambiguous queries.
|
||||
DO NOT TRIGGER when: user asks about CLI commands, terminal usage, or shell
|
||||
scripts (use mem0-cli), or Vercel AI SDK / @mem0/vercel-ai-provider / createMem0
|
||||
(use mem0-vercel-ai-sdk).
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: mem0ai
|
||||
version: "1.0.0"
|
||||
version: "2.0.0"
|
||||
category: ai-memory
|
||||
tags: "memory, personalization, ai, python, typescript, vector-search"
|
||||
compatibility: Requires Python 3.10+ or Node.js 18+, pip install mem0ai or npm install mem0ai, MEM0_API_KEY env var, and internet access to api.mem0.ai
|
||||
compatibility: Requires Python 3.10+ or Node.js 18+, pip install mem0ai or npm install mem0ai, MEM0_API_KEY env var (Platform), and internet access to api.mem0.ai
|
||||
---
|
||||
|
||||
# Mem0 Platform Integration
|
||||
|
||||
Mem0 is a managed memory layer for AI applications. It stores, retrieves, and manages user memories via API — no infrastructure to deploy.
|
||||
> **Skill Graph:** This skill is part of the Mem0 skill graph:
|
||||
> - **mem0** (this skill) -- Platform Client SDK + OSS (Python + TypeScript)
|
||||
> - **[mem0-cli](../mem0-cli/SKILL.md)** ([GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli)) -- Command-line interface
|
||||
> - **[mem0-vercel-ai-sdk](../mem0-vercel-ai-sdk/SKILL.md)** ([GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk)) -- Vercel AI SDK provider
|
||||
|
||||
Mem0 is a managed memory layer for AI applications. It stores, retrieves, and manages user memories via API — no infrastructure to deploy. For self-hosted usage, see the OSS section in the client references below.
|
||||
|
||||
## Step 1: Install and authenticate
|
||||
|
||||
@@ -134,14 +143,24 @@ def chat(user_input: str, user_id: str) -> str:
|
||||
For the latest docs beyond what's in the references, use the doc search tool:
|
||||
|
||||
```bash
|
||||
python scripts/mem0_doc_search.py --query "topic"
|
||||
python scripts/mem0_doc_search.py --page "/platform/features/graph-memory"
|
||||
python scripts/mem0_doc_search.py --index
|
||||
python ${CLAUDE_SKILL_DIR}/scripts/mem0_doc_search.py --query "topic"
|
||||
python ${CLAUDE_SKILL_DIR}/scripts/mem0_doc_search.py --page "/platform/features/graph-memory"
|
||||
python ${CLAUDE_SKILL_DIR}/scripts/mem0_doc_search.py --index
|
||||
```
|
||||
|
||||
No API key needed — searches docs.mem0.ai directly.
|
||||
|
||||
## References
|
||||
## Client SDK References
|
||||
|
||||
Language-specific deep references (Platform + OSS):
|
||||
|
||||
| Language | File |
|
||||
|----------|------|
|
||||
| Python (MemoryClient + AsyncMemoryClient + Memory OSS) | [client/python.md](client/python.md) |
|
||||
| TypeScript/Node.js (MemoryClient + Memory OSS) | [client/node.md](client/node.md) |
|
||||
| Python vs TypeScript differences | [client/differences.md](client/differences.md) |
|
||||
|
||||
## Platform References
|
||||
|
||||
Load these on demand for deeper detail:
|
||||
|
||||
@@ -152,5 +171,12 @@ Load these on demand for deeper detail:
|
||||
| API reference (endpoints, filters, object schema) | [references/api-reference.md](references/api-reference.md) |
|
||||
| Architecture (pipeline, lifecycle, scoping, performance) | [references/architecture.md](references/architecture.md) |
|
||||
| Platform features (retrieval, graph, categories, MCP, etc.) | [references/features.md](references/features.md) |
|
||||
| Framework integrations (LangChain, CrewAI, Vercel AI, etc.) | [references/integration-patterns.md](references/integration-patterns.md) |
|
||||
| Framework integrations (LangChain, CrewAI, OpenAI Agents, etc.) | [references/integration-patterns.md](references/integration-patterns.md) |
|
||||
| Use cases & examples (real-world patterns with code) | [references/use-cases.md](references/use-cases.md) |
|
||||
|
||||
## Related Mem0 Skills
|
||||
|
||||
| Skill | When to use | Link |
|
||||
|-------|-------------|------|
|
||||
| mem0-cli | Terminal commands, scripting, CI/CD, agent tool loops | [local](../mem0-cli/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli) |
|
||||
| mem0-vercel-ai-sdk | Vercel AI SDK provider with automatic memory | [local](../mem0-vercel-ai-sdk/SKILL.md) / [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk) |
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# Python vs TypeScript SDK Differences
|
||||
|
||||
Quick-reference cheatsheet for developers working across both Mem0 SDKs.
|
||||
|
||||
## Constructor
|
||||
|
||||
| Aspect | Python | TypeScript |
|
||||
|--------|--------|------------|
|
||||
| Import (Platform) | `from mem0 import MemoryClient` | `import MemoryClient from 'mem0ai'` |
|
||||
| Import (OSS) | `from mem0 import Memory` | `import { Memory } from 'mem0ai/oss'` |
|
||||
| Constructor | `MemoryClient(api_key="m0-xxx")` | `new MemoryClient({ apiKey: 'm0-xxx' })` |
|
||||
| Required param | `api_key` (positional or kwarg) | `apiKey` (in options object) |
|
||||
|
||||
Both read from `MEM0_API_KEY` env var if no key provided.
|
||||
|
||||
## Method Naming
|
||||
|
||||
| Operation | Python | TypeScript |
|
||||
|-----------|--------|------------|
|
||||
| Add | `add()` | `add()` |
|
||||
| Search | `search()` | `search()` |
|
||||
| Get | `get()` | `get()` |
|
||||
| Get all | `get_all()` | `getAll()` |
|
||||
| Update | `update()` | `update()` |
|
||||
| Delete | `delete()` | `delete()` |
|
||||
| Delete all | `delete_all()` | `deleteAll()` |
|
||||
| History | `history()` | `history()` |
|
||||
| Batch update | `batch_update()` | `batchUpdate()` |
|
||||
| Batch delete | `batch_delete()` | `batchDelete()` |
|
||||
| List users | `users()` | `users()` |
|
||||
| Delete users | `delete_users()` | `deleteUsers()` |
|
||||
| Get project | `project.get()` | `getProject()` |
|
||||
| Update project | `project.update()` | `updateProject()` |
|
||||
| Create webhook | `create_webhook()` | `createWebhook()` |
|
||||
| Get webhooks | `get_webhooks()` | `getWebhooks()` |
|
||||
| Update webhook | `update_webhook()` | `updateWebhook()` |
|
||||
| Delete webhook | `delete_webhook()` | `deleteWebhook()` |
|
||||
| Create export | `create_memory_export()` | `createMemoryExport()` |
|
||||
| Get export | `get_memory_export()` | `getMemoryExport()` |
|
||||
| Feedback | `feedback()` | `feedback()` |
|
||||
|
||||
**Rule:** Python uses `snake_case`, TypeScript uses `camelCase` for method names.
|
||||
|
||||
## Parameter Passing
|
||||
|
||||
```python
|
||||
# Python: kwargs
|
||||
client.add(messages, user_id="alice", metadata={"source": "chat"})
|
||||
client.search("query", user_id="alice", top_k=5, rerank=True)
|
||||
```
|
||||
|
||||
```typescript
|
||||
// TypeScript: options object
|
||||
await client.add(messages, { user_id: 'alice', metadata: { source: 'chat' } });
|
||||
await client.search('query', { user_id: 'alice', top_k: 5, rerank: true });
|
||||
```
|
||||
|
||||
**Important:** Both use `snake_case` for API parameter names (`user_id`, `agent_id`, `top_k`, etc.). Only method names differ.
|
||||
|
||||
Exception: OSS TypeScript uses `camelCase` for config params (`userId`, `agentId`, `runId`).
|
||||
|
||||
## Architectural Differences
|
||||
|
||||
| Aspect | Python | TypeScript |
|
||||
|--------|--------|------------|
|
||||
| HTTP library | httpx | axios |
|
||||
| Default timeout | 300s | 60s |
|
||||
| Sync support | Yes (`MemoryClient`) | No (all async) |
|
||||
| Async support | Yes (`AsyncMemoryClient`) | All methods are async |
|
||||
| Project management | `client.project.*` (separate class) | `client.getProject()` / `client.updateProject()` |
|
||||
| Context manager | `async with AsyncMemoryClient()` | Not supported |
|
||||
|
||||
## Platform Features: Python-only
|
||||
|
||||
These methods exist in Python but not TypeScript:
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `get_summary(filters)` | Get summary of memories |
|
||||
| `reset()` | Delete ALL data (users + memories) |
|
||||
| `project.create(name)` | Create a new project |
|
||||
| `project.delete()` | Delete current project |
|
||||
| `project.get_members()` | List project members |
|
||||
| `project.add_member(email, role)` | Add member to project |
|
||||
| `project.update_member(email, role)` | Change member role |
|
||||
| `project.remove_member(email)` | Remove member |
|
||||
|
||||
## Platform Features: TypeScript-only
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `deleteUser(data)` | Convenience method for single entity deletion |
|
||||
| `ping()` | Health check endpoint |
|
||||
|
||||
## OSS Config Naming
|
||||
|
||||
| Python config key | TypeScript config key |
|
||||
|-------------------|----------------------|
|
||||
| `vector_store` | `vectorStore` |
|
||||
| `graph_store` | `graphStore` |
|
||||
| `history_db_path` | `historyDbPath` |
|
||||
| `custom_fact_extraction_prompt` | `customPrompt` |
|
||||
| `enable_graph` | `enableGraph` |
|
||||
|
||||
## OSS Scope Parameter Naming
|
||||
|
||||
| Python | TypeScript |
|
||||
|--------|------------|
|
||||
| `user_id="alice"` | `userId: 'alice'` |
|
||||
| `agent_id="bot"` | `agentId: 'bot'` |
|
||||
| `run_id="session"` | `runId: 'session'` |
|
||||
|
||||
## Common Gotcha
|
||||
|
||||
When searching/filtering, **both SDKs use `snake_case`** for filter keys:
|
||||
|
||||
```python
|
||||
# Python
|
||||
filters = {"AND": [{"user_id": "alice"}, {"categories": {"contains": "health"}}]}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// TypeScript -- same snake_case in filter objects!
|
||||
const filters = { AND: [{ user_id: 'alice' }, { categories: { contains: 'health' } }] };
|
||||
```
|
||||
@@ -0,0 +1,412 @@
|
||||
# Mem0 Node.js / TypeScript SDK Reference
|
||||
|
||||
Complete reference for the `mem0ai` npm package. Covers both the Platform client (managed API) and the Open Source self-hosted variant.
|
||||
|
||||
---
|
||||
|
||||
## Platform Client
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install mem0ai
|
||||
export MEM0_API_KEY="m0-your-api-key"
|
||||
```
|
||||
|
||||
### MemoryClient
|
||||
|
||||
```typescript
|
||||
import MemoryClient from 'mem0ai';
|
||||
|
||||
const client = new MemoryClient({ apiKey: 'm0-xxx' });
|
||||
```
|
||||
|
||||
**Constructor:** `new MemoryClient({ apiKey })`. If `apiKey` is not provided, reads from `MEM0_API_KEY` environment variable.
|
||||
|
||||
- HTTP library: `axios`
|
||||
- Timeout: 60 seconds
|
||||
- Base URL: `https://api.mem0.ai`
|
||||
- All methods are async (return `Promise`)
|
||||
|
||||
---
|
||||
|
||||
### Memory Methods
|
||||
|
||||
#### add(messages, options?)
|
||||
|
||||
Store new memories from messages.
|
||||
|
||||
```typescript
|
||||
const messages = [
|
||||
{ role: 'user', content: "I'm a vegetarian and allergic to nuts." },
|
||||
{ role: 'assistant', content: "Got it! I'll remember that." },
|
||||
];
|
||||
await client.add(messages, { user_id: 'alice' });
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `messages` | `Message[]` | Array of `{role, content}` objects |
|
||||
| `options.user_id` | string | User identifier |
|
||||
| `options.agent_id` | string | Agent identifier |
|
||||
| `options.app_id` | string | Application identifier |
|
||||
| `options.run_id` | string | Session identifier |
|
||||
| `options.metadata` | object | Custom key-value pairs |
|
||||
| `options.enable_graph` | boolean | Activate knowledge graph |
|
||||
| `options.infer` | boolean | If false, store raw text (default: true) |
|
||||
| `options.immutable` | boolean | Prevent future modification |
|
||||
| `options.expiration_date` | string | Auto-expiry (`YYYY-MM-DD`) |
|
||||
| `options.includes` | string | Preference filter for inclusion |
|
||||
| `options.excludes` | string | Preference filter for exclusion |
|
||||
|
||||
**Returns:** `Promise<any>` -- list of events
|
||||
|
||||
#### search(query, options?)
|
||||
|
||||
Search memories by semantic similarity.
|
||||
|
||||
```typescript
|
||||
const results = await client.search('dietary preferences', { user_id: 'alice' });
|
||||
for (const mem of results.results) {
|
||||
console.log(mem.memory, mem.score);
|
||||
}
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `query` | string | Natural language search query |
|
||||
| `options.user_id` | string | Filter by user |
|
||||
| `options.agent_id` | string | Filter by agent |
|
||||
| `options.filters` | object | V2 filter object (`AND`/`OR`/`NOT`) |
|
||||
| `options.top_k` | number | Number of results (default: 10) |
|
||||
| `options.rerank` | boolean | Enable semantic reranking |
|
||||
| `options.threshold` | number | Minimum similarity (default: 0.3) |
|
||||
| `options.keyword_search` | boolean | Enable keyword search |
|
||||
| `options.enable_graph` | boolean | Include graph relations |
|
||||
| `options.filter_memories` | boolean | Precision filtering |
|
||||
|
||||
**Returns:** `Promise<SearchResult>` -- `{results: [{id, memory, score, ...}], relations: [...]}`
|
||||
|
||||
#### get(memoryId)
|
||||
|
||||
```typescript
|
||||
const memory = await client.get('ea925981-...');
|
||||
```
|
||||
|
||||
#### getAll(options?)
|
||||
|
||||
Retrieve all memories. Requires at least one entity identifier in filters.
|
||||
|
||||
```typescript
|
||||
const memories = await client.getAll({ user_id: 'alice' });
|
||||
// With filters
|
||||
const filtered = await client.getAll({
|
||||
filters: { AND: [{ user_id: 'alice' }, { categories: { contains: 'health' } }] },
|
||||
});
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `options.user_id` | string | Filter by user |
|
||||
| `options.filters` | object | V2 filter object |
|
||||
| `options.page` | number | Page number |
|
||||
| `options.page_size` | number | Results per page |
|
||||
| `options.enable_graph` | boolean | Include graph relations |
|
||||
|
||||
#### update(memoryId, data)
|
||||
|
||||
```typescript
|
||||
await client.update('ea925981-...', { text: 'Updated: vegan since 2024' });
|
||||
await client.update('ea925981-...', { text: 'Updated', metadata: { verified: true } });
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `memoryId` | string | Memory ID |
|
||||
| `data.text` | string | New content |
|
||||
| `data.metadata` | object | New metadata |
|
||||
| `data.timestamp` | string | New timestamp |
|
||||
|
||||
#### delete(memoryId)
|
||||
|
||||
```typescript
|
||||
await client.delete('ea925981-...');
|
||||
```
|
||||
|
||||
#### deleteAll(options?)
|
||||
|
||||
```typescript
|
||||
await client.deleteAll({ user_id: 'alice' });
|
||||
```
|
||||
|
||||
#### history(memoryId)
|
||||
|
||||
```typescript
|
||||
const history = await client.history('ea925981-...');
|
||||
// Returns: [{previous_value, new_value, action, timestamps}]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Batch Methods
|
||||
|
||||
#### batchUpdate(memories)
|
||||
|
||||
```typescript
|
||||
await client.batchUpdate([
|
||||
{ memoryId: 'uuid-1', text: 'Updated text' },
|
||||
{ memoryId: 'uuid-2', text: 'Another update' },
|
||||
]);
|
||||
```
|
||||
|
||||
#### batchDelete(memories)
|
||||
|
||||
```typescript
|
||||
await client.batchDelete(['uuid-1', 'uuid-2', 'uuid-3']);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### User/Entity Management
|
||||
|
||||
#### users()
|
||||
|
||||
```typescript
|
||||
const users = await client.users();
|
||||
// Returns: {results: [{type: "user", name: "alice"}, ...]}
|
||||
```
|
||||
|
||||
#### deleteUser(data) / deleteUsers(data)
|
||||
|
||||
```typescript
|
||||
await client.deleteUser({ user_id: 'alice' }); // Single entity
|
||||
await client.deleteUsers({ agent_id: 'bot-1' }); // Flexible
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Project Management
|
||||
|
||||
```typescript
|
||||
// Get project config
|
||||
const config = await client.getProject({ fields: ['custom_categories'] });
|
||||
|
||||
// Update project settings
|
||||
await client.updateProject({
|
||||
custom_instructions: 'Extract dietary preferences and health info',
|
||||
custom_categories: [{ health: 'Medical and dietary info' }],
|
||||
enable_graph: true,
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Webhooks
|
||||
|
||||
```typescript
|
||||
// List
|
||||
const webhooks = await client.getWebhooks({ project_id: 'proj_123' });
|
||||
|
||||
// Create
|
||||
const webhook = await client.createWebhook({
|
||||
url: 'https://your-app.com/webhook',
|
||||
name: 'Memory Logger',
|
||||
project_id: 'proj_123',
|
||||
event_types: ['memory_add', 'memory_update'],
|
||||
});
|
||||
|
||||
// Update
|
||||
await client.updateWebhook({
|
||||
webhook_id: 'wh_123',
|
||||
name: 'Updated Logger',
|
||||
url: 'https://new-url.com',
|
||||
});
|
||||
|
||||
// Delete
|
||||
await client.deleteWebhook({ webhook_id: 'wh_123' });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Feedback
|
||||
|
||||
```typescript
|
||||
await client.feedback({
|
||||
memory_id: 'mem-123',
|
||||
feedback: 'POSITIVE',
|
||||
feedback_reason: 'Accurately captured preference',
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Export
|
||||
|
||||
```typescript
|
||||
const exportReq = await client.createMemoryExport({
|
||||
schema: JSON.stringify({ type: 'object', properties: { name: { type: 'string' } } }),
|
||||
filters: { user_id: 'alice' },
|
||||
});
|
||||
|
||||
const result = await client.getMemoryExport({ memory_export_id: exportReq.id });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### TypeScript Types
|
||||
|
||||
Key interfaces from `mem0.types.ts`:
|
||||
|
||||
```typescript
|
||||
interface Message { role: string; content: string; }
|
||||
interface Memory { id: string; memory: string; user_id: string; categories: string[]; score?: number; /* ... */ }
|
||||
interface MemoryOptions { user_id?: string; agent_id?: string; app_id?: string; run_id?: string; metadata?: object; /* ... */ }
|
||||
interface SearchOptions { user_id?: string; filters?: object; top_k?: number; rerank?: boolean; threshold?: number; /* ... */ }
|
||||
interface MemoryHistory { id: string; memory_id: string; previous_value: string; new_value: string; action: string; /* ... */ }
|
||||
interface FeedbackPayload { memory_id: string; feedback: string; feedback_reason?: string; }
|
||||
interface WebhookCreatePayload { url: string; name: string; project_id: string; event_types: string[]; }
|
||||
enum OutputFormat { v1_0 = 'v1.0', v1_1 = 'v1.1' }
|
||||
enum API_VERSION { v1 = 'v1', v2 = 'v2' }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Source / Self-Hosted
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install mem0ai
|
||||
```
|
||||
|
||||
### Memory Class
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const m = new Memory(); // Uses default config
|
||||
```
|
||||
|
||||
**Import:** `from 'mem0ai/oss'` (NOT the default export -- that is `MemoryClient` for Platform)
|
||||
|
||||
### Configuration
|
||||
|
||||
```typescript
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'openai', // openai, groq, anthropic, google, ollama, lmstudio, mistral, azure
|
||||
config: {
|
||||
model: 'gpt-4o-mini',
|
||||
apiKey: 'sk-xxx',
|
||||
},
|
||||
},
|
||||
embedder: {
|
||||
provider: 'openai', // openai, ollama, lmstudio, google, azure, langchain, anthropic
|
||||
config: {
|
||||
model: 'text-embedding-3-small',
|
||||
apiKey: 'sk-xxx',
|
||||
},
|
||||
},
|
||||
vectorStore: {
|
||||
provider: 'qdrant', // memory, qdrant, redis, supabase, langchain, azure_ai_search, pgvector
|
||||
config: {
|
||||
collectionName: 'my_memories',
|
||||
host: 'localhost',
|
||||
port: 6333,
|
||||
},
|
||||
},
|
||||
graphStore: { // Optional
|
||||
provider: 'neo4j',
|
||||
config: {
|
||||
url: 'neo4j://localhost:7687',
|
||||
username: 'neo4j',
|
||||
password: 'password',
|
||||
},
|
||||
},
|
||||
historyDbPath: 'history.db',
|
||||
customPrompt: '...',
|
||||
enableGraph: false,
|
||||
disableHistory: false,
|
||||
};
|
||||
|
||||
const m = new Memory(config);
|
||||
// Or from dict with validation:
|
||||
const m2 = Memory.fromConfig(config);
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
All methods are async (return `Promise`):
|
||||
|
||||
#### add(messages, config)
|
||||
|
||||
```typescript
|
||||
await m.add('I prefer dark mode', { userId: 'alice' });
|
||||
await m.add([
|
||||
{ role: 'user', content: 'I like hiking' },
|
||||
{ role: 'assistant', content: 'Great outdoor activity!' },
|
||||
], { userId: 'alice' });
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `messages` | `string \| Message[]` | Content to store |
|
||||
| `config.userId` | string | User identifier (at least one scope required) |
|
||||
| `config.agentId` | string | Agent identifier |
|
||||
| `config.runId` | string | Session identifier |
|
||||
| `config.metadata` | object | Custom key-value pairs |
|
||||
| `config.filters` | object | Additional filters |
|
||||
| `config.infer` | boolean | LLM inference (default: true) |
|
||||
|
||||
**Returns:** `Promise<{results: [...], relations?: [...]}>`
|
||||
|
||||
#### search(query, config)
|
||||
|
||||
```typescript
|
||||
const results = await m.search('dietary preferences', { userId: 'alice', limit: 5 });
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `query` | string | Search query |
|
||||
| `config.userId` | string | Filter by user |
|
||||
| `config.agentId` | string | Filter by agent |
|
||||
| `config.runId` | string | Filter by run |
|
||||
| `config.limit` | number | Max results (default: 100) |
|
||||
| `config.filters` | object | Advanced filters |
|
||||
|
||||
#### get(memoryId) / getAll(config) / update(memoryId, data) / delete(memoryId) / deleteAll(config) / history(memoryId)
|
||||
|
||||
Same interface patterns. Note: OSS `update` takes a string for data, not an object.
|
||||
|
||||
```typescript
|
||||
await m.update('mem-id', 'new content');
|
||||
```
|
||||
|
||||
#### reset()
|
||||
|
||||
Clear the entire vector store and history.
|
||||
|
||||
```typescript
|
||||
await m.reset();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Differences: Platform vs OSS
|
||||
|
||||
| Aspect | Platform (`MemoryClient`) | OSS (`Memory`) |
|
||||
|--------|--------------------------|----------------|
|
||||
| **Import** | `import MemoryClient from 'mem0ai'` | `import { Memory } from 'mem0ai/oss'` |
|
||||
| **Auth** | API key required (`MEM0_API_KEY`) | No API key -- config-based |
|
||||
| **Execution** | API calls to `api.mem0.ai` | Local execution |
|
||||
| **Infrastructure** | Fully managed | Self-managed vector DB, embedder, LLM |
|
||||
| **Param style** | `snake_case` in options (`user_id`) | `camelCase` in config (`userId`) |
|
||||
| **Batch ops** | `batchUpdate`, `batchDelete` | Not available |
|
||||
| **Webhooks** | Full CRUD | Not available |
|
||||
| **Export** | `createMemoryExport` | Not available |
|
||||
| **Feedback** | `feedback()` | Not available |
|
||||
| **Project mgmt** | `getProject`, `updateProject` | Not available |
|
||||
| **User listing** | `users()`, `deleteUser()` | Not available |
|
||||
| **Graph store** | Platform-managed | Self-managed (Neo4j) |
|
||||
| **History** | Platform-managed | SQLite (configurable) |
|
||||
@@ -0,0 +1,481 @@
|
||||
# Mem0 Python SDK Reference
|
||||
|
||||
Complete reference for the `mem0ai` Python package. Covers both the Platform client (managed API) and the Open Source self-hosted variant.
|
||||
|
||||
---
|
||||
|
||||
## Platform Client
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install mem0ai
|
||||
export MEM0_API_KEY="m0-your-api-key"
|
||||
```
|
||||
|
||||
### MemoryClient (Synchronous)
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="m0-xxx")
|
||||
```
|
||||
|
||||
**Constructor:** `MemoryClient(api_key=None)`. If `api_key` is not provided, reads from `MEM0_API_KEY` environment variable. Raises `ValueError` if no key found.
|
||||
|
||||
- HTTP library: `httpx`
|
||||
- Timeout: 300 seconds
|
||||
- Base URL: `https://api.mem0.ai`
|
||||
|
||||
### AsyncMemoryClient (Asynchronous)
|
||||
|
||||
```python
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
client = AsyncMemoryClient(api_key="m0-xxx")
|
||||
|
||||
# Or use as context manager
|
||||
async with AsyncMemoryClient(api_key="m0-xxx") as client:
|
||||
results = await client.search("query", user_id="alice")
|
||||
```
|
||||
|
||||
Same methods as `MemoryClient`, all `async`/`await`. Supports async context manager.
|
||||
|
||||
---
|
||||
|
||||
### Memory Methods
|
||||
|
||||
#### add(messages, **kwargs)
|
||||
|
||||
Store new memories from messages.
|
||||
|
||||
```python
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm a vegetarian and allergic to nuts."},
|
||||
{"role": "assistant", "content": "Got it! I'll remember that."}
|
||||
]
|
||||
client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `messages` | str \| dict \| list[dict] | required | Message content. Strings auto-convert to user messages |
|
||||
| `user_id` | str | None | User identifier |
|
||||
| `agent_id` | str | None | Agent identifier |
|
||||
| `app_id` | str | None | Application identifier |
|
||||
| `run_id` | str | None | Session/run identifier |
|
||||
| `metadata` | dict | None | Custom key-value pairs |
|
||||
| `enable_graph` | bool | None | Activate knowledge graph extraction |
|
||||
| `infer` | bool | True | If False, store raw text without LLM inference |
|
||||
| `immutable` | bool | None | If True, prevents future modification |
|
||||
| `expiration_date` | str | None | Auto-expiry date (`YYYY-MM-DD`) |
|
||||
| `includes` | str | None | Preference filter for inclusion |
|
||||
| `excludes` | str | None | Preference filter for exclusion |
|
||||
| `async_mode` | bool | True | If False, wait for processing to complete |
|
||||
| `custom_categories` | list | None | Override project categories |
|
||||
| `custom_instructions` | str | None | Override extraction instructions |
|
||||
| `timestamp` | int \| float \| str | None | Custom timestamp (Unix epoch or ISO 8601) |
|
||||
|
||||
**Returns:** `dict` -- list of events: `[{"id": "...", "event": "ADD|UPDATE|DELETE", "data": {"memory": "..."}}]`
|
||||
|
||||
#### search(query, **kwargs)
|
||||
|
||||
Search memories by semantic similarity.
|
||||
|
||||
```python
|
||||
results = client.search("dietary preferences", user_id="alice")
|
||||
for mem in results.get("results", []):
|
||||
print(mem["memory"], mem["score"])
|
||||
```
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `query` | str | required | Natural language search query |
|
||||
| `user_id` | str | None | Filter by user |
|
||||
| `agent_id` | str | None | Filter by agent |
|
||||
| `app_id` | str | None | Filter by app |
|
||||
| `top_k` | int | 10 | Number of results |
|
||||
| `filters` | dict | None | V2 filter object (`AND`/`OR`/`NOT`) |
|
||||
| `rerank` | bool | None | Enable deep semantic reranking (+150-200ms) |
|
||||
| `threshold` | float | 0.3 | Minimum similarity score |
|
||||
| `keyword_search` | bool | None | Enable keyword-based search (+10ms) |
|
||||
| `enable_graph` | bool | None | Include graph relations in results |
|
||||
| `filter_memories` | bool | None | Precision filtering, removes low-relevance (+200-300ms) |
|
||||
| `fields` | list | None | Specific fields to return |
|
||||
| `categories` | list | None | Filter by category |
|
||||
|
||||
**Returns:** `dict` -- `{"results": [{id, memory, user_id, categories, score, created_at, ...}], "relations": [...]}`
|
||||
|
||||
#### get(memory_id)
|
||||
|
||||
Retrieve a single memory by ID.
|
||||
|
||||
```python
|
||||
memory = client.get(memory_id="ea925981-...")
|
||||
```
|
||||
|
||||
**Returns:** `dict` -- full memory object
|
||||
|
||||
#### get_all(**kwargs)
|
||||
|
||||
Retrieve all memories with optional filtering. Requires at least one entity identifier.
|
||||
|
||||
```python
|
||||
memories = client.get_all(user_id="alice")
|
||||
# With filters
|
||||
memories = client.get_all(filters={"AND": [{"user_id": "alice"}, {"categories": {"contains": "health"}}]})
|
||||
```
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `user_id` | str | None | Filter by user |
|
||||
| `agent_id` | str | None | Filter by agent |
|
||||
| `app_id` | str | None | Filter by app |
|
||||
| `top_k` | int | None | Limit results |
|
||||
| `page` | int | None | Page number |
|
||||
| `page_size` | int | None | Results per page |
|
||||
| `filters` | dict | None | V2 filter object |
|
||||
| `enable_graph` | bool | None | Include graph relations |
|
||||
|
||||
**Returns:** `dict` -- `{"results": [...]}`
|
||||
|
||||
#### update(memory_id, text=None, metadata=None, timestamp=None)
|
||||
|
||||
Update a memory's content, metadata, or timestamp. At least one parameter required. Cannot update immutable memories.
|
||||
|
||||
```python
|
||||
client.update("ea925981-...", text="Updated: vegan since 2024")
|
||||
client.update("ea925981-...", metadata={"verified": True})
|
||||
```
|
||||
|
||||
**Returns:** `dict` -- updated memory
|
||||
|
||||
#### delete(memory_id)
|
||||
|
||||
Permanently delete a single memory.
|
||||
|
||||
```python
|
||||
client.delete("ea925981-...")
|
||||
```
|
||||
|
||||
#### delete_all(**kwargs)
|
||||
|
||||
Delete all memories matching filters. Irreversible.
|
||||
|
||||
```python
|
||||
client.delete_all(user_id="alice")
|
||||
```
|
||||
|
||||
#### history(memory_id)
|
||||
|
||||
Get the change history of a memory.
|
||||
|
||||
```python
|
||||
history = client.history("ea925981-...")
|
||||
# Returns: [{previous_value, new_value, action, timestamps}]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Batch Methods
|
||||
|
||||
#### batch_update(memories)
|
||||
|
||||
Update up to 1000 memories in a single request.
|
||||
|
||||
```python
|
||||
client.batch_update([
|
||||
{"memory_id": "uuid-1", "text": "Updated text"},
|
||||
{"memory_id": "uuid-2", "text": "Another update", "metadata": {"verified": True}},
|
||||
])
|
||||
```
|
||||
|
||||
#### batch_delete(memories)
|
||||
|
||||
Delete up to 1000 memories in a single request.
|
||||
|
||||
```python
|
||||
client.batch_delete([
|
||||
{"memory_id": "uuid-1"},
|
||||
{"memory_id": "uuid-2"},
|
||||
])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### User/Entity Management
|
||||
|
||||
#### users()
|
||||
|
||||
List all users, agents, and sessions that have memories.
|
||||
|
||||
```python
|
||||
users = client.users()
|
||||
# Returns: {"results": [{"type": "user", "name": "alice"}, ...]}
|
||||
```
|
||||
|
||||
#### delete_users(user_id=None, agent_id=None, app_id=None, run_id=None)
|
||||
|
||||
Delete a specific entity and all its memories.
|
||||
|
||||
```python
|
||||
client.delete_users(user_id="alice")
|
||||
```
|
||||
|
||||
#### reset()
|
||||
|
||||
Delete ALL users, agents, sessions, and memories. Complete data reset.
|
||||
|
||||
```python
|
||||
client.reset()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Export & Summary
|
||||
|
||||
#### create_memory_export(schema, **kwargs)
|
||||
|
||||
Create a structured export of memories.
|
||||
|
||||
```python
|
||||
import json
|
||||
|
||||
schema = json.dumps({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"preferences": {"type": "array", "items": {"type": "string"}},
|
||||
}
|
||||
})
|
||||
export = client.create_memory_export(schema=schema, user_id="alice")
|
||||
```
|
||||
|
||||
#### get_memory_export(**kwargs)
|
||||
|
||||
Retrieve a previously created export.
|
||||
|
||||
```python
|
||||
result = client.get_memory_export(memory_export_id=export["id"])
|
||||
```
|
||||
|
||||
#### get_summary(filters=None)
|
||||
|
||||
Get a summary of memories.
|
||||
|
||||
```python
|
||||
summary = client.get_summary(filters={"user_id": "alice"})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Feedback
|
||||
|
||||
#### feedback(memory_id, feedback=None, feedback_reason=None)
|
||||
|
||||
Provide quality feedback on a memory.
|
||||
|
||||
```python
|
||||
client.feedback(
|
||||
memory_id="mem-123",
|
||||
feedback="POSITIVE", # POSITIVE | NEGATIVE | VERY_NEGATIVE | None (clear)
|
||||
feedback_reason="Accurately captured preference"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Webhooks
|
||||
|
||||
```python
|
||||
# List
|
||||
webhooks = client.get_webhooks(project_id="proj_123")
|
||||
|
||||
# Create
|
||||
webhook = client.create_webhook(
|
||||
url="https://your-app.com/webhook",
|
||||
name="Memory Logger",
|
||||
project_id="proj_123",
|
||||
event_types=["memory_add", "memory_update"]
|
||||
)
|
||||
|
||||
# Update
|
||||
client.update_webhook(webhook_id=123, name="Updated", url="https://new-url.com")
|
||||
|
||||
# Delete
|
||||
client.delete_webhook(webhook_id=123)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Project Management
|
||||
|
||||
Access via `client.project.*`:
|
||||
|
||||
```python
|
||||
# Get project config
|
||||
config = client.project.get(fields=["custom_categories", "custom_instructions"])
|
||||
|
||||
# Update project settings
|
||||
client.project.update(
|
||||
custom_instructions="Extract dietary preferences and health info",
|
||||
custom_categories=[{"health": "Medical and dietary info"}],
|
||||
enable_graph=True,
|
||||
multilingual=True,
|
||||
)
|
||||
|
||||
# Create/delete project (requires org_id)
|
||||
client.project.create(name="My Project", description="...")
|
||||
client.project.delete()
|
||||
|
||||
# Member management
|
||||
members = client.project.get_members()
|
||||
client.project.add_member(email="user@example.com", role="READER") # READER or OWNER
|
||||
client.project.update_member(email="user@example.com", role="OWNER")
|
||||
client.project.remove_member(email="user@example.com")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Source / Self-Hosted
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
### Memory Class
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory() # Uses default config (OpenAI embedder + in-memory vector store)
|
||||
```
|
||||
|
||||
**Import:** `from mem0 import Memory` (NOT `MemoryClient` -- that is the Platform client)
|
||||
|
||||
### Configuration
|
||||
|
||||
```python
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai", # openai, groq, azure, ollama, lmstudio, google, anthropic, mistral
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"api_key": "sk-xxx",
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai", # openai, ollama, azure, lmstudio, google, huggingface
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": "sk-xxx",
|
||||
}
|
||||
},
|
||||
"vector_store": {
|
||||
"provider": "qdrant", # faiss, qdrant, pgvector, redis, supabase, azure_ai_search, memory
|
||||
"config": {
|
||||
"collection_name": "my_memories",
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
"graph_store": { # Optional
|
||||
"provider": "neo4j",
|
||||
"config": {
|
||||
"url": "neo4j://localhost:7687",
|
||||
"username": "neo4j",
|
||||
"password": "password",
|
||||
}
|
||||
},
|
||||
"history_db_path": "history.db", # SQLite path for change history
|
||||
"custom_fact_extraction_prompt": "...", # Custom LLM prompt for extraction
|
||||
"custom_update_memory_prompt": "...", # Custom LLM prompt for updates
|
||||
"enable_graph": False, # Enable graph memory
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
### Context Manager
|
||||
|
||||
```python
|
||||
with Memory(config) as m:
|
||||
m.add("I prefer dark mode", user_id="alice")
|
||||
results = m.search("preferences", user_id="alice")
|
||||
# SQLite connections released automatically
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
All methods mirror the Platform client but run locally:
|
||||
|
||||
#### add(messages, *, user_id, agent_id, run_id, metadata, infer=True)
|
||||
|
||||
```python
|
||||
m.add("I'm a vegetarian", user_id="alice")
|
||||
m.add([
|
||||
{"role": "user", "content": "I like hiking"},
|
||||
{"role": "assistant", "content": "Great outdoor activity!"}
|
||||
], user_id="alice")
|
||||
```
|
||||
|
||||
At least one of `user_id`, `agent_id`, `run_id` required.
|
||||
|
||||
**Returns:** `{"results": [...], "relations": [...]}`
|
||||
|
||||
#### search(query, *, user_id, agent_id, run_id, limit=100, filters=None, threshold=None, rerank=True)
|
||||
|
||||
```python
|
||||
results = m.search("dietary preferences", user_id="alice", limit=5)
|
||||
```
|
||||
|
||||
Supports filter operators: `eq`, `ne`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`.
|
||||
|
||||
#### get(memory_id) / get_all(**kwargs) / update(memory_id, data, metadata=None) / delete(memory_id) / delete_all(**kwargs) / history(memory_id)
|
||||
|
||||
Same interface as Platform client.
|
||||
|
||||
#### reset()
|
||||
|
||||
Clear the entire vector store collection and history database. Recreates the vector store.
|
||||
|
||||
```python
|
||||
m.reset()
|
||||
```
|
||||
|
||||
#### close()
|
||||
|
||||
Release SQLite connections. Called automatically when using context manager.
|
||||
|
||||
### AsyncMemory
|
||||
|
||||
```python
|
||||
from mem0 import AsyncMemory
|
||||
|
||||
m = AsyncMemory(config)
|
||||
await m.add("text", user_id="alice")
|
||||
results = await m.search("query", user_id="alice")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Differences: Platform vs OSS
|
||||
|
||||
| Aspect | Platform (`MemoryClient`) | OSS (`Memory`) |
|
||||
|--------|--------------------------|----------------|
|
||||
| **Import** | `from mem0 import MemoryClient` | `from mem0 import Memory` |
|
||||
| **Auth** | API key required (`MEM0_API_KEY`) | No API key -- config-based |
|
||||
| **Execution** | API calls to `api.mem0.ai` | Local execution |
|
||||
| **Infrastructure** | Fully managed | Self-managed vector DB, embedder, LLM |
|
||||
| **Batch ops** | `batch_update`, `batch_delete` | Not available |
|
||||
| **Webhooks** | Full CRUD | Not available |
|
||||
| **Export** | `create_memory_export`, `get_memory_export` | Not available |
|
||||
| **Feedback** | `feedback()` | Not available |
|
||||
| **Project mgmt** | `client.project.*` | Not available |
|
||||
| **User listing** | `users()`, `delete_users()` | Not available |
|
||||
| **Custom prompts** | Via project settings | Direct config |
|
||||
| **Graph store** | Platform-managed | Self-managed (Neo4j) |
|
||||
| **History** | Platform-managed | SQLite (configurable) |
|
||||
| **Async** | `AsyncMemoryClient` | `AsyncMemory` |
|
||||
@@ -116,73 +116,24 @@ result = crew.kickoff()
|
||||
|
||||
## Vercel AI SDK
|
||||
|
||||
Source: [docs.mem0.ai/integrations/vercel-ai-sdk](https://docs.mem0.ai/integrations/vercel-ai-sdk)
|
||||
> **Dedicated skill available.** For comprehensive Vercel AI SDK documentation, see the [mem0-vercel-ai-sdk skill](../mem0-vercel-ai-sdk/SKILL.md) ([GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk)).
|
||||
|
||||
Install: `npm install @mem0/vercel-ai-provider`
|
||||
|
||||
### Basic Text Generation with Memory
|
||||
Quick example (wrapped model with automatic memory):
|
||||
|
||||
```typescript
|
||||
import { generateText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0({
|
||||
provider: "openai",
|
||||
mem0ApiKey: "m0-xxx",
|
||||
apiKey: "openai-api-key",
|
||||
});
|
||||
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "borat" }),
|
||||
prompt: "Suggest me a good car to buy!",
|
||||
});
|
||||
```
|
||||
|
||||
### Streaming with Memory
|
||||
|
||||
```typescript
|
||||
import { streamText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
|
||||
const mem0 = createMem0();
|
||||
|
||||
const { textStream } = streamText({
|
||||
const { text } = await generateText({
|
||||
model: mem0("gpt-4-turbo", { user_id: "borat" }),
|
||||
prompt: "Suggest me a good car to buy!",
|
||||
});
|
||||
|
||||
for await (const textPart of textStream) {
|
||||
process.stdout.write(textPart);
|
||||
}
|
||||
```
|
||||
|
||||
### Using Memory Utilities Standalone
|
||||
|
||||
```typescript
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { generateText } from "ai";
|
||||
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
|
||||
|
||||
// Retrieve memories and inject into any provider
|
||||
const prompt = "Suggest me a good car to buy.";
|
||||
const memories = await retrieveMemories(prompt, { user_id: "borat", mem0ApiKey: "m0-xxx" });
|
||||
|
||||
const { text } = await generateText({
|
||||
model: openai("gpt-4-turbo"),
|
||||
prompt: prompt,
|
||||
system: memories,
|
||||
});
|
||||
|
||||
// Store new memories
|
||||
await addMemories(
|
||||
[{ role: "user", content: [{ type: "text", text: "I love red cars." }] }],
|
||||
{ user_id: "borat", mem0ApiKey: "m0-xxx" }
|
||||
);
|
||||
```
|
||||
|
||||
### Supported Providers
|
||||
|
||||
`openai`, `anthropic`, `google`, `groq`
|
||||
Supported providers: `openai`, `anthropic`, `google`, `groq`, `cohere`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Complete SDK reference for Python and TypeScript. All methods use `MemoryClient` (Platform API).
|
||||
|
||||
> **For language-specific deep references (including OSS):** See [client/python.md](../client/python.md) and [client/node.md](../client/node.md). For Python vs TypeScript differences: [client/differences.md](../client/differences.md).
|
||||
|
||||
## Initialization
|
||||
|
||||
**Python:**
|
||||
|
||||
Reference in New Issue
Block a user