fix: delete_all now drains all pages, not just the first batch (close… (#4872)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
@@ -649,6 +649,66 @@ describe("Memory - deleteAll()", () => {
|
||||
"At least one filter is required to delete all memories",
|
||||
);
|
||||
});
|
||||
|
||||
test("deletes past the vector store default page limit", async () => {
|
||||
const mem = createMemory();
|
||||
const internals = mem as any;
|
||||
await internals._ensureInitialized();
|
||||
const pagedUserId = `deleteall_paged_${Date.now()}`;
|
||||
const total = 150;
|
||||
|
||||
await internals.vectorStore.insert(
|
||||
Array.from({ length: total }, () => new Array(1536).fill(0.1)),
|
||||
Array.from({ length: total }, (_, index) => `paged-${index}`),
|
||||
Array.from({ length: total }, (_, index) => ({
|
||||
data: `Fact ${index}`,
|
||||
hash: `hash-${index}`,
|
||||
user_id: pagedUserId,
|
||||
createdAt: new Date().toISOString(),
|
||||
})),
|
||||
);
|
||||
|
||||
const [before] = await internals.vectorStore.list(
|
||||
{ user_id: pagedUserId },
|
||||
total * 2,
|
||||
);
|
||||
expect(before).toHaveLength(total);
|
||||
|
||||
const result = await mem.deleteAll({ userId: pagedUserId });
|
||||
expect(result.message).toBe("Memories deleted successfully!");
|
||||
|
||||
const [after] = await internals.vectorStore.list(
|
||||
{ user_id: pagedUserId },
|
||||
total * 2,
|
||||
);
|
||||
expect(after).toHaveLength(0);
|
||||
}, 60000);
|
||||
|
||||
test("stops when the vector store keeps returning the same batch", async () => {
|
||||
const mem = createMemory();
|
||||
const internals = mem as any;
|
||||
await internals._ensureInitialized();
|
||||
const stale = [
|
||||
{ id: "stale-1", payload: { data: "x", user_id: "u1" } },
|
||||
{ id: "stale-2", payload: { data: "x", user_id: "u1" } },
|
||||
];
|
||||
const listSpy = jest
|
||||
.spyOn(internals.vectorStore, "list")
|
||||
.mockResolvedValueOnce([stale, stale.length])
|
||||
.mockResolvedValueOnce([stale, stale.length])
|
||||
.mockImplementation(async () => {
|
||||
throw new Error("deleteAll should have stopped after a repeated batch");
|
||||
});
|
||||
const deleteSpy = jest
|
||||
.spyOn(internals, "deleteMemory")
|
||||
.mockResolvedValue("stale-1");
|
||||
|
||||
const result = await mem.deleteAll({ userId: "u1" });
|
||||
|
||||
expect(result.message).toBe("Memories deleted successfully!");
|
||||
expect(listSpy).toHaveBeenCalledTimes(2);
|
||||
expect(deleteSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── getAll() ────────────────────────────────────────────
|
||||
|
||||
@@ -362,7 +362,10 @@ describe("Memory Input Validation", () => {
|
||||
|
||||
await memory.deleteAll({ userId: " alice " });
|
||||
|
||||
expect(listSpy).toHaveBeenCalledWith({ user_id: "alice" });
|
||||
expect(listSpy).toHaveBeenCalledWith(
|
||||
{ user_id: "alice" },
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5177,20 +5177,22 @@ describe("Memory class – backward compat with all providers", () => {
|
||||
updated_at: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
mockVStore.list.mockResolvedValue([
|
||||
[
|
||||
{
|
||||
id: memoryId,
|
||||
payload: {
|
||||
memory: "test",
|
||||
hash: "h",
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
mockVStore.list
|
||||
.mockResolvedValueOnce([
|
||||
[
|
||||
{
|
||||
id: memoryId,
|
||||
payload: {
|
||||
memory: "test",
|
||||
hash: "h",
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
1,
|
||||
]);
|
||||
],
|
||||
1,
|
||||
])
|
||||
.mockResolvedValue([[], 0]);
|
||||
mockVectorStoreFactory.create.mockReturnValue(mockVStore);
|
||||
|
||||
const mem = new MemoryClass({
|
||||
|
||||
Reference in New Issue
Block a user