AbstractMemory 0.2.1__tar.gz → 0.2.3__tar.gz

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.
Files changed (29) hide show
  1. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/PKG-INFO +46 -25
  2. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/SOURCES.txt +1 -0
  3. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/requires.txt +2 -0
  4. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/PKG-INFO +46 -25
  5. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/README.md +37 -18
  6. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/__init__.py +53 -8
  7. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/embeddings/__init__.py +38 -1
  8. abstractmemory-0.2.3/abstractmemory/embeddings/sentence_transformer_provider.py +159 -0
  9. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/pyproject.toml +9 -9
  10. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/dependency_links.txt +0 -0
  11. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/top_level.txt +0 -0
  12. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/LICENSE +0 -0
  13. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/cognitive/__init__.py +0 -0
  14. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/__init__.py +0 -0
  15. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/core.py +0 -0
  16. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/episodic.py +0 -0
  17. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/semantic.py +0 -0
  18. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/working.py +0 -0
  19. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/__init__.py +0 -0
  20. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/interfaces.py +0 -0
  21. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/temporal.py +0 -0
  22. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/graph/__init__.py +0 -0
  23. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/graph/knowledge_graph.py +0 -0
  24. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/simple.py +0 -0
  25. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/__init__.py +0 -0
  26. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/dual_manager.py +0 -0
  27. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/lancedb_storage.py +0 -0
  28. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/markdown_storage.py +0 -0
  29. {abstractmemory-0.2.1 → abstractmemory-0.2.3}/setup.cfg +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractMemory
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Production-ready memory system for LLM agents - NO MOCKS, real semantic search, clear LLM vs embedding provider separation
5
- Author-email: AbstractMemory Team <lpalbou@gmail.com>
6
- Maintainer-email: AbstractMemory Team <palbou@gmail.com>
5
+ Author-email: Laurent-Philippe Albou <lpalbou@gmail.com>
6
+ Maintainer-email: Laurent-Philippe Albou <lpalbou@gmail.com>
7
7
  License-Expression: MIT
8
- Project-URL: Homepage, https://github.com/lpalbou/AbstractAgent
9
- Project-URL: Documentation, https://github.com/lpalbou/AbstractAgent#readme
10
- Project-URL: Repository, https://github.com/lpalbou/AbstractAgent
11
- Project-URL: Bug Reports, https://github.com/lpalbou/AbstractAgent/issues
8
+ Project-URL: Homepage, https://github.com/lpalbou/AbstractMemory
9
+ Project-URL: Documentation, https://github.com/lpalbou/AbstractMemory#readme
10
+ Project-URL: Repository, https://github.com/lpalbou/AbstractMemory
11
+ Project-URL: Bug Reports, https://github.com/lpalbou/AbstractMemory/issues
12
12
  Keywords: llm,memory,semantic-search,embeddings,ai,agents,knowledge-graph,temporal,grounded-memory,vector-search
13
13
  Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
@@ -34,11 +34,13 @@ Requires-Dist: abstractcore>=2.1.0; extra == "llm"
34
34
  Provides-Extra: embeddings
35
35
  Requires-Dist: abstractcore>=2.1.0; extra == "embeddings"
36
36
  Requires-Dist: lancedb>=0.6.0; extra == "embeddings"
37
+ Requires-Dist: sentence-transformers>=2.0.0; extra == "embeddings"
37
38
  Provides-Extra: storage
38
39
  Requires-Dist: lancedb>=0.6.0; extra == "storage"
39
40
  Provides-Extra: all
40
41
  Requires-Dist: abstractcore>=2.1.0; extra == "all"
41
42
  Requires-Dist: lancedb>=0.6.0; extra == "all"
43
+ Requires-Dist: sentence-transformers>=2.0.0; extra == "all"
42
44
  Dynamic: license-file
43
45
 
44
46
  # AbstractMemory
@@ -165,26 +167,39 @@ memory = create_memory(
165
167
  ```
166
168
 
167
169
  #### Powerful Vector Search
168
- High-performance search with AbstractCore embeddings:
170
+ High-performance search with default optimized embeddings:
169
171
 
170
172
  ```python
171
- from abstractllm import create_llm
172
-
173
- # Create provider with embedding support
174
- provider = create_llm("openai", embedding_model="text-embedding-3-small")
173
+ # Uses default all-MiniLM-L6-v2 model (recommended)
174
+ memory = create_memory(
175
+ "grounded",
176
+ storage_backend="lancedb",
177
+ storage_uri="./memory.db"
178
+ # embedding_provider automatically configured with all-MiniLM-L6-v2
179
+ )
175
180
 
176
- # Vector search storage
181
+ # Or with custom embedding model
182
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
183
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
177
184
  memory = create_memory(
178
185
  "grounded",
179
186
  storage_backend="lancedb",
180
187
  storage_uri="./memory.db",
181
- embedding_provider=provider
188
+ embedding_provider=custom_provider
182
189
  )
183
190
 
184
191
  # Semantic search across stored interactions
185
192
  results = memory.search_stored_interactions("machine learning concepts")
186
193
  ```
187
194
 
195
+ **🎯 Default Embedding Model**: AbstractMemory now uses **all-MiniLM-L6-v2** as the default embedding model, providing:
196
+ - **Superior accuracy** (best semantic similarity performance)
197
+ - **Maximum efficiency** (22M parameters, 384D embeddings)
198
+ - **50% storage savings** compared to larger models
199
+ - **Perfect retrieval performance** (100% P@5, R@5, F1 scores)
200
+
201
+ See [embedding comparison report](docs/test-embeddings-report.md) for detailed benchmarks.
202
+
188
203
  #### Dual Storage - Best of Both Worlds
189
204
  Complete observability with powerful search:
190
205
 
@@ -290,7 +305,7 @@ python -m pytest tests/storage/test_dual_storage_comprehensive.py -v
290
305
  ### Installation
291
306
 
292
307
  ```bash
293
- # Install with semantic search capabilities (recommended)
308
+ # Install with semantic search capabilities (includes sentence-transformers for default all-MiniLM-L6-v2 model)
294
309
  pip install abstractmemory[embeddings]
295
310
 
296
311
  # Or install everything
@@ -334,33 +349,39 @@ memory = create_memory("grounded", embedding_provider=embedder) # NOT llm!
334
349
  ### Basic Usage
335
350
 
336
351
  ```python
337
- from abstractllm.embeddings import EmbeddingManager
338
352
  from abstractmemory import create_memory
339
353
 
340
- # 1. Create embedding manager for semantic search
341
- em = EmbeddingManager() # Uses EmbeddingGemma (768D vectors)
342
-
343
- # 2. Create memory with dual storage
354
+ # 1. Create memory with default all-MiniLM-L6-v2 embeddings (recommended)
344
355
  memory = create_memory(
345
356
  "grounded",
346
357
  storage_backend="dual", # Markdown + LanceDB
347
358
  storage_path="./memory_files", # Observable files
348
- storage_uri="./memory.db", # Vector search
349
- embedding_provider=em # Real embeddings
359
+ storage_uri="./memory.db" # Vector search (auto-configured with all-MiniLM-L6-v2)
350
360
  )
351
361
 
352
- # 3. Add interactions (embeddings generated immediately!)
362
+ # 2. Add interactions (embeddings generated automatically!)
353
363
  memory.set_current_user("alice")
354
364
  memory.add_interaction(
355
365
  "I'm working on machine learning projects",
356
366
  "Great! ML has amazing applications in many fields."
357
367
  )
358
- # ↳ Takes ~36ms: embedding generated and stored instantly
368
+ # ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
359
369
 
360
- # 4. Semantic search finds contextually relevant content
370
+ # 3. Semantic search finds contextually relevant content
361
371
  results = memory.search_stored_interactions("artificial intelligence research")
362
372
  # ↳ Finds ML interaction via semantic similarity (not keywords!)
363
373
  print(f"Found {len(results)} relevant conversations")
374
+
375
+ # Optional: Use custom embedding model
376
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
377
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
378
+ custom_memory = create_memory(
379
+ "grounded",
380
+ storage_backend="dual",
381
+ storage_path="./memory_files",
382
+ storage_uri="./memory.db",
383
+ embedding_provider=custom_provider
384
+ )
364
385
  ```
365
386
 
366
387
  ### 📋 What Happens When You Add Interactions
@@ -18,6 +18,7 @@ abstractmemory/core/__init__.py
18
18
  abstractmemory/core/interfaces.py
19
19
  abstractmemory/core/temporal.py
20
20
  abstractmemory/embeddings/__init__.py
21
+ abstractmemory/embeddings/sentence_transformer_provider.py
21
22
  abstractmemory/graph/__init__.py
22
23
  abstractmemory/graph/knowledge_graph.py
23
24
  abstractmemory/storage/__init__.py
@@ -3,6 +3,7 @@ networkx>=3.0
3
3
  [all]
4
4
  abstractcore>=2.1.0
5
5
  lancedb>=0.6.0
6
+ sentence-transformers>=2.0.0
6
7
 
7
8
  [dev]
8
9
  pytest
@@ -12,6 +13,7 @@ mypy
12
13
  [embeddings]
13
14
  abstractcore>=2.1.0
14
15
  lancedb>=0.6.0
16
+ sentence-transformers>=2.0.0
15
17
 
16
18
  [llm]
17
19
  abstractcore>=2.1.0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractMemory
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Production-ready memory system for LLM agents - NO MOCKS, real semantic search, clear LLM vs embedding provider separation
5
- Author-email: AbstractMemory Team <lpalbou@gmail.com>
6
- Maintainer-email: AbstractMemory Team <palbou@gmail.com>
5
+ Author-email: Laurent-Philippe Albou <lpalbou@gmail.com>
6
+ Maintainer-email: Laurent-Philippe Albou <lpalbou@gmail.com>
7
7
  License-Expression: MIT
8
- Project-URL: Homepage, https://github.com/lpalbou/AbstractAgent
9
- Project-URL: Documentation, https://github.com/lpalbou/AbstractAgent#readme
10
- Project-URL: Repository, https://github.com/lpalbou/AbstractAgent
11
- Project-URL: Bug Reports, https://github.com/lpalbou/AbstractAgent/issues
8
+ Project-URL: Homepage, https://github.com/lpalbou/AbstractMemory
9
+ Project-URL: Documentation, https://github.com/lpalbou/AbstractMemory#readme
10
+ Project-URL: Repository, https://github.com/lpalbou/AbstractMemory
11
+ Project-URL: Bug Reports, https://github.com/lpalbou/AbstractMemory/issues
12
12
  Keywords: llm,memory,semantic-search,embeddings,ai,agents,knowledge-graph,temporal,grounded-memory,vector-search
13
13
  Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
@@ -34,11 +34,13 @@ Requires-Dist: abstractcore>=2.1.0; extra == "llm"
34
34
  Provides-Extra: embeddings
35
35
  Requires-Dist: abstractcore>=2.1.0; extra == "embeddings"
36
36
  Requires-Dist: lancedb>=0.6.0; extra == "embeddings"
37
+ Requires-Dist: sentence-transformers>=2.0.0; extra == "embeddings"
37
38
  Provides-Extra: storage
38
39
  Requires-Dist: lancedb>=0.6.0; extra == "storage"
39
40
  Provides-Extra: all
40
41
  Requires-Dist: abstractcore>=2.1.0; extra == "all"
41
42
  Requires-Dist: lancedb>=0.6.0; extra == "all"
43
+ Requires-Dist: sentence-transformers>=2.0.0; extra == "all"
42
44
  Dynamic: license-file
43
45
 
44
46
  # AbstractMemory
@@ -165,26 +167,39 @@ memory = create_memory(
165
167
  ```
166
168
 
167
169
  #### Powerful Vector Search
168
- High-performance search with AbstractCore embeddings:
170
+ High-performance search with default optimized embeddings:
169
171
 
170
172
  ```python
171
- from abstractllm import create_llm
172
-
173
- # Create provider with embedding support
174
- provider = create_llm("openai", embedding_model="text-embedding-3-small")
173
+ # Uses default all-MiniLM-L6-v2 model (recommended)
174
+ memory = create_memory(
175
+ "grounded",
176
+ storage_backend="lancedb",
177
+ storage_uri="./memory.db"
178
+ # embedding_provider automatically configured with all-MiniLM-L6-v2
179
+ )
175
180
 
176
- # Vector search storage
181
+ # Or with custom embedding model
182
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
183
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
177
184
  memory = create_memory(
178
185
  "grounded",
179
186
  storage_backend="lancedb",
180
187
  storage_uri="./memory.db",
181
- embedding_provider=provider
188
+ embedding_provider=custom_provider
182
189
  )
183
190
 
184
191
  # Semantic search across stored interactions
185
192
  results = memory.search_stored_interactions("machine learning concepts")
186
193
  ```
187
194
 
195
+ **🎯 Default Embedding Model**: AbstractMemory now uses **all-MiniLM-L6-v2** as the default embedding model, providing:
196
+ - **Superior accuracy** (best semantic similarity performance)
197
+ - **Maximum efficiency** (22M parameters, 384D embeddings)
198
+ - **50% storage savings** compared to larger models
199
+ - **Perfect retrieval performance** (100% P@5, R@5, F1 scores)
200
+
201
+ See [embedding comparison report](docs/test-embeddings-report.md) for detailed benchmarks.
202
+
188
203
  #### Dual Storage - Best of Both Worlds
189
204
  Complete observability with powerful search:
190
205
 
@@ -290,7 +305,7 @@ python -m pytest tests/storage/test_dual_storage_comprehensive.py -v
290
305
  ### Installation
291
306
 
292
307
  ```bash
293
- # Install with semantic search capabilities (recommended)
308
+ # Install with semantic search capabilities (includes sentence-transformers for default all-MiniLM-L6-v2 model)
294
309
  pip install abstractmemory[embeddings]
295
310
 
296
311
  # Or install everything
@@ -334,33 +349,39 @@ memory = create_memory("grounded", embedding_provider=embedder) # NOT llm!
334
349
  ### Basic Usage
335
350
 
336
351
  ```python
337
- from abstractllm.embeddings import EmbeddingManager
338
352
  from abstractmemory import create_memory
339
353
 
340
- # 1. Create embedding manager for semantic search
341
- em = EmbeddingManager() # Uses EmbeddingGemma (768D vectors)
342
-
343
- # 2. Create memory with dual storage
354
+ # 1. Create memory with default all-MiniLM-L6-v2 embeddings (recommended)
344
355
  memory = create_memory(
345
356
  "grounded",
346
357
  storage_backend="dual", # Markdown + LanceDB
347
358
  storage_path="./memory_files", # Observable files
348
- storage_uri="./memory.db", # Vector search
349
- embedding_provider=em # Real embeddings
359
+ storage_uri="./memory.db" # Vector search (auto-configured with all-MiniLM-L6-v2)
350
360
  )
351
361
 
352
- # 3. Add interactions (embeddings generated immediately!)
362
+ # 2. Add interactions (embeddings generated automatically!)
353
363
  memory.set_current_user("alice")
354
364
  memory.add_interaction(
355
365
  "I'm working on machine learning projects",
356
366
  "Great! ML has amazing applications in many fields."
357
367
  )
358
- # ↳ Takes ~36ms: embedding generated and stored instantly
368
+ # ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
359
369
 
360
- # 4. Semantic search finds contextually relevant content
370
+ # 3. Semantic search finds contextually relevant content
361
371
  results = memory.search_stored_interactions("artificial intelligence research")
362
372
  # ↳ Finds ML interaction via semantic similarity (not keywords!)
363
373
  print(f"Found {len(results)} relevant conversations")
374
+
375
+ # Optional: Use custom embedding model
376
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
377
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
378
+ custom_memory = create_memory(
379
+ "grounded",
380
+ storage_backend="dual",
381
+ storage_path="./memory_files",
382
+ storage_uri="./memory.db",
383
+ embedding_provider=custom_provider
384
+ )
364
385
  ```
365
386
 
366
387
  ### 📋 What Happens When You Add Interactions
@@ -122,26 +122,39 @@ memory = create_memory(
122
122
  ```
123
123
 
124
124
  #### Powerful Vector Search
125
- High-performance search with AbstractCore embeddings:
125
+ High-performance search with default optimized embeddings:
126
126
 
127
127
  ```python
128
- from abstractllm import create_llm
129
-
130
- # Create provider with embedding support
131
- provider = create_llm("openai", embedding_model="text-embedding-3-small")
128
+ # Uses default all-MiniLM-L6-v2 model (recommended)
129
+ memory = create_memory(
130
+ "grounded",
131
+ storage_backend="lancedb",
132
+ storage_uri="./memory.db"
133
+ # embedding_provider automatically configured with all-MiniLM-L6-v2
134
+ )
132
135
 
133
- # Vector search storage
136
+ # Or with custom embedding model
137
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
138
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
134
139
  memory = create_memory(
135
140
  "grounded",
136
141
  storage_backend="lancedb",
137
142
  storage_uri="./memory.db",
138
- embedding_provider=provider
143
+ embedding_provider=custom_provider
139
144
  )
140
145
 
141
146
  # Semantic search across stored interactions
142
147
  results = memory.search_stored_interactions("machine learning concepts")
143
148
  ```
144
149
 
150
+ **🎯 Default Embedding Model**: AbstractMemory now uses **all-MiniLM-L6-v2** as the default embedding model, providing:
151
+ - **Superior accuracy** (best semantic similarity performance)
152
+ - **Maximum efficiency** (22M parameters, 384D embeddings)
153
+ - **50% storage savings** compared to larger models
154
+ - **Perfect retrieval performance** (100% P@5, R@5, F1 scores)
155
+
156
+ See [embedding comparison report](docs/test-embeddings-report.md) for detailed benchmarks.
157
+
145
158
  #### Dual Storage - Best of Both Worlds
146
159
  Complete observability with powerful search:
147
160
 
@@ -247,7 +260,7 @@ python -m pytest tests/storage/test_dual_storage_comprehensive.py -v
247
260
  ### Installation
248
261
 
249
262
  ```bash
250
- # Install with semantic search capabilities (recommended)
263
+ # Install with semantic search capabilities (includes sentence-transformers for default all-MiniLM-L6-v2 model)
251
264
  pip install abstractmemory[embeddings]
252
265
 
253
266
  # Or install everything
@@ -291,33 +304,39 @@ memory = create_memory("grounded", embedding_provider=embedder) # NOT llm!
291
304
  ### Basic Usage
292
305
 
293
306
  ```python
294
- from abstractllm.embeddings import EmbeddingManager
295
307
  from abstractmemory import create_memory
296
308
 
297
- # 1. Create embedding manager for semantic search
298
- em = EmbeddingManager() # Uses EmbeddingGemma (768D vectors)
299
-
300
- # 2. Create memory with dual storage
309
+ # 1. Create memory with default all-MiniLM-L6-v2 embeddings (recommended)
301
310
  memory = create_memory(
302
311
  "grounded",
303
312
  storage_backend="dual", # Markdown + LanceDB
304
313
  storage_path="./memory_files", # Observable files
305
- storage_uri="./memory.db", # Vector search
306
- embedding_provider=em # Real embeddings
314
+ storage_uri="./memory.db" # Vector search (auto-configured with all-MiniLM-L6-v2)
307
315
  )
308
316
 
309
- # 3. Add interactions (embeddings generated immediately!)
317
+ # 2. Add interactions (embeddings generated automatically!)
310
318
  memory.set_current_user("alice")
311
319
  memory.add_interaction(
312
320
  "I'm working on machine learning projects",
313
321
  "Great! ML has amazing applications in many fields."
314
322
  )
315
- # ↳ Takes ~36ms: embedding generated and stored instantly
323
+ # ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
316
324
 
317
- # 4. Semantic search finds contextually relevant content
325
+ # 3. Semantic search finds contextually relevant content
318
326
  results = memory.search_stored_interactions("artificial intelligence research")
319
327
  # ↳ Finds ML interaction via semantic similarity (not keywords!)
320
328
  print(f"Found {len(results)} relevant conversations")
329
+
330
+ # Optional: Use custom embedding model
331
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
332
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
333
+ custom_memory = create_memory(
334
+ "grounded",
335
+ storage_backend="dual",
336
+ storage_path="./memory_files",
337
+ storage_uri="./memory.db",
338
+ embedding_provider=custom_provider
339
+ )
321
340
  ```
322
341
 
323
342
  ### 📋 What Happens When You Add Interactions
@@ -36,7 +36,7 @@ def create_memory(
36
36
  storage_backend: "markdown", "lancedb", "dual", or None
37
37
  storage_path: Path for markdown storage
38
38
  storage_uri: URI for LanceDB storage
39
- embedding_provider: AbstractCore instance for embeddings
39
+ embedding_provider: Embedding provider for semantic search (defaults to all-MiniLM-L6-v2)
40
40
 
41
41
  Examples:
42
42
  # For a ReAct agent
@@ -55,21 +55,20 @@ def create_memory(
55
55
  storage_path="./memory"
56
56
  )
57
57
 
58
- # With LanceDB storage (SQL + vector search)
59
- from abstractllm import create_llm
60
- provider = create_llm("openai")
58
+ # With LanceDB storage (uses default all-MiniLM-L6-v2 embeddings)
61
59
  memory = create_memory("grounded",
62
60
  storage_backend="lancedb",
63
- storage_uri="./lance.db",
64
- embedding_provider=provider
61
+ storage_uri="./lance.db"
65
62
  )
66
63
 
67
- # With dual storage (both markdown and LanceDB)
64
+ # With custom embedding provider
65
+ from abstractmemory.embeddings.sentence_transformer_provider import create_sentence_transformer_provider
66
+ custom_provider = create_sentence_transformer_provider("bge-base-en-v1.5")
68
67
  memory = create_memory("grounded",
69
68
  storage_backend="dual",
70
69
  storage_path="./memory",
71
70
  storage_uri="./lance.db",
72
- embedding_provider=provider
71
+ embedding_provider=custom_provider
73
72
  )
74
73
  """
75
74
  if memory_type == "scratchpad":
@@ -77,6 +76,30 @@ def create_memory(
77
76
  elif memory_type == "buffer":
78
77
  return BufferMemory(**kwargs)
79
78
  elif memory_type == "grounded":
79
+ # Auto-configure default embedding provider if needed
80
+ storage_backend = kwargs.get('storage_backend')
81
+ embedding_provider = kwargs.get('embedding_provider')
82
+
83
+ # If storage requires embeddings but no provider specified, use default
84
+ if storage_backend in ['lancedb', 'dual'] and embedding_provider is None:
85
+ try:
86
+ from .embeddings.sentence_transformer_provider import create_sentence_transformer_provider
87
+ default_provider = create_sentence_transformer_provider("all-MiniLM-L6-v2")
88
+ kwargs['embedding_provider'] = default_provider
89
+
90
+ import logging
91
+ logging.info("Using default all-MiniLM-L6-v2 embedding model for semantic search")
92
+
93
+ except ImportError:
94
+ import logging
95
+ logging.warning(
96
+ "sentence-transformers not available. Install with: pip install sentence-transformers. "
97
+ "Vector search will not be available."
98
+ )
99
+ except Exception as e:
100
+ import logging
101
+ logging.warning(f"Could not initialize default embedding provider: {e}")
102
+
80
103
  return GroundedMemory(**kwargs)
81
104
  else:
82
105
  raise ValueError(f"Unknown memory type: {memory_type}")
@@ -243,6 +266,11 @@ class GroundedMemory:
243
266
  if interaction_id and note_id:
244
267
  self.storage_manager.link_interaction_to_note(interaction_id, note_id)
245
268
 
269
+ return interaction_id
270
+
271
+ # If no storage manager, return None (or could generate a simple ID)
272
+ return None
273
+
246
274
  def _extract_facts_to_kg(self, text: str, event_time: datetime):
247
275
  """Extract facts from text and add to KG"""
248
276
  # Simplified extraction - would use NLP/LLM in production
@@ -510,6 +538,23 @@ class GroundedMemory:
510
538
  for episode in episodes:
511
539
  context_parts.append(f"- {str(episode.content)[:100]}...")
512
540
 
541
+ # Get from storage manager (semantic search if available)
542
+ if hasattr(self, 'storage_manager') and self.storage_manager and hasattr(self.storage_manager, 'search_interactions'):
543
+ try:
544
+ storage_results = self.storage_manager.search_interactions(query, user_id=user_id, limit=max_items//2)
545
+ if storage_results:
546
+ context_parts.append("\n=== Recent Interactions ===")
547
+ for result in storage_results:
548
+ # Show both user input and agent response from stored interaction
549
+ if 'user_input' in result and 'agent_response' in result:
550
+ user_text = result['user_input'][:100]
551
+ agent_text = result['agent_response'][:100]
552
+ context_parts.append(f"User: {user_text}{'...' if len(result['user_input']) > 100 else ''}")
553
+ context_parts.append(f"Agent: {agent_text}{'...' if len(result['agent_response']) > 100 else ''}")
554
+ except Exception as e:
555
+ # Don't fail if storage search has issues
556
+ pass
557
+
513
558
  # Get from knowledge graph
514
559
  if self.kg:
515
560
  facts = self.kg.query_at_time(query, datetime.now())
@@ -57,6 +57,14 @@ class EmbeddingAdapter:
57
57
  except ImportError:
58
58
  pass
59
59
 
60
+ # Check for SentenceTransformer provider first (before AbstractCore check)
61
+ if hasattr(self.provider, 'model') and hasattr(self.provider, 'generate_embedding'):
62
+ # Check if it's our SentenceTransformerProvider
63
+ if hasattr(self.provider, 'model_name') and hasattr(self.provider, 'provider_name'):
64
+ # Additional check to distinguish from AbstractCore
65
+ if hasattr(self.provider, 'get_embedding_dimension') and hasattr(self.provider, 'get_model_info'):
66
+ return "sentence_transformers"
67
+
60
68
  # Check for AbstractCore provider with embedding support (has specific AbstractCore attributes)
61
69
  if hasattr(self.provider, 'generate_embedding') and hasattr(self.provider, 'provider_name'):
62
70
  return "abstractcore"
@@ -103,6 +111,19 @@ class EmbeddingAdapter:
103
111
  return len(test_embedding)
104
112
  except:
105
113
  return 1024 # Common Ollama embedding dimension
114
+ elif self.provider_type == "sentence_transformers":
115
+ # Get dimension directly from SentenceTransformer provider
116
+ try:
117
+ return self.provider.get_embedding_dimension()
118
+ except Exception as e:
119
+ logger.error(f"Failed to get dimension from SentenceTransformer provider: {e}")
120
+ # Fallback to test embedding
121
+ try:
122
+ test_embedding = self.provider.generate_embedding("dimension_test")
123
+ return len(test_embedding)
124
+ except Exception as e2:
125
+ logger.error(f"Fallback dimension test failed: {e2}")
126
+ raise ValueError(f"Unable to determine embedding dimension: {e}")
106
127
  elif self.provider_type == "generic_embedding_provider":
107
128
  # For any provider with generate_embedding method
108
129
  try:
@@ -142,6 +163,16 @@ class EmbeddingAdapter:
142
163
  info["backend"] = str(self.provider.backend)
143
164
  except Exception as e:
144
165
  logger.debug(f"Could not extract model info: {e}")
166
+ elif self.provider_type == "sentence_transformers":
167
+ # Get model info from SentenceTransformer provider
168
+ try:
169
+ provider_info = self.provider.get_model_info()
170
+ info.update(provider_info)
171
+ except Exception as e:
172
+ logger.debug(f"Could not extract SentenceTransformer model info: {e}")
173
+ # Fallback info
174
+ if hasattr(self.provider, 'model_name'):
175
+ info["model_name"] = self.provider.model_name
145
176
  elif self.provider_type == "openai":
146
177
  info["model_name"] = "text-embedding-3-small" # Default assumption
147
178
 
@@ -171,6 +202,8 @@ class EmbeddingAdapter:
171
202
  return self._generate_ollama_embedding(text)
172
203
  elif self.provider_type == "mlx":
173
204
  return self._generate_mlx_embedding(text)
205
+ elif self.provider_type == "sentence_transformers":
206
+ return self._generate_sentence_transformers_embedding(text)
174
207
  elif self.provider_type == "generic_embedding_provider":
175
208
  return self.provider.generate_embedding(text)
176
209
  else:
@@ -226,9 +259,13 @@ class EmbeddingAdapter:
226
259
  "Please use AbstractCore EmbeddingManager or another provider."
227
260
  )
228
261
 
262
+ def _generate_sentence_transformers_embedding(self, text: str) -> List[float]:
263
+ """Generate embedding using SentenceTransformer provider."""
264
+ return self.provider.generate_embedding(text)
265
+
229
266
  def is_real_embedding(self) -> bool:
230
267
  """Check if this adapter provides real semantic embeddings."""
231
- return self.provider_type in ["abstractcore_embeddings", "abstractcore", "openai", "ollama", "generic_embedding_provider"]
268
+ return self.provider_type in ["abstractcore_embeddings", "abstractcore", "openai", "ollama", "sentence_transformers", "generic_embedding_provider"]
232
269
 
233
270
  def get_embedding_info(self) -> dict:
234
271
  """Get comprehensive information about the embedding provider for consistency tracking."""
@@ -0,0 +1,159 @@
1
+ """
2
+ SentenceTransformer-based embedding provider for testing different models.
3
+ Supports BAAI/bge-base-en-v1.5, all-MiniLM-L6-v2, and other sentence-transformers models.
4
+ """
5
+
6
+ import logging
7
+ from typing import List, Optional
8
+ import numpy as np
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class SentenceTransformerProvider:
14
+ """
15
+ A provider for SentenceTransformer models that can be used with the EmbeddingAdapter.
16
+ Supports various models including BAAI/bge-base-en-v1.5 and all-MiniLM-L6-v2.
17
+ """
18
+
19
+ def __init__(self, model_name: str = "sentence-transformers/all-MiniLM-L6-v2", device: Optional[str] = None):
20
+ """
21
+ Initialize the SentenceTransformer provider.
22
+
23
+ Args:
24
+ model_name: Name of the sentence-transformers model to use
25
+ device: Device to run the model on ('cpu', 'cuda', or None for auto)
26
+ """
27
+ self.model_name = model_name
28
+ self.device = device
29
+ self.model = None
30
+ self.provider_name = f"sentence_transformers_{model_name.replace('/', '_').replace('-', '_')}"
31
+
32
+ try:
33
+ from sentence_transformers import SentenceTransformer
34
+ logger.info(f"Loading SentenceTransformer model: {model_name}")
35
+ self.model = SentenceTransformer(model_name, device=device)
36
+ logger.info(f"Successfully loaded model: {model_name}")
37
+ except ImportError:
38
+ raise ImportError(
39
+ "sentence-transformers library is required. Install with: "
40
+ "pip install sentence-transformers"
41
+ )
42
+ except Exception as e:
43
+ logger.error(f"Failed to load model {model_name}: {e}")
44
+ raise
45
+
46
+ def generate_embedding(self, text: str) -> List[float]:
47
+ """
48
+ Generate embedding for the given text.
49
+
50
+ Args:
51
+ text: Input text to embed
52
+
53
+ Returns:
54
+ List[float]: Embedding vector
55
+ """
56
+ if not self.model:
57
+ raise RuntimeError("Model not initialized")
58
+
59
+ try:
60
+ # Generate embedding and convert to list
61
+ embedding = self.model.encode([text], normalize_embeddings=True)[0]
62
+ if isinstance(embedding, np.ndarray):
63
+ return embedding.tolist()
64
+ return list(embedding)
65
+ except Exception as e:
66
+ logger.error(f"Failed to generate embedding: {e}")
67
+ raise
68
+
69
+ def generate_embeddings_batch(self, texts: List[str]) -> List[List[float]]:
70
+ """
71
+ Generate embeddings for a batch of texts (more efficient).
72
+
73
+ Args:
74
+ texts: List of input texts to embed
75
+
76
+ Returns:
77
+ List[List[float]]: List of embedding vectors
78
+ """
79
+ if not self.model:
80
+ raise RuntimeError("Model not initialized")
81
+
82
+ try:
83
+ # Generate embeddings and convert to list of lists
84
+ embeddings = self.model.encode(texts, normalize_embeddings=True)
85
+ if isinstance(embeddings, np.ndarray):
86
+ return embeddings.tolist()
87
+ return [list(emb) for emb in embeddings]
88
+ except Exception as e:
89
+ logger.error(f"Failed to generate batch embeddings: {e}")
90
+ raise
91
+
92
+ def get_embedding_dimension(self) -> int:
93
+ """Get the embedding dimension of the model."""
94
+ if not self.model:
95
+ raise RuntimeError("Model not initialized")
96
+ return self.model.get_sentence_embedding_dimension()
97
+
98
+ def get_model_info(self) -> dict:
99
+ """Get information about the model."""
100
+ return {
101
+ "model_name": self.model_name,
102
+ "provider": "sentence_transformers",
103
+ "dimension": self.get_embedding_dimension() if self.model else None,
104
+ "device": str(self.device) if self.device else "auto",
105
+ "provider_name": self.provider_name
106
+ }
107
+
108
+
109
+ # Common model configurations
110
+ MODEL_CONFIGS = {
111
+ "bge-base-en-v1.5": {
112
+ "model_name": "BAAI/bge-base-en-v1.5",
113
+ "dimension": 768,
114
+ "description": "BAAI BGE Base English v1.5 - High performance retrieval model",
115
+ "max_sequence_length": 512,
116
+ "parameters": "109M"
117
+ },
118
+ "all-MiniLM-L6-v2": {
119
+ "model_name": "sentence-transformers/all-MiniLM-L6-v2",
120
+ "dimension": 384,
121
+ "description": "All MiniLM L6 v2 - Fast and efficient sentence transformer",
122
+ "max_sequence_length": 256,
123
+ "parameters": "22M"
124
+ },
125
+ "all-mpnet-base-v2": {
126
+ "model_name": "sentence-transformers/all-mpnet-base-v2",
127
+ "dimension": 768,
128
+ "description": "All MPNet Base v2 - High quality general purpose model",
129
+ "max_sequence_length": 384,
130
+ "parameters": "109M"
131
+ },
132
+ "bge-small-en-v1.5": {
133
+ "model_name": "BAAI/bge-small-en-v1.5",
134
+ "dimension": 384,
135
+ "description": "BAAI BGE Small English v1.5 - Compact high performance model",
136
+ "max_sequence_length": 512,
137
+ "parameters": "33M"
138
+ }
139
+ }
140
+
141
+
142
+ def create_sentence_transformer_provider(model_key: str = "all-MiniLM-L6-v2",
143
+ device: Optional[str] = None) -> SentenceTransformerProvider:
144
+ """
145
+ Create a SentenceTransformer provider with a predefined model configuration.
146
+
147
+ Args:
148
+ model_key: Key from MODEL_CONFIGS or full model name
149
+ device: Device to run on
150
+
151
+ Returns:
152
+ SentenceTransformerProvider: Configured provider
153
+ """
154
+ if model_key in MODEL_CONFIGS:
155
+ model_name = MODEL_CONFIGS[model_key]["model_name"]
156
+ else:
157
+ model_name = model_key
158
+
159
+ return SentenceTransformerProvider(model_name, device)
@@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "AbstractMemory"
7
- version = "0.2.1"
7
+ version = "0.2.3"
8
8
  description = "Production-ready memory system for LLM agents - NO MOCKS, real semantic search, clear LLM vs embedding provider separation"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  authors = [
12
- {name = "AbstractMemory Team", email = "lpalbou@gmail.com"}
12
+ {name = "Laurent-Philippe Albou", email = "lpalbou@gmail.com"}
13
13
  ]
14
14
  maintainers = [
15
- {name = "AbstractMemory Team", email = "palbou@gmail.com"}
15
+ {name = "Laurent-Philippe Albou", email = "lpalbou@gmail.com"}
16
16
  ]
17
17
  keywords = ["llm", "memory", "semantic-search", "embeddings", "ai", "agents", "knowledge-graph", "temporal", "grounded-memory", "vector-search"]
18
18
  classifiers = [
@@ -36,15 +36,15 @@ dependencies = [
36
36
  [project.optional-dependencies]
37
37
  dev = ["pytest", "black", "mypy"]
38
38
  llm = ["abstractcore>=2.1.0"]
39
- embeddings = ["abstractcore>=2.1.0", "lancedb>=0.6.0"]
39
+ embeddings = ["abstractcore>=2.1.0", "lancedb>=0.6.0", "sentence-transformers>=2.0.0"]
40
40
  storage = ["lancedb>=0.6.0"]
41
- all = ["abstractcore>=2.1.0", "lancedb>=0.6.0"]
41
+ all = ["abstractcore>=2.1.0", "lancedb>=0.6.0", "sentence-transformers>=2.0.0"]
42
42
 
43
43
  [project.urls]
44
- Homepage = "https://github.com/lpalbou/AbstractAgent"
45
- Documentation = "https://github.com/lpalbou/AbstractAgent#readme"
46
- Repository = "https://github.com/lpalbou/AbstractAgent"
47
- "Bug Reports" = "https://github.com/lpalbou/AbstractAgent/issues"
44
+ Homepage = "https://github.com/lpalbou/AbstractMemory"
45
+ Documentation = "https://github.com/lpalbou/AbstractMemory#readme"
46
+ Repository = "https://github.com/lpalbou/AbstractMemory"
47
+ "Bug Reports" = "https://github.com/lpalbou/AbstractMemory/issues"
48
48
 
49
49
  [tool.setuptools.packages.find]
50
50
  where = ["."]
File without changes
File without changes