Skip to content

Commit 147a549

Browse files
updated ai sdk
1 parent a0d469a commit 147a549

File tree

6 files changed

+199
-176
lines changed

6 files changed

+199
-176
lines changed

apps/docs/integrations/ai-sdk.mdx

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@ Automatically inject user profiles into every LLM call for instant personalizati
3232

3333
```typescript
3434
import { generateText } from "ai"
35-
import { withSupermemory } from "@supermemory/tools/ai-sdk"
35+
import { withSupermemory } from "@supermemory/tools/vercel"
3636
import { openai } from "@ai-sdk/openai"
3737

38-
const modelWithMemory = withSupermemory(openai("gpt-5"), "user-123")
38+
const modelWithMemory = withSupermemory({
39+
model: openai("gpt-4"),
40+
containerTag: "user-123",
41+
customId: "conv-456"
42+
})
3943

4044
const result = await generateText({
4145
model: modelWithMemory,
@@ -44,12 +48,14 @@ const result = await generateText({
4448
```
4549

4650
<Note>
47-
**Memory saving is disabled by default.** The middleware only retrieves existing memories. To automatically save new memories:
51+
**Memory saving is enabled by default.** The middleware automatically saves conversations to memory. To disable memory saving:
4852

4953
```typescript
50-
const modelWithMemory = withSupermemory(openai("gpt-5"), "user-123", {
51-
conversationId: "conv-1",
52-
addMemory: "always"
54+
const modelWithMemory = withSupermemory({
55+
model: openai("gpt-4"),
56+
containerTag: "user-123",
57+
customId: "conv-456",
58+
addMemory: "never"
5359
})
5460
```
5561
</Note>
@@ -59,27 +65,42 @@ const result = await generateText({
5965
**Profile Mode (Default)** - Retrieves the user's complete profile:
6066

6167
```typescript
62-
const model = withSupermemory(openai("gpt-4"), "user-123", { mode: "profile" })
68+
const model = withSupermemory({
69+
model: openai("gpt-4"),
70+
containerTag: "user-123",
71+
customId: "conv-456",
72+
mode: "profile"
73+
})
6374
```
6475

6576
**Query Mode** - Searches memories based on the user's message:
6677

6778
```typescript
68-
const model = withSupermemory(openai("gpt-4"), "user-123", { mode: "query" })
79+
const model = withSupermemory({
80+
model: openai("gpt-4"),
81+
containerTag: "user-123",
82+
customId: "conv-456",
83+
mode: "query"
84+
})
6985
```
7086

7187
**Full Mode** - Combines profile AND query-based search:
7288

7389
```typescript
74-
const model = withSupermemory(openai("gpt-4"), "user-123", { mode: "full" })
90+
const model = withSupermemory({
91+
model: openai("gpt-4"),
92+
containerTag: "user-123",
93+
customId: "conv-456",
94+
mode: "full"
95+
})
7596
```
7697

7798
### Custom Prompt Templates
7899

79100
Customize how memories are formatted. The template receives `userMemories`, `generalSearchMemories`, and `searchResults` (raw array for filtering by metadata):
80101

81102
```typescript
82-
import { withSupermemory, type MemoryPromptData } from "@supermemory/tools/ai-sdk"
103+
import { withSupermemory, type MemoryPromptData } from "@supermemory/tools/vercel"
83104

84105
const claudePrompt = (data: MemoryPromptData) => `
85106
<context>
@@ -92,7 +113,10 @@ const claudePrompt = (data: MemoryPromptData) => `
92113
</context>
93114
`.trim()
94115

95-
const model = withSupermemory(anthropic("claude-3-sonnet"), "user-123", {
116+
const model = withSupermemory({
117+
model: anthropic("claude-3-sonnet"),
118+
containerTag: "user-123",
119+
customId: "conv-456",
96120
mode: "full",
97121
promptTemplate: claudePrompt
98122
})
@@ -101,7 +125,10 @@ const model = withSupermemory(anthropic("claude-3-sonnet"), "user-123", {
101125
### Verbose Logging
102126

103127
```typescript
104-
const model = withSupermemory(openai("gpt-4"), "user-123", {
128+
const model = withSupermemory({
129+
model: openai("gpt-4"),
130+
containerTag: "user-123",
131+
customId: "conv-456",
105132
verbose: true
106133
})
107134
// Console output shows memory retrieval details

bun.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tools/src/vercel/index.ts

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ import {
1212
} from "./middleware"
1313
import type { PromptTemplate, MemoryPromptData } from "./memory-prompt"
1414

15-
interface WrapVercelLanguageModelOptions {
16-
/** Conversation ID to group messages into a single document (maps to customId in Supermemory). Required when addMemory is "always". */
17-
conversationId?: string
15+
interface WrapVercelLanguageModelOptions<T extends LanguageModel> {
16+
/** The language model to wrap with supermemory capabilities */
17+
model: T
18+
/** The container tag/identifier for memory search (e.g., user ID, project ID) */
19+
containerTag: string
20+
/** Custom ID to group messages into a single document. Required. */
21+
customId: string
1822
/** Enable detailed logging of memory search and injection */
1923
verbose?: boolean
2024
/**
@@ -35,8 +39,8 @@ interface WrapVercelLanguageModelOptions {
3539
searchLimit?: number
3640
/**
3741
* Memory persistence mode:
38-
* - "always": Automatically save conversations as memories (requires conversationId)
39-
* - "never": Only retrieve memories, don't store new ones (default)
42+
* - "always": Automatically save conversations as memories (default)
43+
* - "never": Only retrieve memories, don't store new ones
4044
*/
4145
addMemory?: "always" | "never"
4246
/** Supermemory API key (falls back to SUPERMEMORY_API_KEY env var) */
@@ -72,35 +76,40 @@ interface WrapVercelLanguageModelOptions {
7276
* Supports both Vercel AI SDK 5 (LanguageModelV2) and SDK 6 (LanguageModelV3) via runtime
7377
* detection of `model.specificationVersion`.
7478
*
75-
* @param model - The language model to wrap with supermemory capabilities (V2 or V3)
76-
* @param containerTag - The container tag/identifier for memory search (e.g., user ID, project ID)
77-
* @param options - Configuration options for the middleware
78-
* @param options.conversationId - Conversation ID to group messages into a single document (maps to customId in Supermemory)
79+
* @param options - Configuration object containing model and Supermemory options
80+
* @param options.model - The language model to wrap with supermemory capabilities (V2 or V3)
81+
* @param options.containerTag - Required. The container tag/identifier for memory search (e.g., user ID, project ID)
82+
* @param options.customId - Required. Custom ID to group messages into a single document
7983
* @param options.verbose - Optional flag to enable detailed logging of memory search and injection process (default: false)
8084
* @param options.mode - Optional mode for memory search: "profile", "query", or "full" (default: "profile")
8185
* @param options.searchMode - Optional search mode: "memories" (default), "hybrid" (memories + chunks), or "documents" (chunks only)
8286
* @param options.searchLimit - Optional maximum number of search results when using hybrid/documents mode (default: 10)
83-
* @param options.addMemory - Optional mode for memory persistence: "always" (requires conversationId), "never" (default)
87+
* @param options.addMemory - Optional mode for memory persistence: "always" (default - saves conversations), "never" (read-only mode)
8488
* @param options.apiKey - Optional Supermemory API key to use instead of the environment variable
8589
* @param options.baseUrl - Optional base URL for the Supermemory API (default: "https://api.supermemory.ai")
8690
*
8791
* @returns A wrapped language model that automatically includes relevant memories in prompts
8892
*
8993
* @example
9094
* ```typescript
91-
* import { withSupermemory } from "@supermemory/tools/ai-sdk"
95+
* import { withSupermemory } from "@supermemory/tools/vercel"
9296
* import { openai } from "@ai-sdk/openai"
97+
* import { generateText } from "ai"
9398
*
9499
* // Basic usage with profile memories
95-
* const modelWithMemory = withSupermemory(openai("gpt-4"), "user-123", {
96-
* conversationId: "conv-456",
100+
* const modelWithMemory = withSupermemory({
101+
* model: openai("gpt-4"),
102+
* containerTag: "user-123",
103+
* customId: "conv-456",
97104
* mode: "full",
98105
* addMemory: "always"
99106
* })
100107
*
101108
* // RAG usage with hybrid search (memories + document chunks)
102-
* const ragModel = withSupermemory(openai("gpt-4"), "user-123", {
103-
* conversationId: "conv-789",
109+
* const ragModel = withSupermemory({
110+
* model: openai("gpt-4"),
111+
* containerTag: "user-123",
112+
* customId: "conv-789",
104113
* mode: "full",
105114
* searchMode: "hybrid", // Search both memories and document chunks
106115
* searchLimit: 15,
@@ -116,38 +125,28 @@ interface WrapVercelLanguageModelOptions {
116125
* @throws {Error} When supermemory API request fails
117126
*/
118127
const wrapVercelLanguageModel = <T extends LanguageModel>(
119-
model: T,
120-
containerTag: string,
121-
options?: WrapVercelLanguageModelOptions,
128+
options: WrapVercelLanguageModelOptions<T>,
122129
): T => {
123-
const providedApiKey = options?.apiKey ?? process.env.SUPERMEMORY_API_KEY
130+
const { model, containerTag, customId, ...restOptions } = options
131+
const providedApiKey = restOptions.apiKey ?? process.env.SUPERMEMORY_API_KEY
124132

125133
if (!providedApiKey) {
126134
throw new Error(
127135
"SUPERMEMORY_API_KEY is not set — provide it via `options.apiKey` or set `process.env.SUPERMEMORY_API_KEY`",
128136
)
129137
}
130138

131-
if (
132-
(options?.addMemory ?? "never") === "always" &&
133-
!options?.conversationId
134-
) {
135-
throw new Error(
136-
'conversationId is required when addMemory is "always" — provide it via options.conversationId to group messages into a single document',
137-
)
138-
}
139-
140139
const ctx = createSupermemoryContext({
141140
containerTag,
142141
apiKey: providedApiKey,
143-
conversationId: options?.conversationId,
144-
verbose: options?.verbose ?? false,
145-
mode: options?.mode ?? "profile",
146-
searchMode: options?.searchMode ?? "memories",
147-
searchLimit: options?.searchLimit ?? 10,
148-
addMemory: options?.addMemory ?? "never",
149-
baseUrl: options?.baseUrl,
150-
promptTemplate: options?.promptTemplate,
142+
customId,
143+
verbose: restOptions.verbose ?? false,
144+
mode: restOptions.mode ?? "profile",
145+
searchMode: restOptions.searchMode ?? "memories",
146+
searchLimit: restOptions.searchLimit ?? 10,
147+
addMemory: restOptions.addMemory ?? "always",
148+
baseUrl: restOptions.baseUrl,
149+
promptTemplate: restOptions.promptTemplate,
151150
})
152151

153152
const wrappedModel = {
@@ -163,7 +162,7 @@ const wrapVercelLanguageModel = <T extends LanguageModel>(
163162
const userMessage = getLastUserMessage(params)
164163
if (
165164
ctx.addMemory === "always" &&
166-
ctx.conversationId &&
165+
ctx.customId &&
167166
userMessage &&
168167
userMessage.trim()
169168
) {
@@ -173,7 +172,7 @@ const wrapVercelLanguageModel = <T extends LanguageModel>(
173172
saveMemoryAfterResponse(
174173
ctx.client,
175174
ctx.containerTag,
176-
ctx.conversationId,
175+
ctx.customId,
177176
assistantResponseText,
178177
params,
179178
ctx.logger,
@@ -216,14 +215,14 @@ const wrapVercelLanguageModel = <T extends LanguageModel>(
216215
const userMessage = getLastUserMessage(params)
217216
if (
218217
ctx.addMemory === "always" &&
219-
ctx.conversationId &&
218+
ctx.customId &&
220219
userMessage &&
221220
userMessage.trim()
222221
) {
223222
saveMemoryAfterResponse(
224223
ctx.client,
225224
ctx.containerTag,
226-
ctx.conversationId,
225+
ctx.customId,
227226
generatedText,
228227
params,
229228
ctx.logger,

packages/tools/src/vercel/middleware.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ const convertToConversationMessages = (
102102
export const saveMemoryAfterResponse = async (
103103
_client: Supermemory,
104104
containerTag: string,
105-
conversationId: string,
105+
customId: string,
106106
assistantResponseText: string,
107107
params: LanguageModelCallOptions,
108108
logger: Logger,
@@ -116,7 +116,7 @@ export const saveMemoryAfterResponse = async (
116116
)
117117

118118
const response = await addConversation({
119-
conversationId,
119+
conversationId: customId,
120120
messages: conversationMessages,
121121
containerTags: [containerTag],
122122
apiKey,
@@ -125,7 +125,7 @@ export const saveMemoryAfterResponse = async (
125125

126126
logger.info("Conversation saved successfully via /v4/conversations", {
127127
containerTag,
128-
conversationId,
128+
customId,
129129
messageCount: conversationMessages.length,
130130
responseId: response.id,
131131
})
@@ -144,8 +144,8 @@ interface SupermemoryMiddlewareOptions {
144144
containerTag: string
145145
/** Supermemory API key */
146146
apiKey: string
147-
/** Conversation ID to group messages into a single document (maps to customId in Supermemory). Required when addMemory is "always". */
148-
conversationId?: string
147+
/** Custom ID to group messages into a single document. Required. */
148+
customId: string
149149
/** Enable detailed logging of memory search and injection */
150150
verbose?: boolean
151151
/**
@@ -180,7 +180,7 @@ interface SupermemoryMiddlewareContext {
180180
client: Supermemory
181181
logger: Logger
182182
containerTag: string
183-
conversationId?: string
183+
customId: string
184184
mode: MemoryMode
185185
searchMode: SearchMode
186186
searchLimit: number
@@ -201,7 +201,7 @@ export const createSupermemoryContext = (
201201
const {
202202
containerTag,
203203
apiKey,
204-
conversationId,
204+
customId,
205205
verbose = false,
206206
mode = "profile",
207207
searchMode = "memories",
@@ -225,7 +225,7 @@ export const createSupermemoryContext = (
225225
client,
226226
logger,
227227
containerTag,
228-
conversationId,
228+
customId,
229229
mode,
230230
searchMode,
231231
searchLimit,
@@ -247,7 +247,7 @@ const makeTurnKey = (
247247
): string => {
248248
return MemoryCache.makeTurnKey(
249249
ctx.containerTag,
250-
ctx.conversationId,
250+
ctx.customId,
251251
ctx.mode,
252252
userMessage,
253253
)
@@ -288,7 +288,7 @@ export const transformParamsWithMemory = async (
288288

289289
ctx.logger.info("Starting memory search", {
290290
containerTag: ctx.containerTag,
291-
conversationId: ctx.conversationId,
291+
customId: ctx.customId,
292292
mode: ctx.mode,
293293
searchMode: ctx.searchMode,
294294
isNewTurn,

0 commit comments

Comments
 (0)