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.
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/PKG-INFO +46 -25
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/SOURCES.txt +1 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/requires.txt +2 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/PKG-INFO +46 -25
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/README.md +37 -18
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/__init__.py +53 -8
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/embeddings/__init__.py +38 -1
- abstractmemory-0.2.3/abstractmemory/embeddings/sentence_transformer_provider.py +159 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/pyproject.toml +9 -9
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/dependency_links.txt +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/AbstractMemory.egg-info/top_level.txt +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/LICENSE +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/cognitive/__init__.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/__init__.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/core.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/episodic.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/semantic.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/components/working.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/__init__.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/interfaces.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/core/temporal.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/graph/__init__.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/graph/knowledge_graph.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/simple.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/__init__.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/dual_manager.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/lancedb_storage.py +0 -0
- {abstractmemory-0.2.1 → abstractmemory-0.2.3}/abstractmemory/storage/markdown_storage.py +0 -0
- {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.
|
|
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:
|
|
6
|
-
Maintainer-email:
|
|
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/
|
|
9
|
-
Project-URL: Documentation, https://github.com/lpalbou/
|
|
10
|
-
Project-URL: Repository, https://github.com/lpalbou/
|
|
11
|
-
Project-URL: Bug Reports, https://github.com/lpalbou/
|
|
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
|
|
170
|
+
High-performance search with default optimized embeddings:
|
|
169
171
|
|
|
170
172
|
```python
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
#
|
|
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=
|
|
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 (
|
|
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
|
|
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"
|
|
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
|
-
#
|
|
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 ~
|
|
368
|
+
# ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
|
|
359
369
|
|
|
360
|
-
#
|
|
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.
|
|
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:
|
|
6
|
-
Maintainer-email:
|
|
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/
|
|
9
|
-
Project-URL: Documentation, https://github.com/lpalbou/
|
|
10
|
-
Project-URL: Repository, https://github.com/lpalbou/
|
|
11
|
-
Project-URL: Bug Reports, https://github.com/lpalbou/
|
|
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
|
|
170
|
+
High-performance search with default optimized embeddings:
|
|
169
171
|
|
|
170
172
|
```python
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
#
|
|
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=
|
|
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 (
|
|
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
|
|
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"
|
|
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
|
-
#
|
|
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 ~
|
|
368
|
+
# ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
|
|
359
369
|
|
|
360
|
-
#
|
|
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
|
|
125
|
+
High-performance search with default optimized embeddings:
|
|
126
126
|
|
|
127
127
|
```python
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
#
|
|
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=
|
|
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 (
|
|
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
|
|
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"
|
|
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
|
-
#
|
|
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 ~
|
|
323
|
+
# ↳ Takes ~13ms: optimized all-MiniLM-L6-v2 embedding generated and stored
|
|
316
324
|
|
|
317
|
-
#
|
|
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:
|
|
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 (
|
|
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
|
|
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=
|
|
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.
|
|
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 = "
|
|
12
|
+
{name = "Laurent-Philippe Albou", email = "lpalbou@gmail.com"}
|
|
13
13
|
]
|
|
14
14
|
maintainers = [
|
|
15
|
-
{name = "
|
|
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/
|
|
45
|
-
Documentation = "https://github.com/lpalbou/
|
|
46
|
-
Repository = "https://github.com/lpalbou/
|
|
47
|
-
"Bug Reports" = "https://github.com/lpalbou/
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|