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.
- package/dist/config/defaults.js +3 -5
- package/dist/config/manager.js +0 -4
- package/dist/memory/index.js +2 -1
- package/dist/prompts/index.d.ts +12 -13
- package/dist/prompts/index.js +80 -71
- package/dist/types/index.d.ts +1 -219
- package/dist/types/index.js +0 -12
- package/memories-lite-a42ac5108869b599bcbac21069f63fb47f07452fcc4b87e89b3c06a945612d0b.db +0 -0
- package/memories-lite-a9137698d8d3fdbf27efcdc8cd372084b52d484e8db866c5455bbb3f85299b54.db +0 -0
- package/package.json +1 -1
- package/src/config/defaults.ts +3 -5
- package/src/config/manager.ts +0 -4
- package/src/memory/index.ts +2 -1
- package/src/prompts/index.ts +79 -71
- package/src/types/index.ts +1 -15
- package/tests/memory.facts.test.ts +38 -31
- package/tests/memory.todo.test.ts +3 -4
package/dist/config/defaults.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEFAULT_MEMORY_CONFIG = void 0;
|
|
4
4
|
const DEFAULT_SCORING_CONFIG = {
|
|
5
|
-
//
|
|
6
|
-
procedural: { alpha: 0.30, beta: 0.40, gamma: 0.05, halfLifeDays: 1 / 24 }, // ~1 hour
|
|
7
|
-
episodic: { alpha: 0.40, beta: 0.50, gamma: 0.10, halfLifeDays: 2 }, // ~2 days (user request 'temporary')
|
|
5
|
+
// Focused on user preferences with AI - removed episodic and procedural memories
|
|
8
6
|
todo: { alpha: 0.40, beta: 0.50, gamma: 0.10, halfLifeDays: 40 }, // ~40 days
|
|
9
7
|
factual: { alpha: 0.70, beta: 0.20, gamma: 0.10, halfLifeDays: 150 }, // ~150 days
|
|
10
8
|
assistant_preference: { alpha: 0.60, beta: 0.05, gamma: 0.35, halfLifeDays: Infinity },
|
|
@@ -34,7 +32,7 @@ exports.DEFAULT_MEMORY_CONFIG = {
|
|
|
34
32
|
provider: "openai",
|
|
35
33
|
config: {
|
|
36
34
|
apiKey: process.env.OPENAI_API_KEY || "",
|
|
37
|
-
model: "gpt-5-
|
|
35
|
+
model: "gpt-5-mini",
|
|
38
36
|
modelProperties: undefined,
|
|
39
37
|
},
|
|
40
38
|
},
|
|
@@ -48,7 +46,7 @@ exports.DEFAULT_MEMORY_CONFIG = {
|
|
|
48
46
|
llm: {
|
|
49
47
|
provider: "openai",
|
|
50
48
|
config: {
|
|
51
|
-
model: "gpt-5-
|
|
49
|
+
model: "gpt-5-mini",
|
|
52
50
|
},
|
|
53
51
|
},
|
|
54
52
|
},
|
package/dist/config/manager.js
CHANGED
|
@@ -48,8 +48,6 @@ class ConfigManager {
|
|
|
48
48
|
// Merge scoring deeply if present in userConf, otherwise use default
|
|
49
49
|
scoring: userConf.scoring ? {
|
|
50
50
|
todo: { ...defaultConf.scoring?.todo, ...userConf.scoring.todo },
|
|
51
|
-
procedural: { ...defaultConf.scoring?.procedural, ...userConf.scoring.procedural },
|
|
52
|
-
episodic: { ...defaultConf.scoring?.episodic, ...userConf.scoring.episodic },
|
|
53
51
|
factual: { ...defaultConf.scoring?.factual, ...userConf.scoring.factual },
|
|
54
52
|
assistant_preference: { ...defaultConf.scoring?.assistant_preference, ...userConf.scoring.assistant_preference },
|
|
55
53
|
default: { ...defaultConf.scoring?.default, ...userConf.scoring.default },
|
|
@@ -66,8 +64,6 @@ class ConfigManager {
|
|
|
66
64
|
// Merge scoring deeply if present in userConf, otherwise use default
|
|
67
65
|
scoring: userConf?.scoring ? {
|
|
68
66
|
todo: { ...defaultConf.scoring?.todo, ...userConf.scoring.todo },
|
|
69
|
-
procedural: { ...defaultConf.scoring?.procedural, ...userConf.scoring.procedural },
|
|
70
|
-
episodic: { ...defaultConf.scoring?.episodic, ...userConf.scoring.episodic },
|
|
71
67
|
factual: { ...defaultConf.scoring?.factual, ...userConf.scoring.factual },
|
|
72
68
|
assistant_preference: { ...defaultConf.scoring?.assistant_preference, ...userConf.scoring.assistant_preference },
|
|
73
69
|
default: { ...defaultConf.scoring?.default, ...userConf.scoring.default },
|
package/dist/memory/index.js
CHANGED
|
@@ -121,7 +121,7 @@ class MemoriesLite {
|
|
|
121
121
|
// can use native structured output
|
|
122
122
|
// Drop factual facts at capture level (do not store factual memories)
|
|
123
123
|
// FIXME Drop factual should be done at prompt level
|
|
124
|
-
const facts = parsedResponse(response).facts?.filter((f) => !f.existing
|
|
124
|
+
const facts = parsedResponse(response).facts?.filter((f) => !f.existing) || [];
|
|
125
125
|
// console.log("-- DBG extract:", userPrompt);
|
|
126
126
|
// console.log("-- DBG facts:", facts);
|
|
127
127
|
// Get embeddings for new facts
|
|
@@ -153,6 +153,7 @@ class MemoriesLite {
|
|
|
153
153
|
const lastUserMessage = [...messages].reverse().find(m => m.role === 'user');
|
|
154
154
|
const userInstruction = typeof lastUserMessage?.content === 'string' ? lastUserMessage?.content : '';
|
|
155
155
|
const updatePrompt = (0, prompts_1.getUpdateMemoryMessages)(uniqueOldMemories, facts, 'French', userInstruction);
|
|
156
|
+
// console.log("-- DBG updatePrompt:", updatePrompt);
|
|
156
157
|
const updateResponse = await this.llm.generateResponse([{ role: "user", content: updatePrompt }], { ...(0, zod_1.zodResponseFormat)(prompts_1.MemoryUpdateSchema, "Memory") }, [], false);
|
|
157
158
|
// console.log("-- DBG merge:", updatePrompt);
|
|
158
159
|
const memoryActions = parsedResponse(updateResponse).memory || [];
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -11,25 +11,25 @@ export declare const FactRetrievalSchema_extended: z.ZodObject<{
|
|
|
11
11
|
facts: z.ZodArray<z.ZodObject<{
|
|
12
12
|
fact: z.ZodString;
|
|
13
13
|
existing: z.ZodBoolean;
|
|
14
|
-
type: z.ZodEnum<["assistant_preference", "factual", "
|
|
14
|
+
type: z.ZodEnum<["assistant_preference", "factual", "todo"]>;
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
|
-
type: "
|
|
16
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
17
17
|
fact: string;
|
|
18
18
|
existing: boolean;
|
|
19
19
|
}, {
|
|
20
|
-
type: "
|
|
20
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
21
21
|
fact: string;
|
|
22
22
|
existing: boolean;
|
|
23
23
|
}>, "many">;
|
|
24
24
|
}, "strip", z.ZodTypeAny, {
|
|
25
25
|
facts: {
|
|
26
|
-
type: "
|
|
26
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
27
27
|
fact: string;
|
|
28
28
|
existing: boolean;
|
|
29
29
|
}[];
|
|
30
30
|
}, {
|
|
31
31
|
facts: {
|
|
32
|
-
type: "
|
|
32
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
33
33
|
fact: string;
|
|
34
34
|
existing: boolean;
|
|
35
35
|
}[];
|
|
@@ -41,16 +41,16 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
|
|
|
41
41
|
event: z.ZodEnum<["ADD", "UPDATE", "DELETE", "NONE"]>;
|
|
42
42
|
old_memory: z.ZodNullable<z.ZodString>;
|
|
43
43
|
reason: z.ZodString;
|
|
44
|
-
type: z.ZodEnum<["factual", "
|
|
44
|
+
type: z.ZodEnum<["factual", "todo", "assistant_preference"]>;
|
|
45
45
|
}, "strict", z.ZodTypeAny, {
|
|
46
|
-
type: "
|
|
46
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
47
47
|
id: string;
|
|
48
48
|
text: string;
|
|
49
49
|
event: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
50
50
|
old_memory: string | null;
|
|
51
51
|
reason: string;
|
|
52
52
|
}, {
|
|
53
|
-
type: "
|
|
53
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
54
54
|
id: string;
|
|
55
55
|
text: string;
|
|
56
56
|
event: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
@@ -59,7 +59,7 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
|
|
|
59
59
|
}>, "many">;
|
|
60
60
|
}, "strip", z.ZodTypeAny, {
|
|
61
61
|
memory: {
|
|
62
|
-
type: "
|
|
62
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
63
63
|
id: string;
|
|
64
64
|
text: string;
|
|
65
65
|
event: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
@@ -68,7 +68,7 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
|
|
|
68
68
|
}[];
|
|
69
69
|
}, {
|
|
70
70
|
memory: {
|
|
71
|
-
type: "
|
|
71
|
+
type: "todo" | "factual" | "assistant_preference";
|
|
72
72
|
id: string;
|
|
73
73
|
text: string;
|
|
74
74
|
event: "ADD" | "UPDATE" | "DELETE" | "NONE";
|
|
@@ -79,13 +79,12 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
|
|
|
79
79
|
/**
|
|
80
80
|
* Practical Application:
|
|
81
81
|
*
|
|
82
|
-
* If the task is "factual" (e.g., "Where do I live?") → retrieve factual memory.
|
|
83
|
-
* If the task is
|
|
82
|
+
* If the task is "factual" (e.g., "Where do I live?", "What's my job?") → retrieve factual memory.
|
|
83
|
+
* If the task is about assistant behavior (e.g., "How should I respond?") → retrieve assistant_preference memory.
|
|
84
84
|
* If the task is a user task/reminder (e.g., "Add a reminder to call the bank tomorrow") → retrieve todo memory.
|
|
85
85
|
*/
|
|
86
86
|
export declare const MEMORY_STRING_SYSTEM = "# DIRECTIVES FOR MEMORIES\n- Information stored in memory is always enclosed within the <memories> tag.\n- Prioritize the latest user message over memories (the user's current question is authoritative).\n- Select at most the top-5 relevant memories using cosine similarity and recency; ignore the rest.\n- Adapt your answer based strictly on the <memories> section when relevant.\n- If the memories are irrelevant to the user's query, ignore them.\n- By default, do not reference this section or the memories in your response.\n- Use memories only to guide reasoning; do not respond to the memories themselves.";
|
|
87
87
|
export declare const MEMORY_STRING_PREFIX = "Use these contextual memories to guide your response. Prioritize the user's question. Ignore irrelevant memories.";
|
|
88
|
-
export declare const MEMORY_STRING_SYSTEM_OLD = "# USER AND MEMORIES PREFERENCES:\n- Utilize the provided memories to guide your responses.\n- Disregard any memories that are not relevant.\n- By default, do not reference this section or the memories in your response.\n";
|
|
89
88
|
export declare function getFactRetrievalMessages(parsedMessages: string, customRules?: string, defaultLanguage?: string): [string, string];
|
|
90
89
|
export declare function getUpdateMemoryMessages(retrievedOldMemory: Array<{
|
|
91
90
|
id: string;
|
package/dist/prompts/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMemoriesAsSystem = exports.getMemoriesAsPrefix = exports.
|
|
3
|
+
exports.getMemoriesAsSystem = exports.getMemoriesAsPrefix = exports.MEMORY_STRING_PREFIX = exports.MEMORY_STRING_SYSTEM = exports.MemoryUpdateSchema = exports.FactRetrievalSchema_extended = exports.FactRetrievalSchema_simple = void 0;
|
|
4
4
|
exports.getFactRetrievalMessages = getFactRetrievalMessages;
|
|
5
5
|
exports.getUpdateMemoryMessages = getUpdateMemoryMessages;
|
|
6
6
|
exports.parseMessages = parseMessages;
|
|
@@ -12,21 +12,19 @@ exports.FactRetrievalSchema_simple = zod_1.z.object({
|
|
|
12
12
|
.array(zod_1.z.string())
|
|
13
13
|
.describe("An array of distinct facts extracted from the conversation."),
|
|
14
14
|
});
|
|
15
|
-
//1. **Factual
|
|
16
|
-
//2. **
|
|
17
|
-
//3. **
|
|
18
|
-
//4. **Todo memory** – explicit user tasks to remember
|
|
15
|
+
//1. **Factual memory** – stable facts & preferences about the user
|
|
16
|
+
//2. **Todo memory** – explicit user tasks to remember
|
|
17
|
+
//3. **Assistant preference memory** – how the user wants the AI to behave
|
|
19
18
|
//
|
|
20
19
|
exports.FactRetrievalSchema_extended = zod_1.z.object({
|
|
21
20
|
facts: zod_1.z
|
|
22
21
|
.array(zod_1.z.object({
|
|
23
22
|
fact: zod_1.z.string().describe("The fact extracted from the conversation."),
|
|
24
23
|
existing: zod_1.z.boolean().describe("Whether the fact is already present"),
|
|
25
|
-
type: zod_1.z.enum(["assistant_preference", "factual", "
|
|
24
|
+
type: zod_1.z.enum(["assistant_preference", "factual", "todo"])
|
|
26
25
|
.describe(`The type of the fact.
|
|
27
26
|
Use 'assistant_preference' for Assistant behavior preferences (style/language/constraints/commands).
|
|
28
|
-
Use '
|
|
29
|
-
Use 'procedural' for how-to/business questions (e.g., « je veux résilier un bail, comment faire ? »).
|
|
27
|
+
Use 'factual' for stable user facts (identity, preferences, beliefs, work context).
|
|
30
28
|
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.
|
|
31
29
|
`),
|
|
32
30
|
}))
|
|
@@ -48,16 +46,16 @@ exports.MemoryUpdateSchema = zod_1.z.object({
|
|
|
48
46
|
.string()
|
|
49
47
|
.describe("The reason why you selected this event."),
|
|
50
48
|
type: zod_1.z
|
|
51
|
-
.enum(["factual", "
|
|
52
|
-
.describe("Type of the memory. Use 'assistant_preference' for Assistant behavior preferences, '
|
|
49
|
+
.enum(["factual", "todo", "assistant_preference"])
|
|
50
|
+
.describe("Type of the memory. Use 'assistant_preference' for Assistant behavior preferences, 'factual' for user facts, 'todo' for explicit tasks."),
|
|
53
51
|
}))
|
|
54
52
|
.describe("An array representing the state of memory items after processing new facts."),
|
|
55
53
|
});
|
|
56
54
|
/**
|
|
57
55
|
* Practical Application:
|
|
58
56
|
*
|
|
59
|
-
* If the task is "factual" (e.g., "Where do I live?") → retrieve factual memory.
|
|
60
|
-
* If the task is
|
|
57
|
+
* If the task is "factual" (e.g., "Where do I live?", "What's my job?") → retrieve factual memory.
|
|
58
|
+
* If the task is about assistant behavior (e.g., "How should I respond?") → retrieve assistant_preference memory.
|
|
61
59
|
* If the task is a user task/reminder (e.g., "Add a reminder to call the bank tomorrow") → retrieve todo memory.
|
|
62
60
|
*/
|
|
63
61
|
exports.MEMORY_STRING_SYSTEM = `# DIRECTIVES FOR MEMORIES
|
|
@@ -69,44 +67,34 @@ exports.MEMORY_STRING_SYSTEM = `# DIRECTIVES FOR MEMORIES
|
|
|
69
67
|
- By default, do not reference this section or the memories in your response.
|
|
70
68
|
- Use memories only to guide reasoning; do not respond to the memories themselves.`;
|
|
71
69
|
exports.MEMORY_STRING_PREFIX = "Use these contextual memories to guide your response. Prioritize the user's question. Ignore irrelevant memories.";
|
|
72
|
-
exports.MEMORY_STRING_SYSTEM_OLD = `# USER AND MEMORIES PREFERENCES:
|
|
73
|
-
- Utilize the provided memories to guide your responses.
|
|
74
|
-
- Disregard any memories that are not relevant.
|
|
75
|
-
- By default, do not reference this section or the memories in your response.
|
|
76
|
-
`;
|
|
77
70
|
// Deprecated: getFactRetrievalMessages_O removed in favor of getFactRetrievalMessages
|
|
78
71
|
function getFactRetrievalMessages(parsedMessages, customRules = "", defaultLanguage = "French") {
|
|
79
72
|
const injectCustomRules = (customRules) => customRules ? `\n# PRE-EXISTING FACTS\n${customRules}` : "";
|
|
80
|
-
const systemPrompt = `You are a Personal Information Organizer, specialized in
|
|
73
|
+
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).
|
|
81
74
|
|
|
82
75
|
Filter content before extracting triplets:
|
|
83
|
-
- Relevance: keep only statements directly about the user (preferences, identity, actions
|
|
76
|
+
- 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.
|
|
84
77
|
- Disinterest: if the user rejects the topic (e.g., "cette information ne m'intéresse pas", "not interested"), return {"facts":[]}.
|
|
85
|
-
-
|
|
86
|
-
- 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,
|
|
87
|
-
|
|
88
|
-
You must strictly extract {Subject, Predicate, Object} triplets
|
|
78
|
+
- Ignore business/process/regulation/company-policy content entirely (no extraction, no memory).
|
|
79
|
+
- 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":[]}.
|
|
80
|
+
|
|
81
|
+
You must strictly extract {Subject, Predicate, Object} triplets (max 12):
|
|
89
82
|
1. Identify named entities, preferences, and meaningful user-related concepts:
|
|
90
|
-
- Extract triplets
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
- "assistant_preference":
|
|
94
|
-
- "
|
|
95
|
-
- "todo": ONLY if the user explicitly
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
- DO NOT infer personal facts from third-party informations.
|
|
106
|
-
- Treat "**ASSISTANT**:" as responses to enrich context of your reasoning process about the USER query.
|
|
107
|
-
2. Use pronoun "I" instead of "The user" in the subject of the triplet.
|
|
108
|
-
3. Do not output any facts already present in section # PRE-EXISTING FACTS.
|
|
109
|
-
- If you find facts already present in section # PRE-EXISTING FACTS, use field "existing" to store them.
|
|
83
|
+
- Extract triplets *about the user* that help AI personalization (preferences, stable facts, explicit todos).
|
|
84
|
+
- Use explicit, precise, unambiguous predicates (e.g., "prefers", "speaks", "is a", "uses").
|
|
85
|
+
- Triplet type ∈ {"assistant_preference","factual","todo"} only:
|
|
86
|
+
- "assistant_preference": response style/language/format or interaction constraints.
|
|
87
|
+
- "factual": stable user data relevant to personalization (e.g., language, timezone, tools used).
|
|
88
|
+
- "todo": ONLY if the user explicitly asks to save/keep as todo. Never infer from intent alone.
|
|
89
|
+
- Remove introductions, sub-facts, repetitions, fillers, vague statements; prefer the general fact over details.
|
|
90
|
+
- Each triplet (S,P,O) ≤ 10 words total.
|
|
91
|
+
- Do not include type labels inside fact text; use the 'type' field only.
|
|
92
|
+
- Do not infer personal facts from third-party information.
|
|
93
|
+
- Treat "**ASSISTANT**:" as context only; never as a fact source.
|
|
94
|
+
|
|
95
|
+
2. Use pronoun "I" as the Subject (not "The user").
|
|
96
|
+
3. Do not output facts already in # PRE-EXISTING FACTS.
|
|
97
|
+
- If found, put them in "existing" (list of matched facts or IDs).
|
|
110
98
|
|
|
111
99
|
${injectCustomRules(customRules)}
|
|
112
100
|
|
|
@@ -125,47 +113,67 @@ function getUpdateMemoryMessages(retrievedOldMemory, newRetrievedFacts, defaultL
|
|
|
125
113
|
if (facts.length === 0)
|
|
126
114
|
return "";
|
|
127
115
|
if (facts[0].fact) {
|
|
128
|
-
return facts.map((elem) =>
|
|
116
|
+
return facts.map((elem) => `- "${elem.fact}" (type:${elem.type})`).join("\n");
|
|
129
117
|
}
|
|
130
118
|
else {
|
|
131
119
|
return facts.join("\n");
|
|
132
120
|
}
|
|
133
121
|
};
|
|
134
122
|
const serializeMemory = (memory) => {
|
|
135
|
-
return memory.map((elem) =>
|
|
123
|
+
return memory.map((elem) => `- "${elem.text}" (id:${elem.id})`).join("\n");
|
|
136
124
|
};
|
|
137
125
|
return `ROLE:
|
|
138
|
-
You are
|
|
126
|
+
You are the Memory Manager module of an AI assistant. You are specialized in semantic reasoning, fact consistency, and memory lifecycle operations.
|
|
127
|
+
Your job is to maintain a coherent, contradiction-free knowledge base (long-term memory) of user facts.
|
|
139
128
|
|
|
140
129
|
MISSION:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
-
|
|
156
|
-
|
|
130
|
+
Given:
|
|
131
|
+
1. A set of **Current Memory** facts (each with unique ID and textual content).
|
|
132
|
+
2. A set of **New Retrieved Facts** from the user or external sources.
|
|
133
|
+
3. (Optional) A **User Instruction** indicating explicit intent (add, modify, delete).
|
|
134
|
+
|
|
135
|
+
You must process each new fact individually and decide **exactly one** action: **ADD**, **DELETE**, **UPDATE**, or **NONE**, following these rules, in this order:
|
|
136
|
+
|
|
137
|
+
1. **User intent override**
|
|
138
|
+
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.
|
|
139
|
+
|
|
140
|
+
2. **Semantic consistency check**
|
|
141
|
+
For each new fact:
|
|
142
|
+
- If it **contradicts**, **negates**, or **cancels** an existing memory item, you **DELETE** the memory item.
|
|
143
|
+
- 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).
|
|
144
|
+
- Else, if it is **semantically equivalent** (i.e. redundant or paraphrased), assign **NONE** (no change).
|
|
145
|
+
- Else, if it is entirely **new** (no overlap or relation), **ADD** it (generate a new ID).
|
|
146
|
+
- Otherwise (if ambiguous or borderline), assign **NONE** (do not delete).
|
|
147
|
+
|
|
148
|
+
3. **ID reuse and consistency**
|
|
149
|
+
- For **UPDATE**, reuse the existing memory item’s ID.
|
|
150
|
+
- For **DELETE**, simply remove the item from the final memory output.
|
|
151
|
+
- For **ADD**, generate a new unique ID (e.g. UUID).
|
|
152
|
+
- If memory is initially empty, treat all new facts as **ADD**.
|
|
153
|
+
|
|
154
|
+
4. **Output formatting**
|
|
155
|
+
Return the updated memory state in strict JSON format. Each memory entry must include:
|
|
156
|
+
- \`id\` (string)
|
|
157
|
+
- \`text\` (string, the pure factual content)
|
|
158
|
+
- Optionally for updates: \`old_text\` (the prior version)
|
|
159
|
+
- *(No extra annotation or type markup in \`text\`)*
|
|
160
|
+
|
|
161
|
+
If there are no facts at all, return \`{"memory": []}\`.
|
|
162
|
+
|
|
163
|
+
*You must not output any other text besides the valid JSON result.*
|
|
157
164
|
|
|
158
165
|
# Output Instructions
|
|
159
|
-
- Default user language is ${defaultLanguage}.
|
|
166
|
+
- Default user language is "${defaultLanguage}".
|
|
160
167
|
- Each memory item must follow this strict format:
|
|
161
|
-
- UPDATE also include the previous text: \`
|
|
162
|
-
-
|
|
163
|
-
-
|
|
168
|
+
- UPDATE must also include the previous text: \`old_text\`.
|
|
169
|
+
- Reuse correct IDs for UPDATE.
|
|
170
|
+
- For DELETE, exclude the removed item from the final memory list.
|
|
171
|
+
- Generate random IDs for ADDs (format: UUID).
|
|
164
172
|
- If memory is empty, treat all facts as ADD.
|
|
165
173
|
- Without facts, return an empty memory: \`{"memory": []}\`
|
|
166
174
|
- Memory must strictly reflect valid facts.
|
|
167
|
-
- Contradictions, cancellations,
|
|
168
|
-
|
|
175
|
+
- Contradictions, cancellations, or negations must be handled by DELETE. Ambiguities must be handled by NONE.
|
|
176
|
+
- The field 'text' must be the pure memory content only: do not add any type markers or parentheses.
|
|
169
177
|
|
|
170
178
|
# Current Memory (extract and reuse their IDs for UPDATE or DELETE events):
|
|
171
179
|
${serializeMemory(retrievedOldMemory)}
|
|
@@ -173,8 +181,7 @@ ${serializeMemory(retrievedOldMemory)}
|
|
|
173
181
|
# New Retrieved Facts:
|
|
174
182
|
${serializeFacts(newRetrievedFacts)}
|
|
175
183
|
|
|
176
|
-
# User Instruction:
|
|
177
|
-
${userInstruction || ""}
|
|
184
|
+
# User Instruction: "${userInstruction || ''}"
|
|
178
185
|
|
|
179
186
|
Return the updated memory in JSON format only. Do not output anything else.`;
|
|
180
187
|
}
|
|
@@ -198,8 +205,10 @@ const getMemoriesAsPrefix = (memories) => {
|
|
|
198
205
|
};
|
|
199
206
|
exports.getMemoriesAsPrefix = getMemoriesAsPrefix;
|
|
200
207
|
const getMemoriesAsSystem = (memories, facts) => {
|
|
208
|
+
if (!memories || memories.length === 0)
|
|
209
|
+
return "";
|
|
201
210
|
const memoryString = memories.map((mem) => `- ${mem.memory}`).concat(facts || []).join("\n");
|
|
202
|
-
return `${exports.MEMORY_STRING_SYSTEM}\n<memories
|
|
211
|
+
return `${exports.MEMORY_STRING_SYSTEM}\n<memories>\n${memoryString}\n</memories>`;
|
|
203
212
|
};
|
|
204
213
|
exports.getMemoriesAsSystem = getMemoriesAsSystem;
|
|
205
214
|
function parseMessages(messages) {
|