memories-lite 0.9.4 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,126 @@
1
+ /// <reference types="jest" />
2
+ import { MemoriesLite } from "../src";
3
+ import { SearchResult } from "../src/types";
4
+ import dotenv from "dotenv";
5
+ import { createTestMemory } from "./init.mem";
6
+
7
+ dotenv.config();
8
+
9
+ jest.setTimeout(30000); // Increase timeout to 30 seconds
10
+
11
+ describe("Memory Class TODO regression tests", () => {
12
+ let memory: MemoriesLite;
13
+ let userId: string;
14
+
15
+ beforeEach(async () => {
16
+ // Initialize memory via helper
17
+ ({ memory, userId } = createTestMemory({ customPrompt: "L'utilisateur travail pour une régie immobilière!" }));
18
+ // Reset all memories before each test
19
+ await memory.reset(userId);
20
+ });
21
+
22
+ afterEach(async () => {
23
+ // Clean up after each test
24
+ await memory.reset(userId);
25
+ });
26
+
27
+ describe("Manage TODOs (add/remove/update)", () => {
28
+ it("should add a TODO when explicitly asked with 'ajoute un todo'", async () => {
29
+ const result = (await memory.capture([
30
+ { role: "user", content: "Ajoute un todo: appeler la banque demain à 09:00" },
31
+ { role: "assistant", content: "Compris, j'ajoute un todo." }
32
+ ], userId, {})) as SearchResult;
33
+
34
+ expect(result).toBeDefined();
35
+ expect(Array.isArray(result.results)).toBe(true);
36
+ // At least one TODO should be captured when explicitly asked
37
+ expect(result.results.some(r => r.type === "todo")).toBe(true);
38
+ });
39
+
40
+ it("should not create a TODO when task is implicit only", async () => {
41
+ const result = (await memory.capture([
42
+ { role: "user", content: "Je dois appeler la banque demain à 09:00" },
43
+ { role: "assistant", content: "Très bien." }
44
+ ], userId, {})) as SearchResult;
45
+
46
+ expect(result).toBeDefined();
47
+ expect(Array.isArray(result.results)).toBe(true);
48
+ // Must not infer TODO without explicit user request
49
+ expect(result.results.every(r => r.type !== "todo")).toBe(true);
50
+ });
51
+
52
+ it("should not create memory for how-to business requests (procedural removed)", async () => {
53
+ const result = (await memory.capture([
54
+ { role: "user", content: "Je veux résilier un bail, comment faire ?" },
55
+ { role: "assistant", content: "Voici la procédure..." }
56
+ ], userId, {})) as SearchResult;
57
+
58
+ expect(result).toBeDefined();
59
+ expect(Array.isArray(result.results)).toBe(true);
60
+ // Business procedures should not create memories (procedural type removed)
61
+ expect(result.results.length).toBe(0);
62
+ });
63
+
64
+ it("should add then update a TODO via new capture", async () => {
65
+ const add = (await memory.capture([
66
+ { role: "user", content: "Ajoute un todo: appeler la banque demain à 09:00" },
67
+ { role: "assistant", content: "Compris, j'ajoute un todo." }
68
+ ], userId, {})) as SearchResult;
69
+
70
+ expect(add).toBeDefined();
71
+ const todo = add.results.find(r => r.type === "todo");
72
+ expect(todo?.id).toBeDefined();
73
+
74
+ const newText = "Appeler la banque lundi à 10:00";
75
+ const updateRes = (await memory.capture([
76
+ { role: "user", content: `Mets à jour ce todo: ${newText}` },
77
+ { role: "assistant", content: "OK, je mets à jour le todo." }
78
+ ], userId, {})) as SearchResult;
79
+
80
+ expect(updateRes).toBeDefined();
81
+ // Expect an UPDATE event captured (merger decides UPDATE vs ADD)
82
+ const updatedItem = updateRes.results.find(r => (r as any).metadata?.event === 'UPDATE' && r.type === 'todo');
83
+ expect(updatedItem).toBeDefined();
84
+ // Allow optional suffix from LLM like annotations removal; assert containment
85
+ expect(updatedItem?.memory?.toLowerCase().includes("appeler la banque lundi à 10:00".toLowerCase())).toBe(true);
86
+
87
+ const persisted = await memory.get(updatedItem!.id, userId);
88
+ expect(persisted).not.toBeNull();
89
+ expect(persisted?.memory?.toLowerCase().includes("appeler la banque lundi à 10:00".toLowerCase())).toBe(true);
90
+ expect(persisted?.type).toBe("todo");
91
+ });
92
+
93
+ it("should add then delete a TODO via new capture", async () => {
94
+ const add = (await memory.capture([
95
+ { role: "user", content: "Ajoute un todo: appeler la banque demain à 09:00" },
96
+ { role: "assistant", content: "Compris, j'ajoute un todo." }
97
+ ], userId, {})) as SearchResult;
98
+
99
+ const todo = add.results.find(r => r.type === "todo");
100
+ expect(todo?.id).toBeDefined();
101
+
102
+ const delRes = (await memory.capture([
103
+ { role: "user", content: `Supprime ce todo: ${todo!.memory}` },
104
+ { role: "assistant", content: "Je supprime le todo." }
105
+ ], userId, {})) as SearchResult;
106
+
107
+ expect(delRes).toBeDefined();
108
+ const deletedItem = delRes.results.find(r => (r as any).metadata?.event === 'DELETE' && r.type === 'todo');
109
+ expect(deletedItem).toBeDefined();
110
+
111
+ const persisted = await memory.get(deletedItem!.id, userId);
112
+ expect(persisted).toBeNull();
113
+ });
114
+
115
+ it("should add a TODO using 'tâche' wording (synonym)", async () => {
116
+ const result = (await memory.capture([
117
+ { role: "user", content: "Ajoute une tâche: appeler la banque demain à 09:00" },
118
+ { role: "assistant", content: "C'est noté, j'ajoute la tâche." }
119
+ ], userId, {})) as SearchResult;
120
+
121
+ expect(result).toBeDefined();
122
+ expect(Array.isArray(result.results)).toBe(true);
123
+ expect(result.results.some(r => r.type === "todo")).toBe(true);
124
+ });
125
+ });
126
+ });