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.
60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import type OpenAI from "openai"
|
|
import { jsonResponse, profileBody } from "./v5-fetch"
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
import { withSupermemory } from "../src/openai"
|
|
|
|
describe("OpenAI middleware memory context", () => {
|
|
const originalApiKey = process.env.SUPERMEMORY_API_KEY
|
|
|
|
beforeEach(() => {
|
|
process.env.SUPERMEMORY_API_KEY = "sm_test_key"
|
|
})
|
|
|
|
afterEach(() => {
|
|
if (originalApiKey === undefined) delete process.env.SUPERMEMORY_API_KEY
|
|
else process.env.SUPERMEMORY_API_KEY = originalApiKey
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
it("replaces prior SDK context in chat system messages", async () => {
|
|
vi.stubGlobal(
|
|
"fetch",
|
|
vi.fn(async () => jsonResponse(profileBody(["Fresh profile fact"]))),
|
|
)
|
|
const originalCreate = vi.fn(() =>
|
|
Object.assign(Promise.resolve({ choices: [] }), {
|
|
asResponse: async () => new Response(),
|
|
}),
|
|
)
|
|
const client = {
|
|
chat: { completions: { create: originalCreate } },
|
|
} as unknown as OpenAI
|
|
const wrapped = withSupermemory(client, {
|
|
namespace: "user-a",
|
|
id: "conversation-a",
|
|
mode: "profile",
|
|
addMemory: "never",
|
|
})
|
|
|
|
await wrapped.chat.completions.create({
|
|
model: "gpt-4o-mini",
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content:
|
|
'Be helpful.\n\n<supermemory context="user-memories" readonly>\nStale profile fact\n</supermemory>',
|
|
},
|
|
{ role: "user", content: "What do you remember?" },
|
|
],
|
|
})
|
|
|
|
const forwarded = originalCreate.mock.calls[0]?.[0]
|
|
const content = String(forwarded.messages[0].content)
|
|
expect(content).toContain("Be helpful.")
|
|
expect(content).toContain("Fresh profile fact")
|
|
expect(content).not.toContain("Stale profile fact")
|
|
expect(
|
|
content.match(/<supermemory context="user-memories" readonly>/g),
|
|
).toHaveLength(1)
|
|
})
|
|
})
|