20
20
import io .github .mem4j .embeddings .EmbeddingService ;
21
21
import io .github .mem4j .llms .LLMService ;
22
22
import io .github .mem4j .vectorstores .VectorStoreService ;
23
+ import java .util .*;
24
+ import java .util .stream .Collectors ;
23
25
import org .slf4j .Logger ;
24
26
import org .slf4j .LoggerFactory ;
25
27
import org .springframework .stereotype .Service ;
26
28
27
- import java .util .*;
28
- import java .util .stream .Collectors ;
29
-
30
- /**
31
- * Core memory management class for Java Mem4j
32
- */
29
+ /** Core memory management class for Java Mem4j */
33
30
@ Service
34
31
public class Memory {
35
32
@@ -52,16 +49,12 @@ public Memory(MemoryConfigurable config, VectorStoreService vectorStoreService,
52
49
this .embeddingService = embeddingService ;
53
50
}
54
51
55
- /**
56
- * Add memories from a conversation
57
- */
52
+ /** Add memories from a conversation */
58
53
public void add (List <Message > messages , String userId ) {
59
54
add (messages , userId , null , true , MemoryType .FACTUAL );
60
55
}
61
56
62
- /**
63
- * Add memories with custom parameters
64
- */
57
+ /** Add memories with custom parameters */
65
58
public void add (List <Message > messages , String userId , Map <String , Object > metadata , boolean infer ,
66
59
MemoryType memoryType ) {
67
60
@@ -88,47 +81,63 @@ public void add(List<Message> messages, String userId, Map<String, Object> metad
88
81
logger .error ("Error adding memories for user {}" , userId , e );
89
82
throw new RuntimeException ("Failed to add memories" , e );
90
83
}
91
-
92
84
}
93
85
94
- /**
95
- * Search for relevant memories
96
- */
86
+ /** Search for relevant memories */
97
87
public List <MemoryItem > search (String query , String userId ) {
98
88
return search (query , userId , null , 10 , null );
99
89
}
100
90
101
- /**
102
- * Search with custom parameters
103
- */
91
+ /** Search with custom parameters */
104
92
public List <MemoryItem > search (String query , String userId , Map <String , Object > filters , int limit ,
105
93
Double threshold ) {
106
94
107
95
try {
108
96
// Generate embedding for query
109
97
Double [] queryEmbedding = embeddingService .embed (query );
98
+ logger .debug ("Generated query embedding with {} dimensions for query: '{}'" , queryEmbedding .length , query );
110
99
111
100
// Build search filters
112
101
Map <String , Object > searchFilters = buildSearchFilters (userId , filters );
102
+ logger .debug ("Search filters: {}" , searchFilters );
103
+
104
+ // Log the threshold being used
105
+ Double actualThreshold = threshold != null ? threshold : config .getSimilarityThreshold ();
106
+ logger .debug ("Using similarity threshold: {}" , actualThreshold );
113
107
114
108
// Search vector store
115
- List <MemoryItem > results = vectorStoreService .search (queryEmbedding , searchFilters , limit ,
116
- threshold != null ? threshold : config .getSimilarityThreshold ());
109
+ List <MemoryItem > results = vectorStoreService .search (queryEmbedding , searchFilters , limit , actualThreshold );
110
+
111
+ // If no results found and threshold > 0.2, try with lower threshold
112
+ if (results .isEmpty () && actualThreshold > 0.2 ) {
113
+ logger .debug ("No results with threshold {}, retrying with 0.2" , actualThreshold );
114
+ results = vectorStoreService .search (queryEmbedding , searchFilters , limit , 0.2 );
115
+ actualThreshold = 0.2 ; // Update for logging
116
+ }
117
+
118
+ logger .info ("Found {} memories for query: '{}' with threshold: {}" , results .size (), query , actualThreshold );
119
+
120
+ // Log found results for debugging
121
+ if (!results .isEmpty ()) {
122
+ for (MemoryItem item : results ) {
123
+ logger .debug ("Found memory: '{}' with score: {}" , item .getContent (), item .getScore ());
124
+ }
125
+ }
126
+ else {
127
+ logger .warn ("No memories found for query: '{}' with user_id: '{}' and threshold: {}" , query , userId ,
128
+ actualThreshold );
129
+ }
117
130
118
- logger .info ("Found {} memories for query: {}" , results .size (), query );
119
131
return results ;
120
132
}
121
133
catch (Exception e ) {
122
134
123
135
logger .error ("Error searching memories for query: {}" , query , e );
124
136
throw new RuntimeException ("Failed to search memories" , e );
125
137
}
126
-
127
138
}
128
139
129
- /**
130
- * Get all memories for a user
131
- */
140
+ /** Get all memories for a user */
132
141
public List <MemoryItem > getAll (String userId , Map <String , Object > filters , int limit ) {
133
142
134
143
try {
@@ -139,12 +148,9 @@ public List<MemoryItem> getAll(String userId, Map<String, Object> filters, int l
139
148
logger .error ("Error getting all memories for user {}" , userId , e );
140
149
throw new RuntimeException ("Failed to get memories" , e );
141
150
}
142
-
143
151
}
144
152
145
- /**
146
- * Update a memory item
147
- */
153
+ /** Update a memory item */
148
154
public void update (String memoryId , Map <String , Object > data ) {
149
155
150
156
try {
@@ -170,12 +176,9 @@ public void update(String memoryId, Map<String, Object> data) {
170
176
logger .error ("Error updating memory: {}" , memoryId , e );
171
177
throw new RuntimeException ("Failed to update memory" , e );
172
178
}
173
-
174
179
}
175
180
176
- /**
177
- * Delete a memory item
178
- */
181
+ /** Delete a memory item */
179
182
public void delete (String memoryId ) {
180
183
181
184
try {
@@ -186,12 +189,9 @@ public void delete(String memoryId) {
186
189
logger .error ("Error deleting memory: {}" , memoryId , e );
187
190
throw new RuntimeException ("Failed to delete memory" , e );
188
191
}
189
-
190
192
}
191
193
192
- /**
193
- * Delete all memories for a user
194
- */
194
+ /** Delete all memories for a user */
195
195
public void deleteAll (String userId ) {
196
196
197
197
try {
@@ -203,12 +203,9 @@ public void deleteAll(String userId) {
203
203
logger .error ("Error deleting all memories for user {}" , userId , e );
204
204
throw new RuntimeException ("Failed to delete memories" , e );
205
205
}
206
-
207
206
}
208
207
209
- /**
210
- * Extract memories from conversation using LLM
211
- */
208
+ /** Extract memories from conversation using LLM */
212
209
private List <String > extractMemories (List <Message > messages , boolean infer ) {
213
210
214
211
if (!infer ) {
@@ -226,8 +223,6 @@ private List<String> extractMemories(List<Message> messages, boolean infer) {
226
223
227
224
String prompt = String .format ("""
228
225
Extract key memories from this conversation. Focus on:
229
- - Keep the original language and tone
230
- - Be concise and specific
231
226
- Important facts about the user
232
227
- User preferences and behaviors
233
228
- Significant events or experiences
@@ -250,9 +245,7 @@ private List<String> extractMemories(List<Message> messages, boolean infer) {
250
245
.collect (Collectors .toList ());
251
246
}
252
247
253
- /**
254
- * Create a memory item from content
255
- */
248
+ /** Create a memory item from content */
256
249
private MemoryItem createMemoryItem (String content , String userId , Map <String , Object > metadata ,
257
250
MemoryType memoryType ) {
258
251
@@ -263,9 +256,7 @@ private MemoryItem createMemoryItem(String content, String userId, Map<String, O
263
256
return item ;
264
257
}
265
258
266
- /**
267
- * Build search filters
268
- */
259
+ /** Build search filters */
269
260
private Map <String , Object > buildSearchFilters (String userId , Map <String , Object > additionalFilters ) {
270
261
271
262
Map <String , Object > filters = new HashMap <>();
@@ -278,9 +269,7 @@ private Map<String, Object> buildSearchFilters(String userId, Map<String, Object
278
269
return filters ;
279
270
}
280
271
281
- /**
282
- * Get memory by ID
283
- */
272
+ /** Get memory by ID */
284
273
public MemoryItem get (String memoryId ) {
285
274
286
275
try {
@@ -292,9 +281,7 @@ public MemoryItem get(String memoryId) {
292
281
}
293
282
}
294
283
295
- /**
296
- * Reset all memories (for testing)
297
- */
284
+ /** Reset all memories (for testing) */
298
285
public void reset () {
299
286
300
287
try {
0 commit comments