supermemory/packages/tools/test/openai-middleware.unit.test.ts
Dhravya Shah 2fa2e0d85c feat(tools): SDK-level cross-source memory deduplication
Move profile deduplication into the SDK middleware. Facts are normalized
(strip leading date, trim, collapse whitespace, casefold) and deduplicated
in static > dynamic > search priority within each request, then injected as
one owned <supermemory> block that replaces the previous block instead of
accumulating. Dedup is mode-aware so query-mode search results are not
dropped against an omitted profile. No global/browser Set: request-local
only, safe for concurrent requests and Cloudflare Workers.

Covers AI SDK, OpenAI Chat/Responses, Mastra, and VoltAgent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-18 08:13:47 -07:00

61 lines
1.8 KiB
TypeScript

import type OpenAI from "openai"
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().mockResolvedValue({
ok: true,
json: async () => ({
profile: { static: [{ memory: "Fresh profile fact" }], dynamic: [] },
searchResults: { results: [] },
}),
}),
)
const originalCreate = vi.fn().mockResolvedValue({ choices: [] })
const client = {
chat: { completions: { create: originalCreate } },
} as unknown as OpenAI
const wrapped = withSupermemory(client, {
containerTag: "user-a",
customId: "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)
})
})