mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-05-19 16:13:19 +00:00
Expose raw search results in `MemoryPromptData` so prompt templates can traverse, filter, and selectively include results based on metadata (e.g. score, source).
##### Usage example
```typescript
const promptTemplate = (data: MemoryPromptData) => {
const relevant = data.searchResults.filter(
(r) => (r.metadata?.score as number) > 0.7
)
return `${data.userMemories}\n${relevant.map(r => r.memory).join('\n')}`
}
```
450 lines
11 KiB
Text
450 lines
11 KiB
Text
---
|
|
title: "Mastra"
|
|
sidebarTitle: "Mastra"
|
|
description: "Add persistent memory to Mastra AI agents with Supermemory processors"
|
|
icon: "/images/mastra-icon.svg"
|
|
---
|
|
|
|
Integrate Supermemory with [Mastra](https://mastra.ai) to give your AI agents persistent memory. Use the `withSupermemory` wrapper for zero-config setup or processors for fine-grained control.
|
|
|
|
<Card title="@supermemory/tools on npm" icon="npm" href="https://www.npmjs.com/package/@supermemory/tools">
|
|
Check out the NPM page for more details
|
|
</Card>
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @supermemory/tools @mastra/core
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
Wrap your agent config with `withSupermemory` to add memory capabilities:
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { withSupermemory } from "@supermemory/tools/mastra"
|
|
import { openai } from "@ai-sdk/openai"
|
|
|
|
// Create agent with memory-enhanced config
|
|
const agent = new Agent(withSupermemory(
|
|
{
|
|
id: "my-assistant",
|
|
name: "My Assistant",
|
|
model: openai("gpt-4o"),
|
|
instructions: "You are a helpful assistant.",
|
|
},
|
|
"user-123", // containerTag - scopes memories to this user
|
|
{
|
|
mode: "full",
|
|
addMemory: "always",
|
|
threadId: "conv-456",
|
|
}
|
|
))
|
|
|
|
const response = await agent.generate("What do you know about me?")
|
|
```
|
|
|
|
<Note>
|
|
**Memory saving is disabled by default.** The wrapper only retrieves existing memories. To automatically save conversations:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), ... },
|
|
"user-123",
|
|
{
|
|
addMemory: "always",
|
|
threadId: "conv-456" // Required for conversation grouping
|
|
}
|
|
))
|
|
```
|
|
</Note>
|
|
|
|
---
|
|
|
|
## How It Works
|
|
|
|
The Mastra integration uses Mastra's native [Processor](https://mastra.ai/docs/agents/processors) interface:
|
|
|
|
1. **Input Processor** - Fetches relevant memories from Supermemory and injects them into the system prompt before the LLM call
|
|
2. **Output Processor** - Optionally saves the conversation to Supermemory after generation completes
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant User
|
|
participant Agent
|
|
participant InputProcessor
|
|
participant LLM
|
|
participant OutputProcessor
|
|
participant Supermemory
|
|
|
|
User->>Agent: Send message
|
|
Agent->>InputProcessor: Process input
|
|
InputProcessor->>Supermemory: Fetch memories
|
|
Supermemory-->>InputProcessor: Return memories
|
|
InputProcessor->>Agent: Inject into system prompt
|
|
Agent->>LLM: Generate response
|
|
LLM-->>Agent: Return response
|
|
Agent->>OutputProcessor: Process output
|
|
OutputProcessor->>Supermemory: Save conversation (if enabled)
|
|
Agent-->>User: Return response
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `apiKey` | `string` | `SUPERMEMORY_API_KEY` env | Your Supermemory API key |
|
|
| `baseUrl` | `string` | `https://api.supermemory.ai` | Custom API endpoint |
|
|
| `mode` | `"profile" \| "query" \| "full"` | `"profile"` | Memory search mode |
|
|
| `addMemory` | `"always" \| "never"` | `"never"` | Auto-save conversations |
|
|
| `threadId` | `string` | - | Conversation ID for grouping messages |
|
|
| `verbose` | `boolean` | `false` | Enable debug logging |
|
|
| `promptTemplate` | `function` | - | Custom memory formatting |
|
|
|
|
---
|
|
|
|
## Memory Search Modes
|
|
|
|
**Profile Mode (Default)** - Retrieves the user's complete profile without query-based filtering:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(config, "user-123", { mode: "profile" }))
|
|
```
|
|
|
|
**Query Mode** - Searches memories based on the user's message:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(config, "user-123", { mode: "query" }))
|
|
```
|
|
|
|
**Full Mode** - Combines profile AND query-based search for maximum context:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(config, "user-123", { mode: "full" }))
|
|
|
|
### Mode Comparison
|
|
|
|
| Mode | Description | Use Case |
|
|
|------|-------------|----------|
|
|
| `profile` | Static + dynamic user facts | General personalization |
|
|
| `query` | Semantic search on user message | Specific Q&A |
|
|
| `full` | Both profile and search | Chatbots, assistants |
|
|
|
|
---
|
|
|
|
## Saving Conversations
|
|
|
|
Enable automatic conversation saving with `addMemory: "always"`. A `threadId` is required to group messages:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
|
|
"user-123",
|
|
{
|
|
addMemory: "always",
|
|
threadId: "conv-456",
|
|
}
|
|
))
|
|
|
|
// All messages in this conversation are saved
|
|
await agent.generate("I prefer TypeScript over JavaScript")
|
|
await agent.generate("My favorite framework is Next.js")
|
|
```
|
|
|
|
<Warning>
|
|
Without a `threadId`, the output processor will log a warning and skip saving. Always provide a `threadId` when using `addMemory: "always"`.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## Custom Prompt Templates
|
|
|
|
Customize how memories are formatted and injected. The template receives `userMemories`, `generalSearchMemories`, and `searchResults` (raw array for filtering by metadata):
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { withSupermemory } from "@supermemory/tools/mastra"
|
|
import type { MemoryPromptData } from "@supermemory/tools/mastra"
|
|
|
|
const claudePrompt = (data: MemoryPromptData) => `
|
|
<context>
|
|
<user_profile>
|
|
${data.userMemories}
|
|
</user_profile>
|
|
<relevant_memories>
|
|
${data.generalSearchMemories}
|
|
</relevant_memories>
|
|
</context>
|
|
`.trim()
|
|
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
|
|
"user-123",
|
|
{
|
|
mode: "full",
|
|
promptTemplate: claudePrompt,
|
|
}
|
|
))
|
|
```
|
|
|
|
---
|
|
|
|
## Direct Processor Usage
|
|
|
|
For advanced use cases, use processors directly instead of the wrapper:
|
|
|
|
### Input Processor Only
|
|
|
|
Inject memories without saving conversations:
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { createSupermemoryProcessor } from "@supermemory/tools/mastra"
|
|
import { openai } from "@ai-sdk/openai"
|
|
|
|
const agent = new Agent({
|
|
id: "my-assistant",
|
|
name: "My Assistant",
|
|
model: openai("gpt-4o"),
|
|
inputProcessors: [
|
|
createSupermemoryProcessor("user-123", {
|
|
mode: "full",
|
|
verbose: true,
|
|
}),
|
|
],
|
|
})
|
|
```
|
|
|
|
### Output Processor Only
|
|
|
|
Save conversations without memory injection:
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { createSupermemoryOutputProcessor } from "@supermemory/tools/mastra"
|
|
import { openai } from "@ai-sdk/openai"
|
|
|
|
const agent = new Agent({
|
|
id: "my-assistant",
|
|
name: "My Assistant",
|
|
model: openai("gpt-4o"),
|
|
outputProcessors: [
|
|
createSupermemoryOutputProcessor("user-123", {
|
|
addMemory: "always",
|
|
threadId: "conv-456",
|
|
}),
|
|
],
|
|
})
|
|
```
|
|
|
|
### Both Processors
|
|
|
|
Use the factory function for shared configuration:
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { createSupermemoryProcessors } from "@supermemory/tools/mastra"
|
|
import { openai } from "@ai-sdk/openai"
|
|
|
|
const { input, output } = createSupermemoryProcessors("user-123", {
|
|
mode: "full",
|
|
addMemory: "always",
|
|
threadId: "conv-456",
|
|
verbose: true,
|
|
})
|
|
|
|
const agent = new Agent({
|
|
id: "my-assistant",
|
|
name: "My Assistant",
|
|
model: openai("gpt-4o"),
|
|
inputProcessors: [input],
|
|
outputProcessors: [output],
|
|
})
|
|
```
|
|
|
|
---
|
|
|
|
## Using RequestContext
|
|
|
|
Mastra's `RequestContext` can provide `threadId` dynamically:
|
|
|
|
```typescript
|
|
import { Agent } from "@mastra/core/agent"
|
|
import { RequestContext, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context"
|
|
import { withSupermemory } from "@supermemory/tools/mastra"
|
|
import { openai } from "@ai-sdk/openai"
|
|
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
|
|
"user-123",
|
|
{
|
|
mode: "full",
|
|
addMemory: "always",
|
|
// threadId not set - will use RequestContext
|
|
}
|
|
))
|
|
|
|
// Set threadId dynamically via RequestContext
|
|
const ctx = new RequestContext()
|
|
ctx.set(MASTRA_THREAD_ID_KEY, "dynamic-thread-id")
|
|
|
|
await agent.generate("Hello!", { requestContext: ctx })
|
|
```
|
|
|
|
---
|
|
|
|
## Verbose Logging
|
|
|
|
Enable detailed logging for debugging:
|
|
|
|
```typescript
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
|
|
"user-123",
|
|
{ verbose: true }
|
|
))
|
|
|
|
// Console output:
|
|
// [supermemory] Starting memory search { containerTag: "user-123", mode: "profile" }
|
|
// [supermemory] Found 5 memories
|
|
// [supermemory] Injected memories into system prompt { length: 1523 }
|
|
```
|
|
|
|
---
|
|
|
|
## Working with Existing Processors
|
|
|
|
The wrapper correctly merges with existing processors in the config:
|
|
|
|
```typescript
|
|
// Supermemory processors are merged correctly:
|
|
// - Input: [supermemory, myLogging] (supermemory runs first)
|
|
// - Output: [myAnalytics, supermemory] (supermemory runs last)
|
|
const agent = new Agent(withSupermemory(
|
|
{
|
|
id: "my-assistant",
|
|
model: openai("gpt-4o"),
|
|
inputProcessors: [myLoggingProcessor],
|
|
outputProcessors: [myAnalyticsProcessor],
|
|
},
|
|
"user-123"
|
|
))
|
|
```
|
|
|
|
---
|
|
|
|
## API Reference
|
|
|
|
### `withSupermemory`
|
|
|
|
Enhances a Mastra agent config with memory capabilities.
|
|
|
|
```typescript
|
|
function withSupermemory<T extends AgentConfig>(
|
|
config: T,
|
|
containerTag: string,
|
|
options?: SupermemoryMastraOptions
|
|
): T
|
|
```
|
|
|
|
**Parameters:**
|
|
- `config` - The Mastra agent configuration object
|
|
- `containerTag` - User/container ID for scoping memories
|
|
- `options` - Configuration options
|
|
|
|
**Returns:** Enhanced config with Supermemory processors injected
|
|
|
|
### `createSupermemoryProcessor`
|
|
|
|
Creates an input processor for memory injection.
|
|
|
|
```typescript
|
|
function createSupermemoryProcessor(
|
|
containerTag: string,
|
|
options?: SupermemoryMastraOptions
|
|
): SupermemoryInputProcessor
|
|
```
|
|
|
|
### `createSupermemoryOutputProcessor`
|
|
|
|
Creates an output processor for conversation saving.
|
|
|
|
```typescript
|
|
function createSupermemoryOutputProcessor(
|
|
containerTag: string,
|
|
options?: SupermemoryMastraOptions
|
|
): SupermemoryOutputProcessor
|
|
```
|
|
|
|
### `createSupermemoryProcessors`
|
|
|
|
Creates both processors with shared configuration.
|
|
|
|
```typescript
|
|
function createSupermemoryProcessors(
|
|
containerTag: string,
|
|
options?: SupermemoryMastraOptions
|
|
): {
|
|
input: SupermemoryInputProcessor
|
|
output: SupermemoryOutputProcessor
|
|
}
|
|
```
|
|
|
|
### `SupermemoryMastraOptions`
|
|
|
|
```typescript
|
|
interface SupermemoryMastraOptions {
|
|
apiKey?: string
|
|
baseUrl?: string
|
|
mode?: "profile" | "query" | "full"
|
|
addMemory?: "always" | "never"
|
|
threadId?: string
|
|
verbose?: boolean
|
|
promptTemplate?: (data: MemoryPromptData) => string
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
```bash
|
|
SUPERMEMORY_API_KEY=your_supermemory_key
|
|
```
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
Processors gracefully handle errors without breaking the agent:
|
|
|
|
- **API errors** - Logged and skipped; agent continues without memories
|
|
- **Missing API key** - Throws immediately with helpful error message
|
|
- **Missing threadId** - Warns in console; skips saving
|
|
|
|
```typescript
|
|
// Missing API key throws immediately
|
|
const agent = new Agent(withSupermemory(
|
|
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
|
|
"user-123",
|
|
{ apiKey: undefined } // Will check SUPERMEMORY_API_KEY env
|
|
))
|
|
// Error: SUPERMEMORY_API_KEY is not set
|
|
```
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Vercel AI SDK" icon="triangle" href="/integrations/ai-sdk">
|
|
Use with Vercel AI SDK for streamlined development
|
|
</Card>
|
|
|
|
<Card title="User Profiles" icon="user" href="/user-profiles">
|
|
Learn about user profile management
|
|
</Card>
|
|
</CardGroup>
|