mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
docs: add SMFS provider guides for Daytona, E2B, Vercel AI SDK, and Cloudflare
- Add smfs/providers/daytona.mdx with full tutorial (mount + bash tool patterns) - Add smfs/providers/e2b.mdx with sandbox integration guide - Add smfs/providers/vercel.mdx with AI SDK tool-calling examples - Add smfs/providers/cloudflare.mdx with Workers + Containers guide - Update docs.json navigation with Providers group under SMFS - Update smfs/overview.mdx with provider cards
This commit is contained in:
parent
911f5abdc6
commit
d81d4d3bc1
6 changed files with 848 additions and 1 deletions
|
|
@ -152,7 +152,17 @@
|
|||
"smfs/overview",
|
||||
"smfs/install",
|
||||
"smfs/mount",
|
||||
"smfs/bash-tool"
|
||||
"smfs/bash-tool",
|
||||
{
|
||||
"group": "Providers",
|
||||
"icon": "cloud",
|
||||
"pages": [
|
||||
"smfs/providers/daytona",
|
||||
"smfs/providers/e2b",
|
||||
"smfs/providers/vercel",
|
||||
"smfs/providers/cloudflare"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -37,6 +37,25 @@ Pick by where your agent runs.
|
|||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Use SMFS with your sandbox provider
|
||||
|
||||
Already using a sandbox or agent platform? Jump straight to the guide for your provider.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Daytona" icon="server" href="/smfs/providers/daytona">
|
||||
Isolated Linux sandboxes with millisecond boot times. Mount SMFS inside or use the bash tool from your orchestrating code.
|
||||
</Card>
|
||||
<Card title="E2B" icon="cube" href="/smfs/providers/e2b">
|
||||
Firecracker microVMs for AI code execution. Install SMFS directly or use a custom template with it pre-installed.
|
||||
</Card>
|
||||
<Card title="Vercel AI SDK" icon="triangle" href="/smfs/providers/vercel">
|
||||
The most popular TypeScript agent framework. Add memory as a tool with one function call.
|
||||
</Card>
|
||||
<Card title="Cloudflare Workers" icon="cloud" href="/smfs/providers/cloudflare">
|
||||
Edge-first agents. Use the bash tool in Workers, or mount SMFS in Cloudflare Containers.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
|
|
|
|||
205
apps/docs/smfs/providers/cloudflare.mdx
Normal file
205
apps/docs/smfs/providers/cloudflare.mdx
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
---
|
||||
title: "Cloudflare"
|
||||
sidebarTitle: "Cloudflare"
|
||||
description: "Add persistent memory to Cloudflare Workers agents with SMFS."
|
||||
icon: "cloud"
|
||||
---
|
||||
|
||||
[Cloudflare Workers](https://workers.cloudflare.com) run at the edge in V8 isolates — no filesystem, no shell. That's exactly what `@supermemory/bash` is built for. It gives your Worker a virtual bash environment backed by Supermemory, so your agent can `ls`, `cat`, `grep`, and write to a persistent memory container without needing a real filesystem.
|
||||
|
||||
## Architecture
|
||||
|
||||
Cloudflare Workers can't mount SMFS (no FUSE, no disk). Instead, use `@supermemory/bash` as a tool for your agent. The bash tool runs entirely in-process — no child processes, no disk I/O, no native dependencies.
|
||||
|
||||
```
|
||||
Request → Worker → LLM → calls bash tool → @supermemory/bash → Supermemory API
|
||||
```
|
||||
|
||||
<Note>
|
||||
If you're using [Cloudflare Containers](https://developers.cloudflare.com/containers/) (full Linux containers at the edge), you can install the `smfs` binary directly. See [Alternative: Cloudflare Containers](#alternative-cloudflare-containers) below.
|
||||
</Note>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Supermemory](https://console.supermemory.ai) account and API key
|
||||
- A [Cloudflare](https://dash.cloudflare.com) account
|
||||
- Node.js 18+ and Wrangler CLI
|
||||
|
||||
## 1. Set up a Worker
|
||||
|
||||
```bash
|
||||
npm create cloudflare@latest -- my-memory-agent
|
||||
cd my-memory-agent
|
||||
npm install @supermemory/bash
|
||||
```
|
||||
|
||||
Add your Supermemory API key as a secret:
|
||||
|
||||
```bash
|
||||
npx wrangler secret put SUPERMEMORY_API_KEY
|
||||
```
|
||||
|
||||
## 2. Build an agent with memory
|
||||
|
||||
```typescript src/index.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
|
||||
export default {
|
||||
async fetch(request: Request, env: Env): Promise<Response> {
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: env.SUPERMEMORY_API_KEY,
|
||||
containerTag: "user_42",
|
||||
});
|
||||
|
||||
// Read the user's profile
|
||||
const profile = await bash.exec("cat /profile.md");
|
||||
|
||||
// Search memory semantically
|
||||
const results = await bash.exec("sgrep 'project deadlines'");
|
||||
|
||||
// Write new memory
|
||||
await bash.exec('echo "Met with client on April 27" >> /notes.md');
|
||||
|
||||
return new Response(JSON.stringify({
|
||||
profile: profile.stdout,
|
||||
search: results.stdout,
|
||||
}));
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## 3. Full agent with tool calling
|
||||
|
||||
Wire `@supermemory/bash` as a tool for an LLM. This example uses the OpenAI API, but any provider works:
|
||||
|
||||
```typescript src/index.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
|
||||
interface Env {
|
||||
SUPERMEMORY_API_KEY: string;
|
||||
OPENAI_API_KEY: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
async fetch(request: Request, env: Env): Promise<Response> {
|
||||
const { messages, userId } = await request.json() as {
|
||||
messages: any[];
|
||||
userId: string;
|
||||
};
|
||||
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: env.SUPERMEMORY_API_KEY,
|
||||
containerTag: `user_${userId}`,
|
||||
});
|
||||
|
||||
// Call the LLM with the bash tool
|
||||
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${env.OPENAI_API_KEY}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: "gpt-4o",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: `You have persistent memory via a bash tool.
|
||||
Use it to remember things about the user.
|
||||
Start by reading /profile.md for context.`,
|
||||
},
|
||||
...messages,
|
||||
],
|
||||
tools: [{
|
||||
type: "function",
|
||||
function: {
|
||||
name: "bash",
|
||||
description: toolDescription,
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: { cmd: { type: "string" } },
|
||||
required: ["cmd"],
|
||||
},
|
||||
},
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json() as any;
|
||||
|
||||
// Handle tool calls
|
||||
if (data.choices[0].message.tool_calls) {
|
||||
const toolCall = data.choices[0].message.tool_calls[0];
|
||||
const cmd = JSON.parse(toolCall.function.arguments).cmd;
|
||||
const result = await bash.exec(cmd);
|
||||
|
||||
// Send the result back to the LLM
|
||||
const followUp = await fetch("https://api.openai.com/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${env.OPENAI_API_KEY}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: "gpt-4o",
|
||||
messages: [
|
||||
...messages,
|
||||
data.choices[0].message,
|
||||
{
|
||||
role: "tool",
|
||||
tool_call_id: toolCall.id,
|
||||
content: JSON.stringify(result),
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const followUpData = await followUp.json() as any;
|
||||
return new Response(followUpData.choices[0].message.content);
|
||||
}
|
||||
|
||||
return new Response(data.choices[0].message.content);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Alternative: Cloudflare Containers
|
||||
|
||||
[Cloudflare Containers](https://developers.cloudflare.com/containers/) give you full Linux environments at the edge. Unlike Workers, containers have a real filesystem and shell — so you can install and mount SMFS directly.
|
||||
|
||||
```dockerfile Dockerfile
|
||||
FROM node:20-slim
|
||||
|
||||
# Install SMFS
|
||||
RUN curl -fsSL https://smfs.ai/install | sh
|
||||
|
||||
# Your agent code
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
RUN npm install
|
||||
|
||||
CMD ["node", "agent.js"]
|
||||
```
|
||||
|
||||
Inside the container, mount SMFS as you would on any Linux machine:
|
||||
|
||||
```bash
|
||||
smfs login --key $SUPERMEMORY_API_KEY
|
||||
smfs mount agent_memory --ephemeral --path /memory
|
||||
```
|
||||
|
||||
Your agent can then use standard Unix commands to interact with memory.
|
||||
|
||||
## Tips
|
||||
|
||||
- **Workers have a 30-second CPU time limit.** Keep tool call chains short. If your agent needs many steps, consider using Durable Objects for longer-running workflows.
|
||||
- **One container tag per user.** Use the user's ID as the container tag for isolated memory per user.
|
||||
- **`sgrep` for semantic search.** Inside the bash tool, `sgrep "query"` searches by meaning. Regular `grep` does literal matching.
|
||||
- **Cache-friendly.** `@supermemory/bash` warms its path index on `createBash`. For Workers that handle many requests, consider caching the instance in a Durable Object.
|
||||
|
||||
## Resources
|
||||
|
||||
- [Cloudflare Workers docs](https://developers.cloudflare.com/workers/)
|
||||
- [Cloudflare Containers docs](https://developers.cloudflare.com/containers/)
|
||||
- [SMFS Bash Tool reference](/smfs/bash-tool)
|
||||
- [Supermemory quickstart](/quickstart)
|
||||
227
apps/docs/smfs/providers/daytona.mdx
Normal file
227
apps/docs/smfs/providers/daytona.mdx
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
---
|
||||
title: "Daytona"
|
||||
sidebarTitle: "Daytona"
|
||||
description: "Give your Daytona sandboxes persistent memory with SMFS."
|
||||
icon: "server"
|
||||
---
|
||||
|
||||
[Daytona](https://www.daytona.io) gives AI agents isolated Linux sandboxes that boot in milliseconds. Pair it with SMFS and your agent gets both safe code execution **and** persistent memory it can `ls`, `cat`, and `grep`.
|
||||
|
||||
## Architecture
|
||||
|
||||
Daytona sandboxes run full Linux with shell access, filesystem, and network. There are two ways to wire SMFS in:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Mount inside the sandbox" icon="hard-drive">
|
||||
Install the `smfs` binary inside the sandbox and mount a container directly. Best when the sandbox has unrestricted outbound HTTPS.
|
||||
</Card>
|
||||
<Card title="Bash Tool in your agent code" icon="terminal">
|
||||
Use `@supermemory/bash` in the code that **orchestrates** the sandbox. The agent reads memory via the bash tool, then sends code to Daytona for execution. Best for most setups.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Note>
|
||||
Daytona sandboxes may restrict outbound TLS to certain hosts. If `smfs mount` fails with connection errors, use the Bash Tool pattern instead — it runs in your orchestrating code, not inside the sandbox.
|
||||
</Note>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Supermemory](https://console.supermemory.ai) account and API key
|
||||
- A [Daytona](https://app.daytona.io) account and API key
|
||||
- Node.js 18+ or Python 3.10+
|
||||
|
||||
## 1. Get your API keys
|
||||
|
||||
### Supermemory
|
||||
|
||||
1. Go to [console.supermemory.ai](https://console.supermemory.ai)
|
||||
2. Navigate to **Settings → API Keys**
|
||||
3. Create a new key and copy it
|
||||
|
||||
### Daytona
|
||||
|
||||
1. Go to [app.daytona.io](https://app.daytona.io)
|
||||
2. Sign up and verify your email
|
||||
3. Set your default region (US or EU)
|
||||
4. Navigate to **API Keys** in the sidebar
|
||||
5. Click **Create Key**, give it a name, and copy the key
|
||||
|
||||
<Warning>
|
||||
You can only view a Daytona API key once. Store it somewhere safe immediately after creation.
|
||||
</Warning>
|
||||
|
||||
## 2. Install the SDKs
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```bash
|
||||
npm install @supermemory/bash @daytonaio/sdk
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```bash
|
||||
pip install supermemory daytona-sdk
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 3. Build an agent with memory + code execution
|
||||
|
||||
The recommended pattern: your agent code uses `@supermemory/bash` for memory and the Daytona SDK for code execution. The LLM gets both as tools.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript agent.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
import { Daytona } from "@daytonaio/sdk";
|
||||
import { generateText, tool } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
async function main() {
|
||||
// 1. Set up memory (SMFS bash tool)
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!,
|
||||
containerTag: "agent_memory",
|
||||
});
|
||||
|
||||
// 2. Set up code execution (Daytona sandbox)
|
||||
const daytona = new Daytona({
|
||||
apiKey: process.env.DAYTONA_API_KEY!,
|
||||
apiUrl: "https://app.daytona.io/api",
|
||||
});
|
||||
const sandbox = await daytona.create();
|
||||
|
||||
// 3. Give the LLM both tools
|
||||
const result = await generateText({
|
||||
model: openai("gpt-4o"),
|
||||
tools: {
|
||||
memory: tool({
|
||||
description: toolDescription,
|
||||
parameters: z.object({ cmd: z.string() }),
|
||||
execute: async ({ cmd }) => bash.exec(cmd),
|
||||
}),
|
||||
execute_code: tool({
|
||||
description: "Run code in an isolated sandbox",
|
||||
parameters: z.object({ code: z.string() }),
|
||||
execute: async ({ code }) => {
|
||||
const res = await sandbox.process.exec(code);
|
||||
return res.result;
|
||||
},
|
||||
}),
|
||||
},
|
||||
prompt: "Check my memory for the user's preferred language, then write and run a hello world in that language.",
|
||||
});
|
||||
|
||||
console.log(result.text);
|
||||
|
||||
// 4. Clean up
|
||||
await daytona.delete(sandbox);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python agent.py
|
||||
import os
|
||||
from daytona_sdk import Daytona, DaytonaConfig
|
||||
|
||||
# 1. Set up code execution (Daytona sandbox)
|
||||
config = DaytonaConfig(
|
||||
api_key=os.environ["DAYTONA_API_KEY"],
|
||||
api_url="https://app.daytona.io/api",
|
||||
)
|
||||
daytona = Daytona(config)
|
||||
sandbox = daytona.create()
|
||||
|
||||
# 2. Install SMFS inside the sandbox
|
||||
sandbox.process.exec(
|
||||
"curl -fsSL https://smfs.ai/install | sh"
|
||||
)
|
||||
|
||||
# 3. Log in and mount
|
||||
sandbox.process.exec(
|
||||
f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
|
||||
)
|
||||
sandbox.process.exec(
|
||||
"~/.local/bin/smfs mount agent_memory --ephemeral"
|
||||
)
|
||||
|
||||
# 4. Your agent can now use the filesystem
|
||||
sandbox.process.exec('echo "User prefers Python" > agent_memory/memory.md')
|
||||
response = sandbox.process.exec("cat agent_memory/profile.md")
|
||||
print(response.result)
|
||||
|
||||
# 5. Semantic search
|
||||
response = sandbox.process.exec(
|
||||
"~/.local/bin/smfs grep 'preferred language'"
|
||||
)
|
||||
print(response.result)
|
||||
|
||||
# 6. Clean up
|
||||
sandbox.process.exec("~/.local/bin/smfs unmount agent_memory")
|
||||
daytona.delete(sandbox)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Alternative: Mount SMFS inside the sandbox
|
||||
|
||||
If your Daytona sandbox has unrestricted network access, you can install and mount SMFS directly inside it. This gives the agent a real filesystem it can navigate with standard Unix commands.
|
||||
|
||||
```python
|
||||
from daytona_sdk import Daytona, DaytonaConfig
|
||||
import os
|
||||
|
||||
config = DaytonaConfig(
|
||||
api_key=os.environ["DAYTONA_API_KEY"],
|
||||
api_url="https://app.daytona.io/api",
|
||||
)
|
||||
daytona = Daytona(config)
|
||||
sandbox = daytona.create()
|
||||
|
||||
# Install SMFS
|
||||
sandbox.process.exec("curl -fsSL https://smfs.ai/install | sh")
|
||||
|
||||
# Log in
|
||||
sandbox.process.exec(
|
||||
f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
|
||||
)
|
||||
|
||||
# Mount with ephemeral mode (recommended for sandboxes)
|
||||
sandbox.process.exec(
|
||||
"~/.local/bin/smfs mount agent_memory --ephemeral --path /memory"
|
||||
)
|
||||
|
||||
# Now the agent can use standard Unix commands
|
||||
sandbox.process.exec('echo "Meeting notes from standup" > /memory/notes.md')
|
||||
result = sandbox.process.exec("cat /memory/profile.md")
|
||||
print(result.result)
|
||||
|
||||
# Semantic grep works inside the mount
|
||||
result = sandbox.process.exec("cd /memory && grep 'standup'")
|
||||
print(result.result)
|
||||
|
||||
# Clean up
|
||||
sandbox.process.exec("~/.local/bin/smfs unmount agent_memory")
|
||||
daytona.delete(sandbox)
|
||||
```
|
||||
|
||||
<Note>
|
||||
Use `--ephemeral` when mounting inside sandboxes. It keeps the cache in memory only — nothing persists locally after unmount, but writes still push to Supermemory.
|
||||
</Note>
|
||||
|
||||
## Tips
|
||||
|
||||
- **Use `--ephemeral` for sandboxes.** Sandbox filesystems are temporary. Ephemeral mode avoids writing a local SQLite cache that will be thrown away.
|
||||
- **One container, many sandboxes.** Mount the same container tag from multiple sandboxes. Bidirectional sync keeps them in step.
|
||||
- **Give each agent a subdirectory.** If multiple agents share a container, scope them to `/agent_a/`, `/agent_b/`, etc. They can still read across the whole mount.
|
||||
- **Clean up sandboxes.** Call `daytona.delete(sandbox)` when done to avoid burning through free credits.
|
||||
|
||||
## Resources
|
||||
|
||||
- [Daytona docs](https://www.daytona.io/docs)
|
||||
- [Daytona SDK reference](https://www.daytona.io/docs/en/tools/api/)
|
||||
- [SMFS Mount reference](/smfs/mount)
|
||||
- [SMFS Bash Tool reference](/smfs/bash-tool)
|
||||
218
apps/docs/smfs/providers/e2b.mdx
Normal file
218
apps/docs/smfs/providers/e2b.mdx
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
---
|
||||
title: "E2B"
|
||||
sidebarTitle: "E2B"
|
||||
description: "Give your E2B sandboxes persistent memory with SMFS."
|
||||
icon: "cube"
|
||||
---
|
||||
|
||||
[E2B](https://e2b.dev) runs AI-generated code in secure Firecracker microVMs. Pair it with SMFS and your agent gets both safe code execution **and** persistent memory it can `ls`, `cat`, and `grep`.
|
||||
|
||||
## Architecture
|
||||
|
||||
E2B sandboxes are ephemeral Linux microVMs with full shell access. Two ways to wire SMFS in:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Mount inside the sandbox" icon="hard-drive">
|
||||
Install the `smfs` binary inside the sandbox and mount a container. The agent uses standard Unix commands to read and write memory.
|
||||
</Card>
|
||||
<Card title="Bash Tool in your agent code" icon="terminal">
|
||||
Use `@supermemory/bash` in the code that **orchestrates** the sandbox. Memory lives in your agent code; code execution lives in E2B.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Supermemory](https://console.supermemory.ai) account and API key
|
||||
- An [E2B](https://e2b.dev) account and API key
|
||||
- Node.js 18+ or Python 3.10+
|
||||
|
||||
## 1. Get your API keys
|
||||
|
||||
### Supermemory
|
||||
|
||||
1. Go to [console.supermemory.ai](https://console.supermemory.ai)
|
||||
2. Navigate to **Settings → API Keys**
|
||||
3. Create a new key and copy it
|
||||
|
||||
### E2B
|
||||
|
||||
1. Go to [e2b.dev](https://e2b.dev) and sign up
|
||||
2. Open the [Dashboard](https://e2b.dev/dashboard)
|
||||
3. Navigate to **API Keys**
|
||||
4. Copy your API key
|
||||
|
||||
## 2. Install the SDKs
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```bash
|
||||
npm install @supermemory/bash @e2b/code-interpreter
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```bash
|
||||
pip install supermemory e2b-code-interpreter
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 3. Build an agent with memory + code execution
|
||||
|
||||
<Tabs>
|
||||
<Tab title="TypeScript">
|
||||
```typescript agent.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
import { Sandbox } from "@e2b/code-interpreter";
|
||||
import { generateText, tool } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
async function main() {
|
||||
// 1. Set up memory (SMFS bash tool)
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!,
|
||||
containerTag: "agent_memory",
|
||||
});
|
||||
|
||||
// 2. Set up code execution (E2B sandbox)
|
||||
const sandbox = await Sandbox.create({
|
||||
apiKey: process.env.E2B_API_KEY!,
|
||||
});
|
||||
|
||||
// 3. Give the LLM both tools
|
||||
const result = await generateText({
|
||||
model: openai("gpt-4o"),
|
||||
tools: {
|
||||
memory: tool({
|
||||
description: toolDescription,
|
||||
parameters: z.object({ cmd: z.string() }),
|
||||
execute: async ({ cmd }) => bash.exec(cmd),
|
||||
}),
|
||||
execute_code: tool({
|
||||
description: "Run Python code in an isolated sandbox",
|
||||
parameters: z.object({ code: z.string() }),
|
||||
execute: async ({ code }) => {
|
||||
const execution = await sandbox.runCode(code);
|
||||
return execution.text;
|
||||
},
|
||||
}),
|
||||
},
|
||||
prompt: "Check my memory for the user's preferences, then write a script that uses them.",
|
||||
});
|
||||
|
||||
console.log(result.text);
|
||||
|
||||
// 4. Clean up
|
||||
await sandbox.kill();
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Python">
|
||||
```python agent.py
|
||||
import os
|
||||
from e2b_code_interpreter import Sandbox
|
||||
|
||||
# 1. Create an E2B sandbox
|
||||
sandbox = Sandbox(api_key=os.environ["E2B_API_KEY"])
|
||||
|
||||
# 2. Install SMFS inside the sandbox
|
||||
sandbox.commands.run("curl -fsSL https://smfs.ai/install | sh")
|
||||
|
||||
# 3. Log in and mount
|
||||
sandbox.commands.run(
|
||||
f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
|
||||
)
|
||||
sandbox.commands.run(
|
||||
"~/.local/bin/smfs mount agent_memory --ephemeral --path /memory"
|
||||
)
|
||||
|
||||
# 4. Your agent can now use the filesystem
|
||||
sandbox.commands.run('echo "User prefers dark mode" > /memory/memory.md')
|
||||
|
||||
result = sandbox.commands.run("cat /memory/profile.md")
|
||||
print(result.stdout)
|
||||
|
||||
# 5. Semantic search
|
||||
result = sandbox.commands.run("cd /memory && grep 'preferences'")
|
||||
print(result.stdout)
|
||||
|
||||
# 6. Clean up
|
||||
sandbox.commands.run("~/.local/bin/smfs unmount agent_memory")
|
||||
sandbox.kill()
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Alternative: Mount SMFS inside the sandbox
|
||||
|
||||
E2B sandboxes have full network access, so you can install and mount SMFS directly. This gives the agent a real filesystem with semantic grep.
|
||||
|
||||
```python
|
||||
from e2b_code_interpreter import Sandbox
|
||||
import os
|
||||
|
||||
sandbox = Sandbox(api_key=os.environ["E2B_API_KEY"])
|
||||
|
||||
# Install SMFS
|
||||
sandbox.commands.run("curl -fsSL https://smfs.ai/install | sh")
|
||||
|
||||
# Log in and mount
|
||||
sandbox.commands.run(
|
||||
f"~/.local/bin/smfs login --key {os.environ['SUPERMEMORY_API_KEY']}"
|
||||
)
|
||||
sandbox.commands.run(
|
||||
"~/.local/bin/smfs mount agent_memory --ephemeral --path /memory"
|
||||
)
|
||||
|
||||
# Write some memory
|
||||
sandbox.commands.run('echo "Project deadline is March 15" > /memory/notes.md')
|
||||
|
||||
# Read the auto-generated profile
|
||||
result = sandbox.commands.run("cat /memory/profile.md")
|
||||
print(result.stdout)
|
||||
|
||||
# Semantic search across all memory
|
||||
result = sandbox.commands.run("cd /memory && grep 'deadline'")
|
||||
print(result.stdout)
|
||||
|
||||
# Clean up
|
||||
sandbox.commands.run("~/.local/bin/smfs unmount agent_memory")
|
||||
sandbox.kill()
|
||||
```
|
||||
|
||||
## Custom E2B template with SMFS pre-installed
|
||||
|
||||
For faster startup, bake SMFS into a custom E2B template so you don't have to install it every time:
|
||||
|
||||
```dockerfile e2b.Dockerfile
|
||||
FROM e2b/code-interpreter:latest
|
||||
|
||||
# Pre-install SMFS
|
||||
RUN curl -fsSL https://smfs.ai/install | sh
|
||||
```
|
||||
|
||||
```bash
|
||||
e2b template build -d e2b.Dockerfile
|
||||
```
|
||||
|
||||
Then use your custom template:
|
||||
|
||||
```python
|
||||
sandbox = Sandbox(template="your-custom-template")
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- **Use `--ephemeral` for sandboxes.** E2B sandboxes are short-lived. Ephemeral mode avoids writing a local cache that will be thrown away.
|
||||
- **Custom templates save time.** Pre-install SMFS in a template to skip the install step on every sandbox boot.
|
||||
- **E2B sandboxes have a timeout.** Default is 5 minutes. Set `timeout` when creating the sandbox if your agent needs longer.
|
||||
- **One container, many sandboxes.** Mount the same container tag from multiple E2B sandboxes. Bidirectional sync keeps them in step.
|
||||
|
||||
## Resources
|
||||
|
||||
- [E2B docs](https://e2b.dev/docs)
|
||||
- [E2B SDK reference](https://e2b.dev/docs/sdk-reference)
|
||||
- [SMFS Mount reference](/smfs/mount)
|
||||
- [SMFS Bash Tool reference](/smfs/bash-tool)
|
||||
168
apps/docs/smfs/providers/vercel.mdx
Normal file
168
apps/docs/smfs/providers/vercel.mdx
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
---
|
||||
title: "Vercel AI SDK"
|
||||
sidebarTitle: "Vercel AI SDK"
|
||||
description: "Add persistent memory to agents built with the Vercel AI SDK."
|
||||
icon: "triangle"
|
||||
---
|
||||
|
||||
The [Vercel AI SDK](https://sdk.vercel.ai) is the most popular framework for building AI agents in TypeScript. SMFS plugs in as a tool — give your agent a `bash` tool backed by `@supermemory/bash` and it can `ls`, `cat`, `grep`, and write to a Supermemory container without any filesystem to manage.
|
||||
|
||||
## Architecture
|
||||
|
||||
The Vercel AI SDK uses a tool-calling pattern: you define tools, the model decides when to call them. `@supermemory/bash` fits this perfectly — it's a single tool that exposes a virtual filesystem backed by Supermemory.
|
||||
|
||||
```
|
||||
User → AI SDK → LLM → calls bash tool → @supermemory/bash → Supermemory API
|
||||
```
|
||||
|
||||
No sandbox needed. The bash tool runs in your server process and handles all the memory operations.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Supermemory](https://console.supermemory.ai) account and API key
|
||||
- Node.js 18+
|
||||
- An LLM provider (OpenAI, Anthropic, Google, etc.)
|
||||
|
||||
## 1. Install
|
||||
|
||||
```bash
|
||||
npm install @supermemory/bash ai @ai-sdk/openai zod
|
||||
```
|
||||
|
||||
## 2. Create an agent with memory
|
||||
|
||||
```typescript agent.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
import { generateText, tool } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
async function main() {
|
||||
// Set up the SMFS bash tool
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!,
|
||||
containerTag: "user_42",
|
||||
});
|
||||
|
||||
const result = await generateText({
|
||||
model: openai("gpt-4o"),
|
||||
tools: {
|
||||
bash: tool({
|
||||
description: toolDescription,
|
||||
parameters: z.object({ cmd: z.string() }),
|
||||
execute: async ({ cmd }) => bash.exec(cmd),
|
||||
}),
|
||||
},
|
||||
maxSteps: 10,
|
||||
system: `You have access to a persistent memory filesystem via the bash tool.
|
||||
Use it to remember things about the user across conversations.
|
||||
Start by reading /profile.md to see what you already know.`,
|
||||
prompt: "What do you remember about me?",
|
||||
});
|
||||
|
||||
console.log(result.text);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
That's it. The model will call `bash({ cmd: "cat /profile.md" })` to read the user's profile, `bash({ cmd: "ls /" })` to browse memory, and `bash({ cmd: "grep 'preferences'" })` to search semantically.
|
||||
|
||||
## 3. Multi-step agent with memory
|
||||
|
||||
A more complete example with conversation history and memory persistence:
|
||||
|
||||
```typescript chat.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
import { generateText, tool, CoreMessage } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
// Create one bash instance per user (reuse across requests)
|
||||
const userBashInstances = new Map();
|
||||
|
||||
async function getBash(userId: string) {
|
||||
if (!userBashInstances.has(userId)) {
|
||||
const instance = await createBash({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!,
|
||||
containerTag: `user_${userId}`,
|
||||
});
|
||||
userBashInstances.set(userId, instance);
|
||||
}
|
||||
return userBashInstances.get(userId);
|
||||
}
|
||||
|
||||
export async function chat(userId: string, messages: CoreMessage[]) {
|
||||
const { bash, toolDescription } = await getBash(userId);
|
||||
|
||||
return generateText({
|
||||
model: openai("gpt-4o"),
|
||||
tools: {
|
||||
bash: tool({
|
||||
description: toolDescription,
|
||||
parameters: z.object({ cmd: z.string() }),
|
||||
execute: async ({ cmd }) => bash.exec(cmd),
|
||||
}),
|
||||
},
|
||||
maxSteps: 10,
|
||||
system: `You are a helpful assistant with persistent memory.
|
||||
|
||||
Use the bash tool to:
|
||||
- Read /profile.md at the start of each conversation for context
|
||||
- Save important facts to /memory.md
|
||||
- Search with grep when looking for specific information
|
||||
- Organize notes in subdirectories as needed`,
|
||||
messages,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## With Vercel AI SDK Streams
|
||||
|
||||
For streaming responses in a Next.js app:
|
||||
|
||||
```typescript app/api/chat/route.ts
|
||||
import { createBash } from "@supermemory/bash";
|
||||
import { streamText, tool } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { messages, userId } = await req.json();
|
||||
|
||||
const { bash, toolDescription } = await createBash({
|
||||
apiKey: process.env.SUPERMEMORY_API_KEY!,
|
||||
containerTag: `user_${userId}`,
|
||||
});
|
||||
|
||||
const result = streamText({
|
||||
model: openai("gpt-4o"),
|
||||
tools: {
|
||||
bash: tool({
|
||||
description: toolDescription,
|
||||
parameters: z.object({ cmd: z.string() }),
|
||||
execute: async ({ cmd }) => bash.exec(cmd),
|
||||
}),
|
||||
},
|
||||
maxSteps: 10,
|
||||
system: "You have persistent memory via the bash tool. Read /profile.md for context.",
|
||||
messages,
|
||||
});
|
||||
|
||||
return result.toDataStreamResponse();
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- **One `createBash` per user.** Use the user's ID as the container tag. Each user gets their own isolated memory.
|
||||
- **Read `profile.md` first.** Tell the model to `cat /profile.md` at the start of each conversation. It's a live digest of everything in the container.
|
||||
- **`sgrep` for semantic search.** Inside the bash tool, `sgrep "query"` searches by meaning, not just text. Regular `grep` does literal matching.
|
||||
- **Cache the bash instance.** `createBash` warms the path index on startup. Reuse the instance across requests for the same user.
|
||||
- **Works with any LLM provider.** Swap `openai("gpt-4o")` for `anthropic("claude-sonnet-4-20250514")`, `google("gemini-2.0-flash")`, or any AI SDK-compatible provider.
|
||||
|
||||
## Resources
|
||||
|
||||
- [Vercel AI SDK docs](https://sdk.vercel.ai/docs)
|
||||
- [SMFS Bash Tool reference](/smfs/bash-tool)
|
||||
- [Supermemory quickstart](/quickstart)
|
||||
Loading…
Add table
Reference in a new issue