mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-11 03:37:56 +00:00
Every integration (AI SDK, OpenAI, Mastra, VoltAgent, Claude memory) now calls v5 through `supermemory@5`. The config takes one `namespace` instead of `containerTags` or `projectId`, and `withSupermemory` takes `namespace` and `id` instead of `containerTag` and `customId`. No aliases. With no config the tools still use `sm_project_default`. Conversations are stored as one document per conversation keyed by `id` instead of `/v4/conversations`. `memoryForget` drops `reason`; forgetting by text previews with `forgetMatching` and then forgets exact matches by id. Claude memory marks its files with `metadata.source` instead of a second tag. Search keeps the 2.x defaults so results do not shift. `packages/ai-sdk` is removed: npm already deprecates it in favor of `@supermemory/tools/ai-sdk`, so its CI steps and playground wiring go too. `apps/sdk-playground` moves to the new tools API and v5 routes, including its Python server. Tested against production: add, search, profile, list and delete. 112 unit tests pass; type errors drop from 148 to 141, none new. The `supermemory` dependency pins the rc until 5.0.0 is published.
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
// Fake v5 API responses for tests that stub globalThis.fetch.
|
|
|
|
export const jsonResponse = (body: unknown, status = 200): Response =>
|
|
new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { "content-type": "application/json" },
|
|
})
|
|
|
|
export const errorResponse = (status = 500, message = "Server error") =>
|
|
jsonResponse({ error: message }, status)
|
|
|
|
export const profileBody = (
|
|
staticMemories: string[] = [],
|
|
dynamicMemories: string[] = [],
|
|
) => ({
|
|
profile: {
|
|
static: staticMemories.map((memory, index) => ({
|
|
id: `static_${index}`,
|
|
memory,
|
|
})),
|
|
dynamic: dynamicMemories.map((memory, index) => ({
|
|
id: `dynamic_${index}`,
|
|
memory,
|
|
})),
|
|
buckets: {},
|
|
},
|
|
})
|
|
|
|
export const searchBody = (memories: string[] = []) => ({
|
|
results: memories.map((memory, index) => ({
|
|
id: `mem_${index}`,
|
|
memory,
|
|
metadata: {},
|
|
similarity: 0.9,
|
|
isLatest: true,
|
|
isInference: false,
|
|
system: { createdAt: "2026-01-01", updatedAt: "2026-01-01" },
|
|
})),
|
|
searchTime: 1,
|
|
})
|
|
|
|
export const addBody = (id = "doc_1") => ({ id, status: "queued" })
|
|
|
|
export const requestPath = (input: unknown): string =>
|
|
new URL(String(input instanceof Request ? input.url : input)).pathname
|
|
|
|
export const requestJson = (init?: RequestInit): Record<string, unknown> =>
|
|
init?.body ? JSON.parse(String(init.body)) : {}
|
|
|
|
// Routes by path suffix so a single mock serves profile, search, and add calls.
|
|
export const v5Router =
|
|
(routes: {
|
|
profile?: () => unknown
|
|
search?: () => unknown
|
|
document?: () => unknown
|
|
}) =>
|
|
async (input: unknown): Promise<Response> => {
|
|
const path = requestPath(input)
|
|
if (path.endsWith("/profile"))
|
|
return jsonResponse(routes.profile?.() ?? profileBody())
|
|
if (path.endsWith("/search"))
|
|
return jsonResponse(routes.search?.() ?? searchBody())
|
|
if (path.endsWith("/document"))
|
|
return jsonResponse(routes.document?.() ?? addBody())
|
|
return errorResponse(404, `Unexpected path ${path}`)
|
|
}
|