memories-lite 0.99.3 → 0.99.5
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.
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.js +30 -1
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +5 -1
- package/memories-lite-a42ac5108869b599bcbac21069f63fb47f07452fcc4b87e89b3c06a945612d0b.db +0 -0
- package/memories-lite-a9137698d8d3fdbf27efcdc8cd372084b52d484e8db866c5455bbb3f85299b54.db +0 -0
- package/package.json +1 -1
- package/src/memory/index.ts +37 -1
- package/src/types/index.ts +16 -0
- package/tests/memory.applymode.test.ts +228 -0
package/dist/memory/index.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare class MemoriesLite {
|
|
|
33
33
|
capture(messages: string | Message[], userId: string, config: AddMemoryOptions): Promise<SearchResult>;
|
|
34
34
|
get(memoryId: string, userId: string): Promise<MemoryItem | null>;
|
|
35
35
|
retrieve(query: string, userId: string, config: SearchMemoryOptions): Promise<SearchResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Met à jour une mémoire existante
|
|
38
|
+
* @param memoryId - ID de la mémoire
|
|
39
|
+
* @param data - Nouveau contenu
|
|
40
|
+
* @param userId - ID utilisateur
|
|
41
|
+
* @param metadata - Métadonnées optionnelles (peut inclure applyMode pour changer le mode)
|
|
42
|
+
*/
|
|
36
43
|
update(memoryId: string, data: string, userId: string, metadata?: Record<string, any>): Promise<{
|
|
37
44
|
message: string;
|
|
38
45
|
}>;
|
package/dist/memory/index.js
CHANGED
|
@@ -132,11 +132,14 @@ class MemoriesLite {
|
|
|
132
132
|
const embedding = await this.embedder.embed(title);
|
|
133
133
|
//
|
|
134
134
|
// Préparer les métadonnées
|
|
135
|
+
// applyMode par défaut = MEM_SMART (recherche sémantique)
|
|
135
136
|
const memoryType = metadata.type || 'discussion';
|
|
137
|
+
const applyMode = metadata.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE;
|
|
136
138
|
const memoryMetadata = {
|
|
137
139
|
...metadata,
|
|
138
140
|
title,
|
|
139
141
|
type: memoryType,
|
|
142
|
+
applyMode,
|
|
140
143
|
userId,
|
|
141
144
|
};
|
|
142
145
|
//
|
|
@@ -203,6 +206,7 @@ class MemoriesLite {
|
|
|
203
206
|
id: memory.id,
|
|
204
207
|
memory: memory.payload.data,
|
|
205
208
|
type: memory.payload.type,
|
|
209
|
+
applyMode: memory.payload.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE,
|
|
206
210
|
hash: memory.payload.hash,
|
|
207
211
|
createdAt: memory.payload.createdAt,
|
|
208
212
|
updatedAt: memory.payload.updatedAt,
|
|
@@ -252,12 +256,21 @@ class MemoriesLite {
|
|
|
252
256
|
"data",
|
|
253
257
|
"createdAt",
|
|
254
258
|
"updatedAt",
|
|
259
|
+
"applyMode",
|
|
255
260
|
]);
|
|
256
|
-
|
|
261
|
+
//
|
|
262
|
+
// Filtrer uniquement les mémoires avec applyMode = MEM_SMART (recherche sémantique)
|
|
263
|
+
// Les MEM_ALWAYS et MEM_MANUAL ne sont pas retournées par retrieve()
|
|
264
|
+
const filteredMemories = memories.filter((mem) => {
|
|
265
|
+
const mode = mem.payload.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE;
|
|
266
|
+
return mode === 'MEM_SMART';
|
|
267
|
+
});
|
|
268
|
+
const results = filteredMemories.map((mem) => ({
|
|
257
269
|
id: mem.id,
|
|
258
270
|
memory: mem.payload.data,
|
|
259
271
|
hash: mem.payload.hash,
|
|
260
272
|
type: mem.payload.type,
|
|
273
|
+
applyMode: mem.payload.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE,
|
|
261
274
|
createdAt: mem.payload.createdAt,
|
|
262
275
|
updatedAt: mem.payload.updatedAt,
|
|
263
276
|
score: mem.score,
|
|
@@ -271,6 +284,13 @@ class MemoriesLite {
|
|
|
271
284
|
results,
|
|
272
285
|
};
|
|
273
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Met à jour une mémoire existante
|
|
289
|
+
* @param memoryId - ID de la mémoire
|
|
290
|
+
* @param data - Nouveau contenu
|
|
291
|
+
* @param userId - ID utilisateur
|
|
292
|
+
* @param metadata - Métadonnées optionnelles (peut inclure applyMode pour changer le mode)
|
|
293
|
+
*/
|
|
274
294
|
async update(memoryId, data, userId, metadata = {}) {
|
|
275
295
|
// await this._captureEvent("update", { memory_id: memoryId });
|
|
276
296
|
const embedding = await this.embedder.embed(data);
|
|
@@ -350,12 +370,14 @@ class MemoriesLite {
|
|
|
350
370
|
"data",
|
|
351
371
|
"createdAt",
|
|
352
372
|
"updatedAt",
|
|
373
|
+
"applyMode",
|
|
353
374
|
]);
|
|
354
375
|
const results = memories.map((mem) => ({
|
|
355
376
|
id: mem.id,
|
|
356
377
|
memory: mem.payload.data,
|
|
357
378
|
hash: mem.payload.hash,
|
|
358
379
|
type: mem.payload.type,
|
|
380
|
+
applyMode: mem.payload.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE,
|
|
359
381
|
createdAt: mem.payload.createdAt,
|
|
360
382
|
updatedAt: mem.payload.updatedAt,
|
|
361
383
|
metadata: Object.entries(mem.payload)
|
|
@@ -393,16 +415,23 @@ class MemoriesLite {
|
|
|
393
415
|
//
|
|
394
416
|
// Preserve origin fields to avoid corrupting ownership/linkage (discussionId/userId/agentId).
|
|
395
417
|
// - title: keep original unless explicitly changed
|
|
418
|
+
// - applyMode: keep original unless explicitly changed
|
|
396
419
|
// - discussionId, userId, agentId/runId: always keep original
|
|
397
420
|
const title = (typeof metadata.title === "string" && metadata.title.trim())
|
|
398
421
|
? metadata.title.trim()
|
|
399
422
|
: originalPayload.title;
|
|
423
|
+
//
|
|
424
|
+
// applyMode: si fourni dans metadata, on le prend, sinon on garde l'original ou le défaut
|
|
425
|
+
const applyMode = (metadata.applyMode && ['MEM_ALWAYS', 'MEM_SMART', 'MEM_MANUAL'].includes(metadata.applyMode))
|
|
426
|
+
? metadata.applyMode
|
|
427
|
+
: (originalPayload.applyMode || types_1.DEFAULT_MEMORY_APPLY_MODE);
|
|
400
428
|
const newMetadata = {
|
|
401
429
|
...originalPayload,
|
|
402
430
|
data,
|
|
403
431
|
hash: (0, crypto_1.createHash)("md5").update(data).digest("hex"),
|
|
404
432
|
updatedAt: new Date().toISOString(),
|
|
405
433
|
title: title,
|
|
434
|
+
applyMode,
|
|
406
435
|
};
|
|
407
436
|
await vectorStore.update(memoryId, embedding, newMetadata);
|
|
408
437
|
await this.db.addHistory(memoryId, prevValue, data, "UPDATE", newMetadata.createdAt, newMetadata.updatedAt);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -77,10 +77,24 @@ export interface MemoryConfig {
|
|
|
77
77
|
capturePrompt?: string;
|
|
78
78
|
}
|
|
79
79
|
export type MemoryType = 'assistant_preference' | 'discussion';
|
|
80
|
+
/**
|
|
81
|
+
* Mode d'application de la mémoire (inspiré de Cursor AI)
|
|
82
|
+
* Stocké dans metadata.applyMode avec préfixe MEM_* pour migration soft
|
|
83
|
+
*
|
|
84
|
+
* - MEM_ALWAYS: Toujours appliquer - la mémoire est toujours injectée dans le contexte
|
|
85
|
+
* - MEM_SMART: Appliquer intelligemment - utilisé pour la recherche sémantique (défaut)
|
|
86
|
+
* - MEM_MANUAL: Appliquer manuellement - la mémoire n'est jamais injectée automatiquement
|
|
87
|
+
*/
|
|
88
|
+
export type MemoryApplyMode = 'MEM_ALWAYS' | 'MEM_SMART' | 'MEM_MANUAL';
|
|
89
|
+
/**
|
|
90
|
+
* Mode par défaut pour la capture
|
|
91
|
+
*/
|
|
92
|
+
export declare const DEFAULT_MEMORY_APPLY_MODE: MemoryApplyMode;
|
|
80
93
|
export interface MemoryItem {
|
|
81
94
|
id: string;
|
|
82
95
|
memory: string;
|
|
83
96
|
type: MemoryType;
|
|
97
|
+
applyMode?: MemoryApplyMode;
|
|
84
98
|
event?: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
85
99
|
hash?: string;
|
|
86
100
|
createdAt?: string;
|
package/dist/types/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MemoryConfigSchema = void 0;
|
|
3
|
+
exports.MemoryConfigSchema = exports.DEFAULT_MEMORY_APPLY_MODE = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Mode par défaut pour la capture
|
|
7
|
+
*/
|
|
8
|
+
exports.DEFAULT_MEMORY_APPLY_MODE = 'MEM_SMART';
|
|
5
9
|
exports.MemoryConfigSchema = zod_1.z.object({
|
|
6
10
|
version: zod_1.z.string().optional(),
|
|
7
11
|
embedder: zod_1.z.object({
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/memory/index.ts
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
MemoryConfigSchema,
|
|
6
6
|
MemoryItem,
|
|
7
7
|
MemoryType,
|
|
8
|
+
MemoryApplyMode,
|
|
9
|
+
DEFAULT_MEMORY_APPLY_MODE,
|
|
8
10
|
Message,
|
|
9
11
|
SearchFilters,
|
|
10
12
|
SearchResult,
|
|
@@ -208,11 +210,14 @@ export class MemoriesLite {
|
|
|
208
210
|
|
|
209
211
|
//
|
|
210
212
|
// Préparer les métadonnées
|
|
213
|
+
// applyMode par défaut = MEM_SMART (recherche sémantique)
|
|
211
214
|
const memoryType: MemoryType = metadata.type || 'discussion';
|
|
215
|
+
const applyMode: MemoryApplyMode = metadata.applyMode || DEFAULT_MEMORY_APPLY_MODE;
|
|
212
216
|
const memoryMetadata = {
|
|
213
217
|
...metadata,
|
|
214
218
|
title,
|
|
215
219
|
type: memoryType,
|
|
220
|
+
applyMode,
|
|
216
221
|
userId,
|
|
217
222
|
};
|
|
218
223
|
|
|
@@ -315,6 +320,7 @@ export class MemoriesLite {
|
|
|
315
320
|
id: memory.id,
|
|
316
321
|
memory: memory.payload.data,
|
|
317
322
|
type: memory.payload.type,
|
|
323
|
+
applyMode: memory.payload.applyMode || DEFAULT_MEMORY_APPLY_MODE,
|
|
318
324
|
hash: memory.payload.hash,
|
|
319
325
|
createdAt: memory.payload.createdAt,
|
|
320
326
|
updatedAt: memory.payload.updatedAt,
|
|
@@ -382,12 +388,23 @@ export class MemoriesLite {
|
|
|
382
388
|
"data",
|
|
383
389
|
"createdAt",
|
|
384
390
|
"updatedAt",
|
|
391
|
+
"applyMode",
|
|
385
392
|
]);
|
|
386
|
-
|
|
393
|
+
|
|
394
|
+
//
|
|
395
|
+
// Filtrer uniquement les mémoires avec applyMode = MEM_SMART (recherche sémantique)
|
|
396
|
+
// Les MEM_ALWAYS et MEM_MANUAL ne sont pas retournées par retrieve()
|
|
397
|
+
const filteredMemories = memories.filter((mem) => {
|
|
398
|
+
const mode = mem.payload.applyMode || DEFAULT_MEMORY_APPLY_MODE;
|
|
399
|
+
return mode === 'MEM_SMART';
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
const results = filteredMemories.map((mem) => ({
|
|
387
403
|
id: mem.id,
|
|
388
404
|
memory: mem.payload.data,
|
|
389
405
|
hash: mem.payload.hash,
|
|
390
406
|
type: mem.payload.type,
|
|
407
|
+
applyMode: mem.payload.applyMode || DEFAULT_MEMORY_APPLY_MODE,
|
|
391
408
|
createdAt: mem.payload.createdAt,
|
|
392
409
|
updatedAt: mem.payload.updatedAt,
|
|
393
410
|
score: mem.score,
|
|
@@ -403,6 +420,13 @@ export class MemoriesLite {
|
|
|
403
420
|
};
|
|
404
421
|
}
|
|
405
422
|
|
|
423
|
+
/**
|
|
424
|
+
* Met à jour une mémoire existante
|
|
425
|
+
* @param memoryId - ID de la mémoire
|
|
426
|
+
* @param data - Nouveau contenu
|
|
427
|
+
* @param userId - ID utilisateur
|
|
428
|
+
* @param metadata - Métadonnées optionnelles (peut inclure applyMode pour changer le mode)
|
|
429
|
+
*/
|
|
406
430
|
async update(
|
|
407
431
|
memoryId: string,
|
|
408
432
|
data: string,
|
|
@@ -506,12 +530,14 @@ export class MemoriesLite {
|
|
|
506
530
|
"data",
|
|
507
531
|
"createdAt",
|
|
508
532
|
"updatedAt",
|
|
533
|
+
"applyMode",
|
|
509
534
|
]);
|
|
510
535
|
const results = memories.map((mem) => ({
|
|
511
536
|
id: mem.id,
|
|
512
537
|
memory: mem.payload.data,
|
|
513
538
|
hash: mem.payload.hash,
|
|
514
539
|
type: mem.payload.type,
|
|
540
|
+
applyMode: mem.payload.applyMode || DEFAULT_MEMORY_APPLY_MODE,
|
|
515
541
|
createdAt: mem.payload.createdAt,
|
|
516
542
|
updatedAt: mem.payload.updatedAt,
|
|
517
543
|
metadata: Object.entries(mem.payload)
|
|
@@ -576,17 +602,27 @@ export class MemoriesLite {
|
|
|
576
602
|
//
|
|
577
603
|
// Preserve origin fields to avoid corrupting ownership/linkage (discussionId/userId/agentId).
|
|
578
604
|
// - title: keep original unless explicitly changed
|
|
605
|
+
// - applyMode: keep original unless explicitly changed
|
|
579
606
|
// - discussionId, userId, agentId/runId: always keep original
|
|
580
607
|
const title =
|
|
581
608
|
(typeof metadata.title === "string" && metadata.title.trim())
|
|
582
609
|
? metadata.title.trim()
|
|
583
610
|
: originalPayload.title;
|
|
611
|
+
|
|
612
|
+
//
|
|
613
|
+
// applyMode: si fourni dans metadata, on le prend, sinon on garde l'original ou le défaut
|
|
614
|
+
const applyMode: MemoryApplyMode =
|
|
615
|
+
(metadata.applyMode && ['MEM_ALWAYS', 'MEM_SMART', 'MEM_MANUAL'].includes(metadata.applyMode))
|
|
616
|
+
? metadata.applyMode
|
|
617
|
+
: (originalPayload.applyMode || DEFAULT_MEMORY_APPLY_MODE);
|
|
618
|
+
|
|
584
619
|
const newMetadata: Record<string, any> = {
|
|
585
620
|
...originalPayload,
|
|
586
621
|
data,
|
|
587
622
|
hash: createHash("md5").update(data).digest("hex"),
|
|
588
623
|
updatedAt: new Date().toISOString(),
|
|
589
624
|
title: title,
|
|
625
|
+
applyMode,
|
|
590
626
|
};
|
|
591
627
|
|
|
592
628
|
await vectorStore.update(memoryId, embedding, newMetadata);
|
package/src/types/index.ts
CHANGED
|
@@ -88,10 +88,26 @@ export interface MemoryConfig {
|
|
|
88
88
|
|
|
89
89
|
export type MemoryType = 'assistant_preference' | 'discussion';
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Mode d'application de la mémoire (inspiré de Cursor AI)
|
|
93
|
+
* Stocké dans metadata.applyMode avec préfixe MEM_* pour migration soft
|
|
94
|
+
*
|
|
95
|
+
* - MEM_ALWAYS: Toujours appliquer - la mémoire est toujours injectée dans le contexte
|
|
96
|
+
* - MEM_SMART: Appliquer intelligemment - utilisé pour la recherche sémantique (défaut)
|
|
97
|
+
* - MEM_MANUAL: Appliquer manuellement - la mémoire n'est jamais injectée automatiquement
|
|
98
|
+
*/
|
|
99
|
+
export type MemoryApplyMode = 'MEM_ALWAYS' | 'MEM_SMART' | 'MEM_MANUAL';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Mode par défaut pour la capture
|
|
103
|
+
*/
|
|
104
|
+
export const DEFAULT_MEMORY_APPLY_MODE: MemoryApplyMode = 'MEM_SMART';
|
|
105
|
+
|
|
91
106
|
export interface MemoryItem {
|
|
92
107
|
id: string;
|
|
93
108
|
memory: string;
|
|
94
109
|
type: MemoryType;
|
|
110
|
+
applyMode?: MemoryApplyMode;
|
|
95
111
|
event?: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
96
112
|
hash?: string;
|
|
97
113
|
createdAt?: string;
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/// <reference types="jest" />
|
|
2
|
+
import { MemoriesLite, DEFAULT_MEMORY_APPLY_MODE, MemoryApplyMode } 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);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tests pour le MemoryApplyMode (type d'application de mémoire)
|
|
13
|
+
* - MEM_ALWAYS: Toujours appliquer
|
|
14
|
+
* - MEM_SMART: Appliquer intelligemment (défaut, recherche sémantique)
|
|
15
|
+
* - MEM_MANUAL: Appliquer manuellement
|
|
16
|
+
*/
|
|
17
|
+
describe("Memory ApplyMode", () => {
|
|
18
|
+
let memory: MemoriesLite;
|
|
19
|
+
let userId: string;
|
|
20
|
+
|
|
21
|
+
beforeEach(async () => {
|
|
22
|
+
({ memory, userId } = createTestMemory({}));
|
|
23
|
+
await memory.reset(userId);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(async () => {
|
|
27
|
+
await memory.reset(userId);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("Default ApplyMode", () => {
|
|
31
|
+
it("should set applyMode to MEM_SMART by default on capture", async () => {
|
|
32
|
+
//
|
|
33
|
+
// Capture une discussion avec le mode par défaut
|
|
34
|
+
const messages = [
|
|
35
|
+
{ role: "user", content: "Bonjour, comment gérer les congés ?" },
|
|
36
|
+
{ role: "assistant", content: "Pour gérer les congés, vous devez..." }
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const result = await memory.capture(messages, userId, {
|
|
40
|
+
metadata: { type: "discussion" }
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
expect(result.results.length).toBeGreaterThan(0);
|
|
44
|
+
const createdMemory = result.results[0];
|
|
45
|
+
|
|
46
|
+
//
|
|
47
|
+
// Vérifier que le mode par défaut est MEM_SMART
|
|
48
|
+
expect(createdMemory.metadata?.applyMode || DEFAULT_MEMORY_APPLY_MODE).toBe("MEM_SMART");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should return DEFAULT_MEMORY_APPLY_MODE as MEM_SMART", () => {
|
|
52
|
+
expect(DEFAULT_MEMORY_APPLY_MODE).toBe("MEM_SMART");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("ApplyMode Update", () => {
|
|
57
|
+
it("should update applyMode when specified in metadata", async () => {
|
|
58
|
+
//
|
|
59
|
+
// Créer une mémoire avec le mode par défaut
|
|
60
|
+
const messages = [
|
|
61
|
+
{ role: "user", content: "Comment faire une facture ?" },
|
|
62
|
+
{ role: "assistant", content: "Pour créer une facture..." }
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const result = await memory.capture(messages, userId, {
|
|
66
|
+
metadata: { type: "discussion" }
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(result.results.length).toBeGreaterThan(0);
|
|
70
|
+
const memoryId = result.results[0].id;
|
|
71
|
+
|
|
72
|
+
//
|
|
73
|
+
// Mettre à jour avec un nouveau mode
|
|
74
|
+
await memory.update(
|
|
75
|
+
memoryId,
|
|
76
|
+
"Procédure de facturation mise à jour",
|
|
77
|
+
userId,
|
|
78
|
+
{ applyMode: "MEM_ALWAYS" as MemoryApplyMode }
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
//
|
|
82
|
+
// Vérifier que le mode a été mis à jour
|
|
83
|
+
const updatedMemory = await memory.get(memoryId, userId);
|
|
84
|
+
expect(updatedMemory).not.toBeNull();
|
|
85
|
+
expect(updatedMemory?.applyMode).toBe("MEM_ALWAYS");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should preserve applyMode when not specified in update metadata", async () => {
|
|
89
|
+
//
|
|
90
|
+
// Créer une mémoire avec un mode spécifique
|
|
91
|
+
const messages = [
|
|
92
|
+
{ role: "user", content: "Règles de sécurité" },
|
|
93
|
+
{ role: "assistant", content: "Les règles de sécurité sont..." }
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
const result = await memory.capture(messages, userId, {
|
|
97
|
+
metadata: { type: "discussion", applyMode: "MEM_MANUAL" }
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(result.results.length).toBeGreaterThan(0);
|
|
101
|
+
const memoryId = result.results[0].id;
|
|
102
|
+
|
|
103
|
+
//
|
|
104
|
+
// Mettre à jour le contenu sans changer le mode
|
|
105
|
+
await memory.update(
|
|
106
|
+
memoryId,
|
|
107
|
+
"Règles de sécurité mises à jour",
|
|
108
|
+
userId,
|
|
109
|
+
{} // Pas de applyMode dans les metadata
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
//
|
|
113
|
+
// Vérifier que le mode est préservé
|
|
114
|
+
const updatedMemory = await memory.get(memoryId, userId);
|
|
115
|
+
expect(updatedMemory).not.toBeNull();
|
|
116
|
+
expect(updatedMemory?.applyMode).toBe("MEM_MANUAL");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should change applyMode from MEM_SMART to MEM_MANUAL", async () => {
|
|
120
|
+
//
|
|
121
|
+
// Créer une mémoire avec le mode par défaut
|
|
122
|
+
const messages = [
|
|
123
|
+
{ role: "user", content: "Comment utiliser l'API ?" },
|
|
124
|
+
{ role: "assistant", content: "L'API s'utilise de la manière suivante..." }
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const result = await memory.capture(messages, userId, {
|
|
128
|
+
metadata: { type: "discussion" }
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const memoryId = result.results[0].id;
|
|
132
|
+
|
|
133
|
+
//
|
|
134
|
+
// Changer de MEM_SMART vers MEM_MANUAL
|
|
135
|
+
await memory.update(
|
|
136
|
+
memoryId,
|
|
137
|
+
"Documentation API mise à jour",
|
|
138
|
+
userId,
|
|
139
|
+
{ applyMode: "MEM_MANUAL" as MemoryApplyMode }
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const updatedMemory = await memory.get(memoryId, userId);
|
|
143
|
+
expect(updatedMemory?.applyMode).toBe("MEM_MANUAL");
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("Retrieve Filtering by ApplyMode", () => {
|
|
148
|
+
it("should only return MEM_SMART memories in retrieve()", async () => {
|
|
149
|
+
//
|
|
150
|
+
// Créer 3 mémoires avec différents modes
|
|
151
|
+
const messagesBase = [
|
|
152
|
+
{ role: "user", content: "Question sur les procédures" },
|
|
153
|
+
{ role: "assistant", content: "Les procédures sont..." }
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
//
|
|
157
|
+
// Mémoire 1: MEM_SMART (par défaut)
|
|
158
|
+
await memory.capture(messagesBase, userId, {
|
|
159
|
+
metadata: { type: "discussion", customTag: "smart" }
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
//
|
|
163
|
+
// Mémoire 2: MEM_ALWAYS
|
|
164
|
+
await memory.capture([
|
|
165
|
+
{ role: "user", content: "Règle toujours appliquée" },
|
|
166
|
+
{ role: "assistant", content: "Cette règle est toujours appliquée..." }
|
|
167
|
+
], userId, {
|
|
168
|
+
metadata: { type: "discussion", applyMode: "MEM_ALWAYS", customTag: "always" }
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
//
|
|
172
|
+
// Mémoire 3: MEM_MANUAL
|
|
173
|
+
await memory.capture([
|
|
174
|
+
{ role: "user", content: "Note manuelle" },
|
|
175
|
+
{ role: "assistant", content: "Ceci est une note manuelle..." }
|
|
176
|
+
], userId, {
|
|
177
|
+
metadata: { type: "discussion", applyMode: "MEM_MANUAL", customTag: "manual" }
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
//
|
|
181
|
+
// Vérifier que getAll retourne les 3 mémoires
|
|
182
|
+
const allMemories = await memory.getAll(userId, { type: "discussion" });
|
|
183
|
+
expect(allMemories.results.length).toBe(3);
|
|
184
|
+
|
|
185
|
+
//
|
|
186
|
+
// Vérifier que retrieve() ne retourne que MEM_SMART
|
|
187
|
+
const searchResult = await memory.retrieve("procédures", userId, { limit: 10 });
|
|
188
|
+
|
|
189
|
+
//
|
|
190
|
+
// Seule la mémoire MEM_SMART devrait être retournée
|
|
191
|
+
const smartMemories = searchResult.results.filter(m => m.applyMode === "MEM_SMART");
|
|
192
|
+
const nonSmartMemories = searchResult.results.filter(m => m.applyMode !== "MEM_SMART");
|
|
193
|
+
|
|
194
|
+
expect(smartMemories.length).toBeGreaterThanOrEqual(0);
|
|
195
|
+
expect(nonSmartMemories.length).toBe(0);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe("GetAll returns all ApplyModes", () => {
|
|
200
|
+
it("should return memories of all applyModes in getAll()", async () => {
|
|
201
|
+
//
|
|
202
|
+
// Créer des mémoires avec différents modes
|
|
203
|
+
await memory.capture([
|
|
204
|
+
{ role: "user", content: "Mémoire intelligente" },
|
|
205
|
+
{ role: "assistant", content: "Réponse intelligente" }
|
|
206
|
+
], userId, {
|
|
207
|
+
metadata: { type: "discussion" } // MEM_SMART par défaut
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
await memory.capture([
|
|
211
|
+
{ role: "user", content: "Mémoire toujours" },
|
|
212
|
+
{ role: "assistant", content: "Réponse toujours" }
|
|
213
|
+
], userId, {
|
|
214
|
+
metadata: { type: "discussion", applyMode: "MEM_ALWAYS" }
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
//
|
|
218
|
+
// getAll doit retourner les deux
|
|
219
|
+
const allMemories = await memory.getAll(userId, { type: "discussion" });
|
|
220
|
+
expect(allMemories.results.length).toBe(2);
|
|
221
|
+
|
|
222
|
+
const modes = allMemories.results.map(m => m.applyMode);
|
|
223
|
+
expect(modes).toContain("MEM_SMART");
|
|
224
|
+
expect(modes).toContain("MEM_ALWAYS");
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|