memories-lite 0.9.5 → 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.
@@ -9,10 +9,9 @@ export const FactRetrievalSchema_simple = z.object({
9
9
  });
10
10
 
11
11
 
12
- //1. **Factual memory** – stable facts & preferences
13
- //2. **Episodic memory** – time‑stamped events / interactions
14
- //3. **Procedural memory** – step‑by‑step know‑how
15
- //4. **Todo memory** – explicit user tasks to remember
12
+ //1. **Factual memory** – stable facts & preferences about the user
13
+ //2. **Todo memory** – explicit user tasks to remember
14
+ //3. **Assistant preference memory** – how the user wants the AI to behave
16
15
  //
17
16
  export const FactRetrievalSchema_extended = z.object({
18
17
  facts: z
@@ -20,11 +19,10 @@ export const FactRetrievalSchema_extended = z.object({
20
19
  z.object({
21
20
  fact: z.string().describe("The fact extracted from the conversation."),
22
21
  existing: z.boolean().describe("Whether the fact is already present"),
23
- type: z.enum(["assistant_preference","factual","episodic","procedural","todo"])
22
+ type: z.enum(["assistant_preference","factual","todo"])
24
23
  .describe(`The type of the fact.
25
24
  Use 'assistant_preference' for Assistant behavior preferences (style/language/constraints/commands).
26
- Use 'episodic' always for time-based events.
27
- Use 'procedural' for how-to/business questions (e.g., « je veux résilier un bail, comment faire ? »).
25
+ Use 'factual' for stable user facts (identity, preferences, beliefs, work context).
28
26
  Use 'todo' ONLY if the user explicitly asks to save/keep as a todo (e.g., « garde/enregistre en todo », « ajoute un todo »). Do not infer todos.
29
27
  `),
30
28
  })
@@ -56,8 +54,8 @@ export const MemoryUpdateSchema = z.object({
56
54
  "The reason why you selected this event.",
57
55
  ),
58
56
  type: z
59
- .enum(["factual", "episodic", "todo", "procedural","assistant_preference"])
60
- .describe("Type of the memory. Use 'assistant_preference' for Assistant behavior preferences, 'procedural' for all business processes."),
57
+ .enum(["factual", "todo", "assistant_preference"])
58
+ .describe("Type of the memory. Use 'assistant_preference' for Assistant behavior preferences, 'factual' for user facts, 'todo' for explicit tasks."),
61
59
  }),
62
60
  )
63
61
  .describe(
@@ -67,8 +65,8 @@ export const MemoryUpdateSchema = z.object({
67
65
  /**
68
66
  * Practical Application:
69
67
  *
70
- * If the task is "factual" (e.g., "Where do I live?") → retrieve factual memory.
71
- * If the task is temporal or event-based ("What was I doing yesterday?") → retrieve episodic memory.
68
+ * If the task is "factual" (e.g., "Where do I live?", "What's my job?") → retrieve factual memory.
69
+ * If the task is about assistant behavior (e.g., "How should I respond?") → retrieve assistant_preference memory.
72
70
  * If the task is a user task/reminder (e.g., "Add a reminder to call the bank tomorrow") → retrieve todo memory.
73
71
  */
74
72
  export const MEMORY_STRING_SYSTEM = `# DIRECTIVES FOR MEMORIES
@@ -82,12 +80,7 @@ export const MEMORY_STRING_SYSTEM = `# DIRECTIVES FOR MEMORIES
82
80
 
83
81
  export const MEMORY_STRING_PREFIX = "Use these contextual memories to guide your response. Prioritize the user's question. Ignore irrelevant memories."
84
82
 
85
- export const MEMORY_STRING_SYSTEM_OLD = `# USER AND MEMORIES PREFERENCES:
86
- - Utilize the provided memories to guide your responses.
87
- - Disregard any memories that are not relevant.
88
- - By default, do not reference this section or the memories in your response.
89
- `;
90
-
83
+
91
84
  // Deprecated: getFactRetrievalMessages_O removed in favor of getFactRetrievalMessages
92
85
 
93
86
 
@@ -98,36 +91,31 @@ export function getFactRetrievalMessages(
98
91
  ): [string, string] {
99
92
 
100
93
  const injectCustomRules = (customRules:string) => customRules ?`\n# PRE-EXISTING FACTS\n${customRules}` : "";
101
- const systemPrompt = `You are a Personal Information Organizer, specialized in accurately storing facts, user memories, and preferences. You are also an expert in job tasks extraction.
94
+ const systemPrompt = `You are a Personal Information Organizer, specialized in extracting and structuring user facts and preferences for AI personalization. You also handle explicit task extraction (todos only).
102
95
 
103
96
  Filter content before extracting triplets:
104
- - Relevance: keep only statements directly about the user (preferences, identity, actions, experiences) or explicit tasks; drop weather/small talk.
97
+ - Relevance: keep only statements directly about the user (preferences with the AI, identity relevant to personalization, actions/experiences that affect responses) or explicit todos; drop weather/small talk.
105
98
  - Disinterest: if the user rejects the topic (e.g., "cette information ne m'intéresse pas", "not interested"), return {"facts":[]}.
106
- - Business/procedures: if the user asks about processes, regulations, or third-party policies (company workflows, public steps, legal actions), classify as "procedural". This applies even if personal pronouns are used.
107
- - Action requests to the assistant (find/search/locate/call/email/book/reserve) are NOT preferences. Unless the user explicitly asks to save as a todo, do not create a memory for such requests (return {"facts":[]}).
108
-
109
- You must strictly extract {Subject, Predicate, Object} triplets by following these rules (max 12 triplets):
99
+ - Ignore business/process/regulation/company-policy content entirely (no extraction, no memory).
100
+ - Action requests to the assistant (find/search/locate/call/email/book/reserve) are NOT preferences. Unless the user explicitly asks to save as a todo, return {"facts":[]}.
101
+
102
+ You must strictly extract {Subject, Predicate, Object} triplets (max 12):
110
103
  1. Identify named entities, preferences, and meaningful user-related concepts:
111
- - Extract triplets that describe facts *about the user* based on their statements, covering areas like preferences, beliefs, actions, experiences, learning, identity, work, or relationships (e.g., "I love working").
112
- - Apply explicit, precise, and unambiguous predicates (e.g., "owns", "is located at", "is a", "has function", "causes", etc.).
113
- - Determine the triplet type ("assistant_preference", "procedural", "episodic", "factual", "todo"):
114
- - "assistant_preference": ONLY when the user specifies response style/language/format or interaction constraints.
115
- - "procedural": for how-to/business questions (e.g., « je veux résilier un bail, comment faire ? »).
116
- - "todo": ONLY if the user explicitly requests to save/keep as todo (e.g., « garde/enregistre en todo », « ajoute un todo »). Never infer todo from intent alone.
117
- - If multiple types apply (excluding assistant_preference and todo rules above), priority: procedural > episodic > factual.
118
- - "episodic" If a fact depends on a temporal, situational, or immediate personal context, then that fact AND ALL OF ITS sub-facts MUST be classified as episodic.
119
- - "procedural" for business processes (e.g., "Looking for customer John Doe address", "How to create a new contract").
120
- - "factual" for stable user data (except procedural that prevails).
121
-
122
- - Eliminate introductions, sub-facts, detailed repetitive elements, stylistic fillers, or vague statements. General facts always takes precedence over multiple sub-facts (signal vs noise).
123
- - The query intention can include specific preferences about how the Assistant should respond (e.g., "answer concisely", "explain in detail").
124
- - Compress each OUTPUT (fact and reason) 10 words.
125
- - Do not include type labels or annotations inside the fact text (e.g., avoid "(todo)", "(procedural)"). Use the separate 'type' field only.
126
- - DO NOT infer personal facts from third-party informations.
127
- - Treat "**ASSISTANT**:" as responses to enrich context of your reasoning process about the USER query.
128
- 2. Use pronoun "I" instead of "The user" in the subject of the triplet.
129
- 3. Do not output any facts already present in section # PRE-EXISTING FACTS.
130
- - If you find facts already present in section # PRE-EXISTING FACTS, use field "existing" to store them.
104
+ - Extract triplets *about the user* that help AI personalization (preferences, stable facts, explicit todos).
105
+ - Use explicit, precise, unambiguous predicates (e.g., "prefers", "speaks", "is a", "uses").
106
+ - Triplet type {"assistant_preference","factual","todo"} only:
107
+ - "assistant_preference": response style/language/format or interaction constraints.
108
+ - "factual": stable user data relevant to personalization (e.g., language, timezone, tools used).
109
+ - "todo": ONLY if the user explicitly asks to save/keep as todo. Never infer from intent alone.
110
+ - Remove introductions, sub-facts, repetitions, fillers, vague statements; prefer the general fact over details.
111
+ - Each triplet (S,P,O) 10 words total.
112
+ - Do not include type labels inside fact text; use the 'type' field only.
113
+ - Do not infer personal facts from third-party information.
114
+ - Treat "**ASSISTANT**:" as context only; never as a fact source.
115
+
116
+ 2. Use pronoun "I" as the Subject (not "The user").
117
+ 3. Do not output facts already in # PRE-EXISTING FACTS.
118
+ - If found, put them in "existing" (list of matched facts or IDs).
131
119
 
132
120
  ${injectCustomRules(customRules)}
133
121
 
@@ -153,46 +141,66 @@ export function getUpdateMemoryMessages(
153
141
  const serializeFacts = (facts: any[]) => {
154
142
  if(facts.length === 0) return "";
155
143
  if(facts[0].fact) {
156
- return facts.map((elem) => `* ${elem.fact} (${elem.type})`).join("\n");
144
+ return facts.map((elem) => `- "${elem.fact}" (type:${elem.type})`).join("\n");
157
145
  } else {
158
146
  return facts.join("\n");
159
147
  }
160
148
  }
161
149
  const serializeMemory = (memory: any[]) => {
162
- return memory.map((elem) => `* ${elem.id} - ${elem.text}`).join("\n");
150
+ return memory.map((elem) => `- "${elem.text}" (id:${elem.id})`).join("\n");
163
151
  }
164
152
  return `ROLE:
165
- You are a smart memory manager dedicated on users. You are expert in semantic comparison, RDF inference and boolean logic.
153
+ You are the Memory Manager module of an AI assistant. You are specialized in semantic reasoning, fact consistency, and memory lifecycle operations.
154
+ Your job is to maintain a coherent, contradiction-free knowledge base (long-term memory) of user facts.
166
155
 
167
156
  MISSION:
168
- For each new user fact from "# New Retrieved Facts", you MUSTmerge it into "# Current Memory" by assigning exactly ONE of: ADD, DELETE, UPDATE, or NONE:
169
-
170
- 1. Semantic compare each new facts to memory, for each fact:
171
- - If the new fact **contradicts**, **negates**, **reverses**, **retracts**, or **cancels** the meaning of a memory entry THEN DELETE.
172
- ⛔ You MUST NOT treat this as an UPDATE. Contradictions invalidate the original fact.
173
- - Else If the new fact **specializes** the previous fact (adds precision, extends the detail without changing the core meaning) THEN UPDATE.
174
- - Else If it is **equivalent** → NONE.
175
- - Else If it is **completely new** → ADD.
176
- - Else (default) NONE.
177
- 2. Event mapping from user intent (imperatives prevail):
178
- - DELETE if user asks to remove.
179
- - UPDATE if user asks to change: "mets à jour", "modifie", "corrige", "update", "change", "replace".
180
- - ADD if user asks to add: "ajoute", "add" (including explicit todo adds).
181
- 3. If no match is found:
182
- - Generate a new ID for ADD
183
- 5. Assign the action (IF you can't find a match, restart the process)
157
+ Given:
158
+ 1. A set of **Current Memory** facts (each with unique ID and textual content).
159
+ 2. A set of **New Retrieved Facts** from the user or external sources.
160
+ 3. (Optional) A **User Instruction** indicating explicit intent (add, modify, delete).
161
+
162
+ You must process each new fact individually and decide **exactly one** action: **ADD**, **DELETE**, **UPDATE**, or **NONE**, following these rules, in this order:
163
+
164
+ 1. **User intent override**
165
+ If the User Instruction clearly requests adding, updating, or removal (e.g. “ajoute X”, “mets à jour Y”, “supprime Z”), you **must** respect that and assign the corresponding action for the matching fact, superseding semantic rules.
166
+
167
+ 2. **Semantic consistency check**
168
+ For each new fact:
169
+ - If it **contradicts**, **negates**, or **cancels** an existing memory item, you **DELETE** the memory item.
170
+ - Else, if the new fact is a **specialization** (i.e. same core meaning + additional detail) of an existing one, **UPDATE** that memory (keeping the same ID).
171
+ - Else, if it is **semantically equivalent** (i.e. redundant or paraphrased), assign **NONE** (no change).
172
+ - Else, if it is entirely **new** (no overlap or relation), **ADD** it (generate a new ID).
173
+ - Otherwise (if ambiguous or borderline), assign **NONE** (do not delete).
174
+
175
+ 3. **ID reuse and consistency**
176
+ - For **UPDATE**, reuse the existing memory item’s ID.
177
+ - For **DELETE**, simply remove the item from the final memory output.
178
+ - For **ADD**, generate a new unique ID (e.g. UUID).
179
+ - If memory is initially empty, treat all new facts as **ADD**.
180
+
181
+ 4. **Output formatting**
182
+ Return the updated memory state in strict JSON format. Each memory entry must include:
183
+ - \`id\` (string)
184
+ - \`text\` (string, the pure factual content)
185
+ - Optionally for updates: \`old_text\` (the prior version)
186
+ - *(No extra annotation or type markup in \`text\`)*
187
+
188
+ If there are no facts at all, return \`{"memory": []}\`.
189
+
190
+ *You must not output any other text besides the valid JSON result.*
184
191
 
185
192
  # Output Instructions
186
- - Default user language is ${defaultLanguage}.
193
+ - Default user language is "${defaultLanguage}".
187
194
  - Each memory item must follow this strict format:
188
- - UPDATE also include the previous text: \`old_memory\`.
189
- - ⚠️ Reuse correct IDs for UPDATE and DELETE.
190
- - Generate random IDs for ADDs.
195
+ - UPDATE must also include the previous text: \`old_text\`.
196
+ - Reuse correct IDs for UPDATE.
197
+ - For DELETE, exclude the removed item from the final memory list.
198
+ - Generate random IDs for ADDs (format: UUID).
191
199
  - If memory is empty, treat all facts as ADD.
192
200
  - Without facts, return an empty memory: \`{"memory": []}\`
193
201
  - Memory must strictly reflect valid facts.
194
- - Contradictions, cancellations, negations, or ambiguities must be handled by DELETE.
195
- - The field 'text' must be the pure memory content only: do not add any type markers or parentheses like "(todo)".
202
+ - Contradictions, cancellations, or negations must be handled by DELETE. Ambiguities must be handled by NONE.
203
+ - The field 'text' must be the pure memory content only: do not add any type markers or parentheses.
196
204
 
197
205
  # Current Memory (extract and reuse their IDs for UPDATE or DELETE events):
198
206
  ${serializeMemory(retrievedOldMemory)}
@@ -200,8 +208,7 @@ ${serializeMemory(retrievedOldMemory)}
200
208
  # New Retrieved Facts:
201
209
  ${serializeFacts(newRetrievedFacts)}
202
210
 
203
- # User Instruction:
204
- ${userInstruction || ""}
211
+ # User Instruction: "${userInstruction || ''}"
205
212
 
206
213
  Return the updated memory in JSON format only. Do not output anything else.`;
207
214
  }
@@ -229,8 +236,9 @@ export const getMemoriesAsPrefix = (memories: MemoryItem[]) => {
229
236
  };
230
237
 
231
238
  export const getMemoriesAsSystem = (memories: MemoryItem[], facts?: string[]) => {
239
+ if(!memories || memories.length === 0) return "";
232
240
  const memoryString = memories.map((mem) => `- ${mem.memory}`).concat(facts||[]).join("\n");
233
- return `${MEMORY_STRING_SYSTEM}\n<memories>${memoryString}\n</memories>`;
241
+ return `${MEMORY_STRING_SYSTEM}\n<memories>\n${memoryString}\n</memories>`;
234
242
  }
235
243
 
236
244
  export function parseMessages(messages: string[]): string {
@@ -73,8 +73,6 @@ export interface MemoryTypeConfig {
73
73
 
74
74
  export interface MemoryScoringConfig {
75
75
  todo: MemoryTypeConfig;
76
- procedural: MemoryTypeConfig;
77
- episodic: MemoryTypeConfig;
78
76
  factual: MemoryTypeConfig;
79
77
  assistant_preference: MemoryTypeConfig;
80
78
  default: MemoryTypeConfig; // Fallback if type is missing or unknown
@@ -103,7 +101,7 @@ export interface MemoryConfig {
103
101
  enableGraph?: boolean;
104
102
  }
105
103
 
106
- export type MemoryType = 'procedural' | 'todo' | 'episodic' | 'factual' | 'assistant_preference';
104
+ export type MemoryType = 'todo' | 'factual' | 'assistant_preference';
107
105
 
108
106
  export interface MemoryItem {
109
107
  id: string;
@@ -170,18 +168,6 @@ export const MemoryConfigSchema = z.object({
170
168
  gamma: z.number(),
171
169
  halfLifeDays: z.number(),
172
170
  }),
173
- procedural: z.object({
174
- alpha: z.number(),
175
- beta: z.number(),
176
- gamma: z.number(),
177
- halfLifeDays: z.number(),
178
- }),
179
- episodic: z.object({
180
- alpha: z.number(),
181
- beta: z.number(),
182
- gamma: z.number(),
183
- halfLifeDays: z.number(),
184
- }),
185
171
  factual: z.object({
186
172
  alpha: z.number(),
187
173
  beta: z.number(),
@@ -40,7 +40,7 @@ describe("Memory Class facts regression tests", () => {
40
40
  expect(result.results.length).toBe(0);
41
41
  // expect(result.results[0]?.type).toBe("factual");
42
42
  });
43
- it("episodic: Je veux manger des sushis pour ma pause de midi.", async () => {
43
+ it("should not create memory for temporal events (episodic removed)", async () => {
44
44
  const customFacts = "Je suis Olivier Poulain\nIT et je travaille chez Immeuble SA";
45
45
  const result = (await memory.capture([
46
46
  {role:"user", content:"J'ai faim, je veux manger des sushis pour ma pause de midi."},
@@ -51,9 +51,8 @@ describe("Memory Class facts regression tests", () => {
51
51
 
52
52
  expect(result).toBeDefined();
53
53
  expect(result.results).toBeDefined();
54
- expect(result.results.length).toBeGreaterThan(1);
55
- expect(result.results[0]?.type).toBe("episodic");
56
- expect(result.results[1]?.type).toBe("episodic");
54
+ // Should not create memory for temporal events or action requests
55
+ expect(result.results.length).toBe(0);
57
56
  });
58
57
 
59
58
 
@@ -72,8 +71,7 @@ describe("Memory Class facts regression tests", () => {
72
71
  expect(result.results[0]?.type).toBe("assistant_preference");
73
72
  });
74
73
 
75
- it("business:je cherche le téléphone de mon client Alphonse MAGLOIRE", async () => {
76
- // type?: "factual" | "episodic" | "todo"|"procedural" | "assistant_preference";
74
+ it("business: should not create memory for business queries", async () => {
77
75
  // Capture a query that contains a name but is asking for contact information
78
76
  const result = (await memory.capture(
79
77
  "je cherche le téléphone de mon client Alphonse MAGLOIRE",
@@ -81,16 +79,15 @@ describe("Memory Class facts regression tests", () => {
81
79
  {},
82
80
  )) as SearchResult;
83
81
 
84
- // Verify no memory was created (business query)
82
+ // Verify no memory was created (business query - procedural removed)
85
83
  expect(result).toBeDefined();
86
84
  expect(result.results).toBeDefined();
87
85
  expect(Array.isArray(result.results)).toBe(true);
88
- expect(result.results.length).toBe(1);
89
- const type = result.results[0]?.type;
90
- expect(["procedural","episodic"].includes(type)).toBe(true);
86
+ // Business queries should not create memories anymore
87
+ expect(result.results.length).toBe(0);
91
88
  });
92
89
 
93
- it("business:Le logement de Alphonse MAGLOIRE au 5ème étage est de combien pièces", async () => {
90
+ it("business: should not create memory for business property questions", async () => {
94
91
  const result = (await memory.capture([
95
92
  {role:"user", content:"Le logement de Alphonse MAGLOIRE au 5ème étage est de combien pièces.",},
96
93
  {role:"assitant", content:"Alphonse MAGLOIRE a un logement de 4 pièces au 5ème étage",}],
@@ -100,35 +97,26 @@ describe("Memory Class facts regression tests", () => {
100
97
  expect(result).toBeDefined();
101
98
  expect(result.results).toBeDefined();
102
99
  expect(Array.isArray(result.results)).toBe(true);
103
- //
104
- // result can also be empty
105
- if(result.results.length > 0) {
106
- expect(result.results.length).toBe(1);
107
- expect(result.results[0]?.type).toBe("procedural");
108
- }
100
+ // Business information should not be stored (procedural removed)
101
+ expect(result.results.length).toBe(0);
109
102
  });
110
103
 
111
104
 
112
- it("business task are not factual (2)", async () => {
105
+ it("business: should not create memory for procedure questions", async () => {
113
106
  const result = (await memory.capture([
114
107
  {role:"user", content:"Quelle est la procédure pour résilier un bail chez Pouet & Compagnie SA ?"}],
115
108
  userId,
116
109
  {customFacts:"Je suis Olivier Poulain, Je m'occupe de la gérance locataire chez Immeuble SA"},
117
110
  )) as SearchResult;
118
111
 
119
-
120
112
  expect(result).toBeDefined();
121
113
  expect(result.results).toBeDefined();
122
114
  expect(Array.isArray(result.results)).toBe(true);
123
- //
124
- // result can also be empty
125
- if(result.results.length > 0) {
126
- expect(result.results.length).toBe(1);
127
- expect(result.results[0]?.type).toBe("procedural");
128
- }
115
+ // Procedure questions should not create memories (procedural removed)
116
+ expect(result.results.length).toBe(0);
129
117
  });
130
118
 
131
- it("business:Est-ce que Claude RIBUR est à jour avec son loyer ?", async () => {
119
+ it("business: should not create memory for client status queries", async () => {
132
120
  const result = (await memory.capture([
133
121
  {role:"user", content:"Est-ce que Claude RIBUR est à jour avec son loyer ?"}],
134
122
  userId,
@@ -137,10 +125,8 @@ describe("Memory Class facts regression tests", () => {
137
125
  expect(result).toBeDefined();
138
126
  expect(result.results).toBeDefined();
139
127
  expect(Array.isArray(result.results)).toBe(true);
140
- expect(result.results.length).toBe(1);
141
- expect(result.results[0]?.type).toBe("procedural");
142
-
143
-
128
+ // Business/client queries should not create memories (procedural removed)
129
+ expect(result.results.length).toBe(0);
144
130
  });
145
131
 
146
132
 
@@ -153,12 +139,33 @@ describe("Memory Class facts regression tests", () => {
153
139
  expect(result.results?.[0]?.id).toBeDefined();
154
140
  const memoryId = result.results[0]?.id;
155
141
  await memory.capture(
156
- "je ne veux plus que tu répondes en italien",
142
+ "je veux que tu répondes en français",
143
+ userId,
144
+ {},
145
+ ) as SearchResult;
146
+
147
+ const id = await memory.get(memoryId, userId);
148
+ console.log("-- DBG id:", id);
149
+ // expect(id).toBeNull();
150
+
151
+ });
152
+
153
+ it.skip("should add and remove a single memory", async () => {
154
+ const result = (await memory.capture(
155
+ "je veux que tu répondes en italien",
156
+ userId,
157
+ {},
158
+ )) as SearchResult;
159
+ expect(result.results?.[0]?.id).toBeDefined();
160
+ const memoryId = result.results[0]?.id;
161
+ await memory.capture(
162
+ "je ne veux plus que tu répondes en Italien",
157
163
  userId,
158
164
  {},
159
165
  ) as SearchResult;
160
166
 
161
167
  const id = await memory.get(memoryId, userId);
168
+ console.log("-- DBG id:", id);
162
169
  expect(id).toBeNull();
163
170
 
164
171
  });
@@ -49,7 +49,7 @@ describe("Memory Class TODO regression tests", () => {
49
49
  expect(result.results.every(r => r.type !== "todo")).toBe(true);
50
50
  });
51
51
 
52
- it("should classify a how-to business request as procedural", async () => {
52
+ it("should not create memory for how-to business requests (procedural removed)", async () => {
53
53
  const result = (await memory.capture([
54
54
  { role: "user", content: "Je veux résilier un bail, comment faire ?" },
55
55
  { role: "assistant", content: "Voici la procédure..." }
@@ -57,9 +57,8 @@ describe("Memory Class TODO regression tests", () => {
57
57
 
58
58
  expect(result).toBeDefined();
59
59
  expect(Array.isArray(result.results)).toBe(true);
60
- // Should capture a procedural fact, not a TODO
61
- expect(result.results.some(r => r.type === "procedural")).toBe(true);
62
- expect(result.results.every(r => r.type !== "todo")).toBe(true);
60
+ // Business procedures should not create memories (procedural type removed)
61
+ expect(result.results.length).toBe(0);
63
62
  });
64
63
 
65
64
  it("should add then update a TODO via new capture", async () => {