memories-lite 0.9.0 β†’ 0.9.2

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/README.md CHANGED
@@ -2,80 +2,53 @@
2
2
 
3
3
  > **A lightweight memory layer for AI agents, leveraging LLMs for fact extraction and vector embeddings for retrieval.**
4
4
 
5
- Inspired by concepts from research papers like **A-MEM** (Lu et al., 2025) for its approach to atomized, embedded memories and similarity search, **MemoryLLM** (Wang et al., 2024) for its insights into memory decay, and **Reflexion** (Shinn et al., 2023) for self-correction loops, `memories-lite` provides a practical implementation focusing initially on the core memory capture and retrieval mechanisms.
5
+ ## πŸ“‹ Table of Contents
6
+ - [Quick Start](#-quick-start)
7
+ - [Installation](#-installation)
8
+ - [Basic Usage](#-basic-usage)
9
+ - [Key Features](#-key-features)
10
+ - [Memory Types](#-memory-types)
11
+ - [Use Cases](#-use-cases)
12
+ - [Advanced Configuration](#-advanced-configuration)
13
+ - [Documentation](#-documentation)
14
+ - [Acknowledgements](#-acknowledgements)
15
+
16
+ ## πŸš€ Quick Start
6
17
 
7
- **For detailed technical implementation specifics, see [TECHNICAL.md](./TECHNICAL.md).**
8
-
9
- ---
10
-
11
- ## Goal
12
-
13
- Memories-lite provides contextual memory for AI agents. It uses Language Models (LLMs) like OpenAI's GPT models to extract key information (memories) from conversations and stores them using vector embeddings for efficient retrieval. Unlike purely stateless approaches, it utilizes configurable vector stores and an optional history manager (defaulting to in-memory SQLite) for persistence and tracking changes.
14
-
15
- ---
16
-
17
- ## Use Cases
18
-
19
- - **Personalized AI Assistants**: Enable more natural interactions through contextual memory.
20
- - **Autonomous Agents**: Maintain conversational context without heavy infrastructure.
21
- - **Local or Serverless Applications**: Add memory capabilities to embedded bots or assistants.
22
-
23
-
24
- ## Core Features
25
- - **Semantic Memory Typing**: Explicitly tagging and utilizing memory types (factual, episodic, semantic, procedural).
26
- - **Memory Capture**: Processes user messages or structured input, uses an LLM to extract relevant facts/memories, generates embeddings, and stores them in a vector database (inspired by **A-MEM**).
27
- - **Contextual Retrieval**: Searches the vector store based on a query embedding to find relevant memories using vector similarity (inspired by **A-MEM**).
28
- - **Memory Management**: Provides methods to `get`, `update`, `delete`, `getAll`, and `deleteAll` memories associated with a specific user ID.
29
- - **Configurable Backends**: Supports different providers for LLMs (e.g., OpenAI), Embedders (e.g., OpenAI, Google), and Vector Stores.
30
- - **User-centric Persistence**: Memories are securely stored and isolated by user ID, ensuring data privacy and delegate storage control to the server.
31
-
32
-
33
- ## Roadmap & TODO
34
- Features planned or under development:
35
-
36
- - [ ] **Memory Decay & Scoring**: Implement hybrid scoring combining vector similarity with recency decay (e.g., exponential decay based on half-life per memory type, inspired by **MemoryLLM**) and explicit importance weights.
37
- - [ ] **Reflexion Pattern Integration**: Add optional self-correction/reflection loops where the agent evaluates and potentially refines memories (inspired by **Reflexion**).
38
- - [ ] **Memory Recency**: Implementing mechanisms to prioritize memories based on importance, relevance, or time decay.
39
- - [X] **Semantic Memory Typing & Structuring**: Explicitly tagging and utilizing memory types (factual, episodic, semantic, procedural) within the storage and retrieval logic beyond basic metadata.
40
- - [X] **Implicit Memory Updates**: Automatically updating or merging memories based on conversational context or corrections, rather than requiring explicit `update` calls with memory IDs.
41
- - [X] **Virtual Sessions/Context Grouping**: Logic for grouping memories related to specific conversational contexts or sessions automatically.
42
-
43
- ## Memory Types (Conceptual)
44
-
45
- While the internal storage is primarily based on vectorized text facts, `memories-lite` can be used to manage different conceptual types of memory through prompting and metadata:
46
-
47
- ### 1. Factual Memory
48
- - **Description**: Explicit knowledge about the user, such as preferences, skills, or personal information.
49
- - **Example**: "Likes Italian cuisine", "Speaks Spanish fluently".
50
-
51
- ### 2. Episodic Memory
52
- - **Description**: Memories of past events or interactions, often tied to a specific time or place.
53
- - **Example**: "Attended a concert in Paris in 2023", "Met Marie at a conference".
54
- - **Context Dependency**: Highly dependent on history to establish a timeline and narrative coherence.
55
-
56
- ### 3. Semantic Memory
57
- - **Description**: Understanding of general concepts, relationships, and meanings.
58
- - **Example**: "Yoga is beneficial for mental health", "Cats are domestic animals".
59
- - **Context Dependency**: Generally independent, but can be influenced by past interactions to refine understanding.
60
-
61
- ### 4. Procedural Memory
62
- - **Description**: Knowledge of processes or sequences of actions, often acquired through practice.
63
- - **Example**: "Knows how to make a latte", "Can configure a home Wi-Fi network".
64
- - **Context Dependency**: May require history to adapt procedures to user preferences or habits.
18
+ ```bash
19
+ # Install the package
20
+ npm install memories-lite
65
21
 
66
- ## πŸ“Œ Example: Transforming Input into Memory
22
+ # Basic usage
23
+ import { MemoriesLite } from 'memories-lite';
67
24
 
68
- **User Interaction**: `"I started learning piano last week."`
25
+ const memory = new MemoriesLite({
26
+ llm: {
27
+ provider: 'openai',
28
+ config: { apiKey: 'YOUR_API_KEY' }
29
+ },
30
+ embedder: {
31
+ provider: 'openai',
32
+ config: { apiKey: 'YOUR_API_KEY', model: 'text-embedding-3-small' }
33
+ }
34
+ });
69
35
 
70
- **Potential Memories Extracted (via LLM)**:
71
- - `"User is learning piano"`
72
- - `"User started learning piano recently"` (or specific date if LLM extracts it)
36
+ // Add a memory for a user
37
+ await memory.capture("I prefer dark chocolate over milk chocolate", "user123");
73
38
 
74
- These extracted facts are then embedded and stored in the vector store associated with the `userId`.
39
+ // Retrieve relevant memories
40
+ const results = await memory.retrieve("What are my food preferences?", "user123");
41
+ ```
75
42
 
43
+ ## 🌟 Highlights
76
44
 
45
+ - **Higher Performance**: Optimized memory operations that run significantly faster than mem0
46
+ - **Business-Centric Design**: Simplified API and workflows specifically tailored for business use cases
47
+ - **Advanced Hybrid Scoring**: Improved relevance through a custom scoring algorithm that balances vector similarity, recency, and importance
48
+ - **Enhanced Security**: One database per user architecture that provides stronger isolation and data protection
49
+ - **Streamlined Implementation**: Focused on essential features with minimal dependencies
77
50
 
78
- ## Installation
51
+ ## πŸ“₯ Installation
79
52
 
80
53
  ```bash
81
54
  npm install memories-lite
@@ -83,139 +56,141 @@ npm install memories-lite
83
56
  yarn add memories-lite
84
57
  ```
85
58
 
86
- ---
87
-
88
- ## πŸš€ Usage
59
+ ## πŸ” Basic Usage
89
60
 
90
61
  ```typescript
91
- import { MemoriesLite, OpenAIEmbedder, OpenAILLM } from 'memories-lite';
62
+ import { MemoriesLite } from 'memories-lite';
92
63
 
93
- // Basic configuration (uses defaults: in-memory SQLite history, OpenAI)
94
- const apiKey = 'YOUR_OPENAI_API_KEY';
95
- const memories = new MemoriesLite({
64
+ // Basic configuration
65
+ const memory = new MemoriesLite({
96
66
  llm: {
97
67
  provider: 'openai',
98
- config: { apiKey }
68
+ config: { apiKey: 'YOUR_OPENAI_API_KEY' }
99
69
  },
100
70
  embedder: {
101
71
  provider: 'openai',
102
- config: { apiKey }
72
+ config: { apiKey: 'YOUR_OPENAI_API_KEY' }
103
73
  }
104
74
  // Vector store defaults to an in-memory store
105
- // History defaults to in-memory SQLite
106
75
  });
107
76
 
77
+ // Unique ID for each user
108
78
  const userId = 'user-123';
109
79
 
110
- async function runExample() {
111
- // Capture a memory
112
- await memories.capture('I am passionate about the humanitarianism of Pol Pot.', userId); // Note: Example text used for demonstration.
113
-
114
- // Retrieve relevant memories
115
- const searchResults = await memories.retrieve('What are my interests?', userId);
80
+ // Add memories
81
+ await memory.capture('I love Italian food', userId);
116
82
 
117
- console.log('Relevant Memories:', searchResults.memories.map(m => m.memory));
118
- // Example Output might include: ["User is passionate about the humanitarianism of Pol Pot."]
119
- // The exact output depends on the LLM's fact extraction.
83
+ // Retrieve relevant memories
84
+ const results = await memory.retrieve('What foods do I like?', userId);
85
+ console.log('Relevant memories:', results.results.map(m => m.memory));
120
86
 
121
- // --- Example integrating retrieval into a response generation flow ---
122
- const userMessage = 'Tell me about my hobbies.';
123
- const relevantMemories = await memories.retrieve(userMessage, userId);
124
-
125
- const memoryContext = relevantMemories.memories.map(m => m.memory).join('\n');
126
-
127
- // You would typically pass this context to your main application's LLM call
128
- console.log('\nContext for LLM:', memoryContext);
87
+ // Update a memory
88
+ if (results.results.length > 0) {
89
+ await memory.update(results.results[0].id, 'I love Italian and French cuisine', userId);
129
90
  }
130
91
 
131
- runExample().catch(console.error);
92
+ // Delete a memory
93
+ if (results.results.length > 0) {
94
+ await memory.delete(results.results[0].id, userId);
95
+ }
132
96
 
97
+ // Get all memories for a user
98
+ const allMemories = await memory.getAll(userId, {});
133
99
  ```
134
100
 
135
- ## πŸ“„ License
101
+ ## πŸ”‘ Key Features
136
102
 
137
- MIT
103
+ - **Memory Capture**: Extract and store relevant information from conversations
104
+ - **Contextual Retrieval**: Find memories most relevant to the current query
105
+ - **User Isolation**: Each user's memories are stored separately for privacy and security
106
+ - **Memory Types**: Support for different types of memories (factual, episodic, etc.)
107
+ - **Custom Scoring**: Hybrid scoring system balancing similarity, recency, and importance
138
108
 
139
- ---
109
+ ## 🧩 Memory Types
140
110
 
141
- ## Acknowledgements
142
- Forked from the [Mem0](https://github.com/mem0ai/mem0) project ❀️.
111
+ Memories-lite supports four main types of memory:
143
112
 
144
- ## Useful Links and research
113
+ 1. **Factual Memory** βœ“
114
+ - User preferences, traits, and personal information
115
+ - Example: "User likes Italian cuisine"
145
116
 
146
- - [**Zep: A Temporal Knowledge Graph Architecture for Agent Memory** (arXiv:2501.13956)](https://arxiv.org/abs/2501.13956)
147
- - [**A-MEM: Agentic Memory for LLM Agents** (arXiv:2402.12110)](https://arxiv.org/abs/2402.12110) *(Note: Link points to 2402.12110, the user-provided 2502.12110 might be a typo)*
148
- - [**Reflexion: Language Agents with Verbal Reinforcement Learning** (arXiv:2303.11366)](https://arxiv.org/abs/2303.11366)
149
- - [**MemoryLLM: Towards Self-Updatable Large Language Models** (arXiv:2402.04624)](https://arxiv.org/abs/2402.04624)
117
+ 2. **Episodic Memory** ⏱️
118
+ - Time-based events and interactions
119
+ - Example: "User has a meeting tomorrow at 2pm"
150
120
 
121
+ 3. **Semantic Memory** 🧠
122
+ - General knowledge and concepts
123
+ - Example: "Yoga is beneficial for mental health"
151
124
 
152
- - **Exponential Decay**: Applying a decay function \( w(t) = e^{-\lambda t} \) where the decay rate \( \lambda \) depends on the memory type (e.g., episodic memories decay faster than factual ones).
153
- - **Half-Life**: Defining a half-life (HL) for different memory types to calculate \( \lambda = \ln(2) / \text{HL} \).
154
- - **Hybrid Scoring**: Integrating the decay factor into the memory retrieval score alongside vector similarity and potentially other metadata.
125
+ 4. **Procedural Memory** πŸ”„
126
+ - Step-by-step processes and workflows
127
+ - Example: "Steps to configure the company VPN"
155
128
 
129
+ ## πŸ’Ό Use Cases
130
+
131
+ - **Customer Support Bots**: Remember customer preferences and past interactions
132
+ - **Personal Assistants**: Build context-aware AI assistants that learn about user preferences
133
+ - **Business Applications**: Integrate with enterprise systems to maintain contextual awareness
134
+ - **Educational Tools**: Create learning assistants that remember student progress
135
+
136
+ ## βš™οΈ Advanced Configuration
156
137
 
157
138
  ```typescript
158
- // --- Advanced Configuration Example: Custom Scoring ---
159
- import { MemoriesLite, MemoryScoringConfig } from 'memories-lite';
160
-
161
- const apiKey = 'YOUR_OPENAI_API_KEY';
162
-
163
- // Define custom scoring rules
164
- const customScoring: MemoryScoringConfig = {
165
- // Make Factual memory very durable (long half-life, high similarity weight)
166
- factual: { alpha: 0.7, beta: 0.1, gamma: 0.1, halfLifeDays: 365 * 2 }, // 2 years HL
167
- // Make Assistant Preferences permanent (infinite half-life, high base weight)
168
- assistant_preference: { alpha: 0.5, beta: 0.0, gamma: 0.5, halfLifeDays: Infinity },
169
- // Make Procedural memory decay extremely fast (useless after ~1 hour)
170
- procedural: { alpha: 0.1, beta: 0.1, gamma: 0.0, halfLifeDays: 1 / 24 }, // 1 hour HL
171
- // Keep defaults for others (or customize as needed)
172
- episodic: { alpha: 0.40, beta: 0.50, gamma: 0.10, halfLifeDays: 7 },
173
- semantic: { alpha: 0.50, beta: 0.25, gamma: 0.25, halfLifeDays: 120 },
174
- default: { alpha: 0.5, beta: 0.3, gamma: 0.1, halfLifeDays: 30 },
175
- };
176
-
177
- const memoriesWithCustomScoring = new MemoriesLite({
139
+ // Custom scoring for different memory types
140
+ const customMemory = new MemoriesLite({
178
141
  llm: {
179
142
  provider: 'openai',
180
- config: { apiKey }
143
+ config: { apiKey: 'YOUR_API_KEY' }
181
144
  },
182
145
  embedder: {
183
- provider: 'openai',
184
- config: { apiKey }
146
+ provider: 'openai',
147
+ config: { apiKey: 'YOUR_API_KEY' }
185
148
  },
186
149
  vectorStore: {
187
- provider: 'lite', // Assuming LiteVectorStore which uses scoring
150
+ provider: 'lite',
188
151
  config: {
189
- // Other vector store config...
190
- scoring: customScoring // Pass the custom scoring rules
152
+ dimension: 1536,
153
+ scoring: {
154
+ // Prioritize factual memories with long retention
155
+ factual: { alpha: 0.7, beta: 0.2, gamma: 0.1, halfLifeDays: 365 },
156
+ // Make preferences permanently available
157
+ assistant_preference: { alpha: 0.6, beta: 0.0, gamma: 0.4, halfLifeDays: Infinity },
158
+ }
191
159
  }
192
160
  }
193
161
  });
194
-
195
- // Now use memoriesWithCustomScoring instance...
196
- // const userId = 'user-456';
197
- // await memoriesWithCustomScoring.capture('User learned how to bake bread.', userId, { type: 'procedural' });
198
- // await memoriesWithCustomScoring.capture('User prefers results in French.', userId, { type: 'assistant_preference' });
199
162
  ```
200
163
 
201
- ## πŸ“„ License
164
+ ## πŸ“š Documentation
202
165
 
203
- MIT
166
+ For detailed technical information and implementation details, see:
204
167
 
205
- ---
168
+ - [TECHNICAL.md](./TECHNICAL.md) - Technical implementation details
169
+ - [MEMORIES.md](./MEMORIES.md) - Detailed memory models and concepts
206
170
 
207
- ## Acknowledgements
208
- Forked from the [Mem0](https://github.com/mem0ai/mem0) project ❀️.
209
-
210
- ## Useful Links and research
171
+ ## πŸ™ Acknowledgements
211
172
 
212
- - [**Zep: A Temporal Knowledge Graph Architecture for Agent Memory** (arXiv:2501.13956)](https://arxiv.org/abs/2501.13956)
213
- - [**A-MEM: Agentic Memory for LLM Agents** (arXiv:2402.12110)](https://arxiv.org/abs/2402.12110) *(Note: Link points to 2402.12110, the user-provided 2502.12110 might be a typo)*
214
- - [**Reflexion: Language Agents with Verbal Reinforcement Learning** (arXiv:2303.11366)](https://arxiv.org/abs/2303.11366)
215
- - [**MemoryLLM: Towards Self-Updatable Large Language Models** (arXiv:2402.04624)](https://arxiv.org/abs/2402.04624)
173
+ Forked from the [Mem0](https://github.com/mem0ai/mem0) project ❀️.
216
174
 
175
+ Inspired by research concepts from:
176
+ - **A-MEM**: Agentic Memory for LLM Agents
177
+ - **MemoryLLM**: Self-Updatable Large Language Models
178
+ - **Reflexion**: Language Agents with Verbal Reinforcement Learning
179
+
180
+ ## πŸ“ Development Roadmap
181
+
182
+ - [x] **Semantic Memory Typing & Structuring**: Explicitly tagging and utilizing memory types (factual, episodic, semantic, procedural)
183
+ - [x] **Implicit Memory Updates**: Auto-merging memories based on context without explicit ID references
184
+ - [x] **Virtual Sessions/Context Grouping**: Group memories related to specific conversation contexts
185
+ - [x] **User Isolation**: Separate storage per user for enhanced security and data privacy
186
+ - [x] **Memory Type Detection**: LLM-based automatic classification of memory types
187
+ - [x] **Core Memory Operations**: Basic CRUD operations with user-specific isolation
188
+ - [x] **Memory Decay & Scoring**: Hybrid scoring with recency decay and importance weights
189
+ - [ ] **Reflexion Pattern Integration**: Self-correction loops for memory refinement
190
+ - [x] **Memory Recency**: Prioritizing memories based on importance and time decay
191
+ - [x] **Edge Case Tests**: Complete unit tests for episodic and factual memory edge cases
192
+ - [ ] **Middleware Support**: Hooks and middleware for custom processing pipelines
217
193
 
218
- - **Exponential Decay**: Applying a decay function \( w(t) = e^{-\lambda t} \) where the decay rate \( \lambda \) depends on the memory type (e.g., episodic memories decay faster than factual ones).
219
- - **Half-Life**: Defining a half-life (HL) for different memory types to calculate \( \lambda = \ln(2) / \text{HL} \).
220
- - **Hybrid Scoring**: Integrating the decay factor into the memory retrieval score alongside vector similarity and potentially other metadata.
194
+ ## πŸ“„ License
221
195
 
196
+ MIT
@@ -96,7 +96,7 @@ class MemoriesLite {
96
96
  async addToVectorStore(messages, metadata, userId, filters, customFacts) {
97
97
  const $t = this.$t;
98
98
  const vectorStore = await this.getVectorStore(userId);
99
- const parsedMessages = messages.filter((m) => typeof m.content === 'string').map((m) => `${m.role == 'user' ? '**USER**: ' : '**ASSISTANT**: '}${$t(m.content)}\n`).join("\n");
99
+ const parsedMessages = messages.filter((m) => typeof m.content === 'string' && m.role == 'user').map((m) => `${m.role == 'user' ? '**USER**: ' : '**ASSISTANT**: '}${$t(m.content)}\n`).join("\n");
100
100
  const [systemPrompt, userPrompt] = (0, prompts_1.getFactRetrievalMessages)(parsedMessages, customFacts || this.customPrompt);
101
101
  const response = await this.llm.generateResponse([
102
102
  { role: "system", content: systemPrompt },
@@ -124,6 +124,9 @@ class MemoriesLite {
124
124
  // Get embeddings for new facts
125
125
  const newMessageEmbeddings = {};
126
126
  const retrievedOldMemory = [];
127
+ //
128
+ // add the userId to the filters
129
+ filters.userId = userId;
127
130
  // Create embeddings and search for similar memories
128
131
  for (const elem of facts) {
129
132
  const fact = elem.fact;
@@ -155,7 +158,7 @@ class MemoriesLite {
155
158
  console.log(`-- β›” LLM Error: ${action.event}, ${action.type}, "${action.text}"`);
156
159
  continue;
157
160
  }
158
- console.log(`-- DBG memory action: ${action.event}, ${action.type}, "${action.text}", why: "${action.reason}"`);
161
+ console.log(`-- DBG memory "${userId}": ${action.event}, ${action.type}, "${action.text}", why: "${action.reason}"`);
159
162
  try {
160
163
  switch (action.event) {
161
164
  case "ADD": {
@@ -176,7 +179,7 @@ class MemoriesLite {
176
179
  }
177
180
  case "UPDATE": {
178
181
  const realMemoryId = tempUuidMapping[action.id];
179
- const type = uniqueOldMemories[action.id].type;
182
+ const type = metadata.type = uniqueOldMemories[action.id].type || action.type;
180
183
  await this.updateMemory(realMemoryId, action.text, newMessageEmbeddings, metadata, userId);
181
184
  results.push({
182
185
  id: realMemoryId,
@@ -307,6 +310,7 @@ class MemoriesLite {
307
310
  throw new Error("One of the filters: userId, agentId or runId is required!");
308
311
  }
309
312
  const vectorStore = await this.getVectorStore(userId);
313
+ filters.userId = userId;
310
314
  // Search vector store
311
315
  const queryEmbedding = await this.embedder.embed(query);
312
316
  const memories = await vectorStore.search(queryEmbedding, limit, filters);
@@ -420,6 +424,7 @@ class MemoriesLite {
420
424
  filters.runId = runId;
421
425
  if (type)
422
426
  filters.type = type;
427
+ filters.userId = userId;
423
428
  const [memories] = await vectorStore.list(filters, limit);
424
429
  const excludedKeys = new Set([
425
430
  "userId",
@@ -453,6 +458,7 @@ class MemoriesLite {
453
458
  ...metadata,
454
459
  data,
455
460
  hash: (0, crypto_1.createHash)("md5").update(data).digest("hex"),
461
+ userId,
456
462
  createdAt: new Date().toISOString(),
457
463
  };
458
464
  await vectorStore.insert([embedding], [memoryId], [memoryMetadata]);
@@ -471,6 +477,7 @@ class MemoriesLite {
471
477
  ...metadata,
472
478
  data,
473
479
  hash: (0, crypto_1.createHash)("md5").update(data).digest("hex"),
480
+ type: existingMemory.payload.type,
474
481
  createdAt: existingMemory.payload.createdAt,
475
482
  updatedAt: new Date().toISOString(),
476
483
  ...(existingMemory.payload.agentId && {
@@ -83,7 +83,7 @@ export declare const MemoryUpdateSchema: z.ZodObject<{
83
83
  * If the task is temporal or event-based ("What was I doing yesterday?") β†’ retrieve episodic memory.
84
84
  * If the task is conceptual ("What does the user think about Marxism?") β†’ retrieve semantic memory.
85
85
  */
86
- export declare const MEMORY_STRING_SYSTEM = "# DIRECTIVES FOR MEMORIES\n- Information stored in memory is always enclosed within the <memories> tag.\n- Give 10x more weight to the user's current conversation and prioritize answering it first.\n- You must adapt your answer based on the contents found within the <memories> section.\n- If the memories are irrelevant to the user's query, you MUST ignore them.\n- By default, do not reference this section or the memories in your response.\n- Use the memory type only to guide your reasoning. Do not respond to this section of the prompt, nor to the memories themselves \u2014 they are for your reference only.";
86
+ export declare const MEMORY_STRING_SYSTEM = "# DIRECTIVES FOR MEMORIES\n- Information stored in memory is always enclosed within the <memories> tag.\n- Give 10x more weight to the user's current conversation and prioritize answering it first.\n- You must adapt your answer based on the contents found within the <memories> section.\n- If the memories are irrelevant to the user's query, you MUST ignore them.\n- By default, do not reference this section or the memories in your response.\n- Use memories only to guide your 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
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
89
  export declare function getFactRetrievalMessages_O(parsedMessages: string, customRules?: string, defaultLanguage?: string): [string, string];
@@ -23,7 +23,12 @@ exports.FactRetrievalSchema_extended = zod_1.z.object({
23
23
  .array(zod_1.z.object({
24
24
  fact: zod_1.z.string().describe("The fact extracted from the conversation."),
25
25
  existing: zod_1.z.boolean().describe("Whether the fact is already present"),
26
- type: zod_1.z.enum(["assistant_preference", "factual", "episodic", "procedural", "semantic"]).describe("The type of the fact. Use 'assistant_preference' for Assistant behavior preferences."),
26
+ type: zod_1.z.enum(["assistant_preference", "factual", "episodic", "procedural", "semantic"])
27
+ .describe(`The type of the fact.
28
+ Use 'assistant_preference' for Assistant behavior preferences.
29
+ Use 'episodic' always for time-based events.
30
+ Use 'procedural' always when it concerns a business question.
31
+ Use 'semantic' for Understanding of concepts, relationships and general meanings.`),
27
32
  }))
28
33
  });
29
34
  // Define Zod schema for memory update output
@@ -61,7 +66,7 @@ exports.MEMORY_STRING_SYSTEM = `# DIRECTIVES FOR MEMORIES
61
66
  - You must adapt your answer based on the contents found within the <memories> section.
62
67
  - If the memories are irrelevant to the user's query, you MUST ignore them.
63
68
  - By default, do not reference this section or the memories in your response.
64
- - Use the memory type only to guide your reasoning. Do not respond to this section of the prompt, nor to the memories themselves β€” they are for your reference only.`;
69
+ - Use memories only to guide your reasoning. Do not respond to the memories themselves.`;
65
70
  exports.MEMORY_STRING_PREFIX = "Use these contextual memories to guide your response. Prioritize the user's question. Ignore irrelevant memories.";
66
71
  exports.MEMORY_STRING_SYSTEM_OLD = `# USER AND MEMORIES PREFERENCES:
67
72
  - Utilize the provided memories to guide your responses.
@@ -81,17 +86,17 @@ Your mission is to analyze a input content line by line and produce:
81
86
 
82
87
  Filter content before extracting triplets:
83
88
  - Ignore content with no direct relevance to user (e.g., "today is sunny", "I'm working").
84
- - If the user asks about a process, regulation, or third-party policy (e.g. company workflows, public steps, legal actions), assume they are seeking information, not expressing a personal desire.
85
- - Eliminate introductions, sub-facts, detailed repetitive elements, stylistic fillers, or vague statements. A general fact always takes precedence over multiple sub-facts (signal vs noise).
89
+ - Eliminate introductions, vague statements and detailed repetitive elements.
86
90
 
87
91
  You must extract {Subject, Predicate, Object} triplets by following these rules:
88
92
  1. Identify named entities, preferences, and meaningful user-related concepts:
89
- - All extracted triplets describe the user query intention as: the user’s preferences, beliefs, actions, experiences, learning, identity, work, or relationships (e.g., "I'm love working").
93
+ - All extracted triplets describe the user query intention as: the user’s preferences, beliefs, actions, experiences, learning, identity, work, or relationships (e.g., "I love working with precise Agents").
94
+ - Merge triplets from sub-facts or detailed objects. A general fact always takes precedence over multiple sub-facts (signal vs noise).
90
95
  - If the user asks about third-party business information classify it as "procedural" type.
91
96
  - The query intention can include specific preferences about how the Assistant should respond (e.g., "answer concisely", "explain in detail").
92
97
  - Use inference to compress each fact (max 10 words).
93
98
  - DO NOT infer personal facts from third-party informations.
94
- - Treat "Assistant Answer:" messages as external responses from the Assistant to the user. These responses MUST be used to enrich your reasoning process.
99
+ - Treat "Assistant:" messages as external and transient responses, there is no fact to extract from them. These responses MUST be used to enrich your reasoning process.
95
100
  2. Compress the facts:
96
101
  - Keep only the most shortest version of the Triplet.
97
102
  3. Rewrite comparatives, conditionals, or temporals into explicit predicates (e.g., "prefers", "available during", "used because of").
@@ -123,15 +128,15 @@ You must strictly extract {Subject, Predicate, Object} triplets by following the
123
128
  - 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").
124
129
  - Apply explicit, precise, and unambiguous predicates (e.g., "owns", "is located at", "is a", "has function", "causes", etc.).
125
130
  - Determine the triplet type (e.g., "factual", "episodic", "procedural", "semantic") based on the content and meaning.
126
- - "episodic" for time-based events (e.g., "I went to the park yesterday").
131
+ - "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.
127
132
  - "procedural" for business processes (e.g., "Looking for customer John Doe address", "How to create a new contract").
128
133
  - "factual" for stable user data (except procedural that prevails).
129
134
 
130
135
  - Eliminate introductions, sub-facts, detailed repetitive elements, stylistic fillers, or vague statements. General facts always takes precedence over multiple sub-facts (signal vs noise).
131
136
  - The query intention can include specific preferences about how the Assistant should respond (e.g., "answer concisely", "explain in detail").
132
- - Compress each fact and reason (less than 12 words).
137
+ - Compress each OUTPUT (fact and reason) with less than 10 words.
133
138
  - DO NOT infer personal facts from third-party informations.
134
- - Treat "Assistant Answer:" as external responses from the Assistant to enrich your reasoning process about the user.
139
+ - Treat "**ASSISTANT**:" as responses to enrich context of your reasoning process about the USER query.
135
140
  2. Use pronoun "I" instead of "The user" in the subject of the triplet.
136
141
  3. Do not output any facts already present in section # PRE-EXISTING FACTS.
137
142
  - If you find facts already present in section # PRE-EXISTING FACTS, use field "existing" to store them.
@@ -12,6 +12,7 @@ import { SearchFilters, VectorStoreConfig, VectorStoreResult } from "../types";
12
12
  */
13
13
  export declare class LiteVectorStore implements VectorStore {
14
14
  private db;
15
+ private dbPath;
15
16
  private isSecure;
16
17
  private dimension;
17
18
  private currentUserId;
@@ -36,5 +37,14 @@ export declare class LiteVectorStore implements VectorStore {
36
37
  list(filters?: SearchFilters, limit?: number): Promise<[VectorStoreResult[], number]>;
37
38
  private calculateRecencyScore;
38
39
  private calculateHybridScore;
40
+ /**
41
+ * Internal method to clean up vectors based on recency score threshold.
42
+ *
43
+ * @param threshold - The minimum recency score required for a memory to be retained.
44
+ * - Recency score is calculated using exponential decay: 1.0 means brand new, 0.5 means at half-life, 0.0 means fully decayed.
45
+ * - Memories with a recency score below this threshold will be deleted (unless their half-life is infinite or zero).
46
+ * - For example, a threshold of 0.25 will remove all memories whose recency score has decayed 2 times the half-life.
47
+ * - Use a lower threshold to keep more old memories, or a higher threshold to keep only fresher ones.
48
+ */
39
49
  private _cleanupByRecency;
40
50
  }