fix: update skills and docs (#4868)

This commit is contained in:
Kartik
2026-04-18 11:42:37 +05:30
committed by GitHub
parent c1c5bd62f6
commit 93da5ef8f7
23 changed files with 461 additions and 662 deletions
+10 -11
View File
@@ -12,7 +12,7 @@ description: >
license: Apache-2.0
metadata:
author: mem0ai
version: "1.0.0"
version: "1.1.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
@@ -47,16 +47,16 @@ import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0();
const { text } = await generateText({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { 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
1. The prompt is sent to Mem0 search (`POST /v3/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)
3. The underlying LLM (e.g., OpenAI gpt-5-mini) generates a response using the enriched prompt
4. The conversation is stored back to Mem0 (`POST /v3/memories/add/`) as a fire-and-forget async call (no await)
## Pattern 2: Standalone Utilities
@@ -77,7 +77,7 @@ const memories = await retrieveMemories(prompt, {
// Generate using any provider with injected memories
const { text } = await generateText({
model: openai("gpt-4-turbo"),
model: openai("gpt-5-mini"),
prompt,
system: memories,
});
@@ -102,7 +102,7 @@ import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0();
const result = streamText({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "What should I cook for dinner?",
});
@@ -128,7 +128,7 @@ 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" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "Hello!",
});
```
@@ -139,7 +139,7 @@ const { text } = await generateText({
```
User prompt
--> searchInternalMemories (POST /v2/memories/search/)
--> searchInternalMemories (POST /v3/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)
@@ -161,7 +161,7 @@ User controls each step:
| 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 |
| `getMemories` | Raw memory **array** | Processing memories programmatically |
| `searchMemories` | Full search **response** (results + relations) | Need relations, scores, metadata |
| `addMemories` | API response | Storing new messages to Mem0 |
@@ -171,7 +171,6 @@ All four accept `LanguageModelV2Prompt | string` as the first argument and optio
- **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.
@@ -79,8 +79,7 @@ async function retrieveMemories(
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
4. 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.
@@ -91,17 +90,13 @@ System Message: These are the memories I have stored. Give more weightage to the
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).
Retrieves memories and returns the **raw memory array**.
```typescript
import { getMemories } from "@mem0/vercel-ai-provider";
@@ -111,14 +106,6 @@ const memories = await getMemories("What are my preferences?", {
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:**
@@ -140,10 +127,9 @@ async function getMemories(
**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`)
3. Returns `memories.results` (the array of memory objects)
**Returns:** Memory object array, or full response object when graph is enabled.
**Returns:** Memory object array.
---
@@ -184,7 +170,7 @@ async function searchMemories(
**Returns:** The complete API response object. On error, returns `[]`.
**Note:** Unlike `getMemories`, this always returns the full response regardless of `enable_graph` setting.
**Note:** Unlike `getMemories`, this always returns the full response.
---
@@ -193,8 +179,8 @@ async function searchMemories(
| 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 |
| `getMemories` | Memory **array** | Processing memories programmatically (filtering, transforming, counting) |
| `searchMemories` | Full API **response** (results + relations) | Need relations, similarity scores, or complete metadata |
| `addMemories` | API response | Storing new conversation messages as memories |
## Internal: `searchInternalMemories(query, config?, top_k?)`
@@ -210,15 +196,13 @@ async function searchInternalMemories(
```
**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`)
1. Builds a `filters` object from entity identifiers (`user_id`, `app_id`, `agent_id`, `run_id`)
2. Resolves entity identifiers
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
- `filters`: the filter object with entity identifiers
- `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`
@@ -264,10 +248,6 @@ All fields are optional. Used across all utility functions.
| `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 |
@@ -277,8 +257,4 @@ All fields are optional. Used across all utility functions.
| `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 |
@@ -9,8 +9,8 @@ Factory function that creates a `Mem0Provider` instance. This is the primary ent
```typescript
import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0(); // defaults: provider "openai"
const mem0 = createMem0({ provider: "anthropic" }); // use Anthropic as LLM backend
const mem0 = createMem0(); // defaults: provider "openai"
const mem0 = createMem0({ provider: "anthropic" }); // use Anthropic as LLM backend
```
**Signature:**
@@ -39,7 +39,7 @@ interface Mem0Provider extends ProviderV2 {
}
```
- **Direct call** (`mem0("gpt-4-turbo", {...})`): creates a generic language model (neither chat nor completion mode forced).
- **Direct call** (`mem0("gpt-5-mini", {...})`): 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).
@@ -73,7 +73,7 @@ interface Mem0ProviderSettings {
| `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 }` |
| `mem0Config` | Default Mem0 settings for all calls | `{ user_id: "alice" }` |
| `config` | Provider-specific SDK settings | `{ organization: "org-xxx" }` for OpenAI |
| `baseURL` | Override LLM provider base URL | `"https://my-proxy.example.com"` |
@@ -85,7 +85,7 @@ A pre-configured instance using default settings (OpenAI provider, no API keys s
import { mem0 } from "@mem0/vercel-ai-provider";
const { text } = await generateText({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "Hello",
});
```
@@ -102,10 +102,6 @@ interface Mem0ConfigSettings {
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
@@ -113,13 +109,9 @@ interface Mem0ConfigSettings {
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)
threshold?: number; // Minimum similarity score for retrieval (default: 0.1)
rerank?: boolean; // Enable re-ranking of search results (default: false)
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
}
```
@@ -138,9 +130,9 @@ This means a `Mem0ChatConfig` has all fields from both `Mem0ConfigSettings` and
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
mem0("gpt-5-mini", { user_id: "alice" })
// ^^^^^^^^^^^^^^^^^^
// This object is Mem0ChatSettings
```
## `LLMProviderSettings` Type
@@ -188,8 +180,8 @@ An alternative exported class that creates models directly without the callable-
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");
const chatModel = mem0.chat("gpt-5-mini", { user_id: "alice" });
const completionModel = mem0.completion("gpt-5-mini");
```
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.
@@ -210,7 +202,7 @@ class Mem0GenericLanguageModel implements LanguageModelV2 {
readonly supportedUrls: Record<string, RegExp[]> = { '*': [/.*/] };
provider: string; // e.g., "openai"
modelId: string; // e.g., "gpt-4-turbo"
modelId: string; // e.g., "gpt-5-mini"
settings: Mem0ChatSettings;
config: Mem0ChatConfig;
@@ -230,10 +222,12 @@ Both `doGenerate` and `doStream` follow the same internal flow:
4. Delegate to the underlying model's `doGenerate` or `doStream`
5. Return the result
**Note:** Entity identifier fields use snake_case (`user_id`, `app_id`, `agent_id`, `run_id`) to match the Mem0 API.
## 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"`).
Any non-null string. The model ID is passed through to the underlying provider (e.g., `"gpt-5-mini"`, `"gemini-pro"`).
@@ -13,7 +13,7 @@ import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0();
const { text } = await generateText({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "Recommend a restaurant based on my preferences",
});
@@ -33,7 +33,7 @@ import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0();
const result = streamText({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "What should I cook for dinner tonight?",
});
@@ -53,17 +53,17 @@ import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
const userId = "alice";
const user_id = "alice";
const prompt = "Suggest a weekend trip";
// Step 1: Retrieve memories as a formatted system prompt
const memories = await retrieveMemories(prompt, {
user_id: userId,
user_id: user_id,
});
// Step 2: Generate with the memories injected as system context
const { text } = await generateText({
model: openai("gpt-4-turbo"),
model: openai("gpt-5-mini"),
prompt,
system: memories,
});
@@ -76,7 +76,7 @@ await addMemories(
{ role: "user", content: [{ type: "text", text: prompt }] },
{ role: "assistant", content: [{ type: "text", text }] },
],
{ user_id: userId }
{ user_id: user_id }
);
```
@@ -121,7 +121,7 @@ import { z } from "zod";
const mem0 = createMem0();
const { object } = await generateObject({
model: mem0("gpt-4-turbo", { user_id: "alice" }),
model: mem0("gpt-5-mini", { user_id: "alice" }),
prompt: "Suggest a meal plan for today",
schema: z.object({
breakfast: z.string(),
@@ -138,53 +138,7 @@ console.log(object);
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
## 6. Multi-Provider Setup
Configure different LLM providers with the wrapped model.
@@ -194,7 +148,7 @@ Configure different LLM providers with the wrapped model.
import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0(); // defaults to "openai"
const model = mem0("gpt-4-turbo", { user_id: "alice" });
const model = mem0("gpt-5-mini", { user_id: "alice" });
```
### Anthropic
@@ -235,7 +189,7 @@ const mem0 = createMem0({
});
```
## 8. Next.js API Route Integration
## 7. Next.js API Route Integration
A POST handler that uses the wrapped model in a Next.js App Router API route.
@@ -247,12 +201,12 @@ import { createMem0 } from "@mem0/vercel-ai-provider";
const mem0 = createMem0();
export async function POST(req: Request) {
const { messages, userId } = await req.json();
const { messages, user_id } = await req.json();
const lastMessage = messages[messages.length - 1];
const result = streamText({
model: mem0("gpt-4-turbo", { user_id: userId }),
model: mem0("gpt-5-mini", { user_id }),
prompt: lastMessage.content,
});
@@ -269,17 +223,17 @@ 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 { messages, user_id } = await req.json();
const lastMessage = messages[messages.length - 1];
// Retrieve relevant memories
const memories = await retrieveMemories(lastMessage.content, {
user_id: userId,
user_id,
});
// Stream the response
const result = streamText({
model: openai("gpt-4-turbo"),
model: openai("gpt-5-mini"),
prompt: lastMessage.content,
system: memories,
});
@@ -291,7 +245,7 @@ export async function POST(req: Request) {
{ role: "user", content: [{ type: "text", text: lastMessage.content }] },
{ role: "assistant", content: [{ type: "text", text }] },
],
{ user_id: userId }
{ user_id }
);
});
@@ -299,7 +253,7 @@ export async function POST(req: Request) {
}
```
## 9. How Memory Processing Works Internally
## 8. How Memory Processing Works Internally
### Wrapped model flow (doGenerate / doStream)
@@ -308,10 +262,10 @@ export async function POST(req: Request) {
2. processMemories(messagesPrompts, mem0Config):
a. addMemories(messagesPrompts, mem0Config)
--> fire-and-forget: .then().catch(), NO await
--> POST /v1/memories/ with converted messages
--> POST /v3/memories/add/ with converted messages
b. await getMemories(messagesPrompts, mem0Config)
--> POST /v2/memories/search/ with flattened prompt
--> returns memory array (or {results, relations} if enable_graph)
--> POST /v3/memories/search/ with flattened prompt
--> returns memory array
c. Format memories into system message string
d. Prepend system message to messagesPrompts array
e. Return { memories, messagesPrompts }
@@ -337,7 +291,7 @@ The memories are injected as a system message at position 0 of the prompt array:
}
```
## 10. Custom Configuration
## 9. Custom Configuration
### Custom Mem0 API host
@@ -358,32 +312,15 @@ const memories = await retrieveMemories(prompt, {
});
```
### 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", {
const model = mem0("gpt-5-mini", {
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,
rerank: true, // enable re-ranking of results
});
```
@@ -409,14 +346,13 @@ Set defaults at the provider level that apply to every model created:
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
// These calls inherit user_id and top_k from mem0Config
const { text } = await generateText({
model: mem0("gpt-4-turbo"),
model: mem0("gpt-5-mini"),
prompt: "Hello",
});
```
@@ -425,7 +361,7 @@ Per-call settings (passed as the second argument to `mem0()`) are merged on top
```typescript
// Override user_id for this specific call
const model = mem0("gpt-4-turbo", { user_id: "bob" });
const model = mem0("gpt-5-mini", { user_id: "bob" });
```
The merge order is: `config.mem0Config` (provider defaults) < `settings` (per-call overrides).