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,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).
|
||||
Reference in New Issue
Block a user