feat(memory): add opt-in scoped memory tools

This commit is contained in:
sargatxet committed 2026-10-08 14:18:29 +02:00
1 parent cd09ed531d
commit e4e56db488
14 files changed
+618 -5

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
import assert from "node:assert/strict"
import test from "node:test"
import { createMemoryStore } from "../dist/memory.js"
function createStorage() {
const values = new Map()
return {
values,
get: async (key) => values.get(key),
set: async (key, value) => { values.set(key, value) },
remove: async (key) => { values.delete(key) },
scan: async ({ prefix, after, limit }) => {
const keys = [...values.keys()].filter((key) => key.startsWith(prefix)).sort().filter((key) => after === undefined || key > after)
const selected = keys.slice(0, limit)
return {
entries: selected.map((key) => ({ key, value: values.get(key) })),
...(keys.length > selected.length && selected.length > 0 ? { next: selected.at(-1) } : {}),
}
},
}
}
test("memory records expire and are removed when accessed", async () => {
const storage = createStorage()
let clock = new Date("2026-10-08T12:00:00.000Z")
const store = createMemoryStore({
storage,
projectID: "project-1",
projectCanonical: "/workspace/demo",
projectMemoryEnabled: false,
retentionDays: 1,
getSession: async (sessionID) => ({ projectID: "project-1", location: { directory: `/workspace/demo/${sessionID}` } }),
now: () => clock,
createID: () => "12345678-1234-4234-8234-123456789abc",
})
const record = await store.save({ sessionID: "session-1", scope: "session", content: "Keep this briefly" })
assert.equal(record.expiresAt, "2026-10-09T12:00:00.000Z")
clock = new Date("2026-10-09T12:00:00.000Z")
assert.equal(await store.get({ sessionID: "session-1", scope: "session", id: record.id }), undefined)
assert.equal(storage.values.size, 0)
})
test("memory writes reject sessions belonging to another project", async () => {
const store = createMemoryStore({
storage: createStorage(),
projectID: "project-1",
projectCanonical: "/workspace/demo",
projectMemoryEnabled: false,
retentionDays: 30,
getSession: async () => ({ projectID: "project-2", location: { directory: "/workspace/other" } }),
})
await assert.rejects(store.save({ sessionID: "foreign", scope: "session", content: "remember" }), /current project/)
})