superlocalmemory 2.8.2 → 2.8.3
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 +7 -5
- package/api_server.py +5 -0
- package/bin/slm.bat +3 -3
- package/docs/SECURITY-QUICK-REFERENCE.md +214 -0
- package/install.ps1 +11 -11
- package/mcp_server.py +3 -3
- package/package.json +2 -2
- package/requirements-core.txt +16 -18
- package/requirements-learning.txt +8 -8
- package/requirements.txt +9 -7
- package/scripts/prepack.js +33 -0
- package/scripts/verify-v27.ps1 +301 -0
- package/src/agent_registry.py +32 -28
- package/src/auto_backup.py +12 -6
- package/src/cache_manager.py +2 -2
- package/src/compression/__init__.py +25 -0
- package/src/compression/cli.py +150 -0
- package/src/compression/cold_storage.py +217 -0
- package/src/compression/config.py +72 -0
- package/src/compression/orchestrator.py +133 -0
- package/src/compression/tier2_compressor.py +228 -0
- package/src/compression/tier3_compressor.py +153 -0
- package/src/compression/tier_classifier.py +148 -0
- package/src/db_connection_manager.py +5 -5
- package/src/event_bus.py +24 -22
- package/src/hnsw_index.py +3 -3
- package/src/learning/__init__.py +5 -4
- package/src/learning/adaptive_ranker.py +14 -265
- package/src/learning/bootstrap/__init__.py +69 -0
- package/src/learning/bootstrap/constants.py +93 -0
- package/src/learning/bootstrap/db_queries.py +316 -0
- package/src/learning/bootstrap/sampling.py +82 -0
- package/src/learning/bootstrap/text_utils.py +71 -0
- package/src/learning/cross_project_aggregator.py +58 -57
- package/src/learning/db/__init__.py +40 -0
- package/src/learning/db/constants.py +44 -0
- package/src/learning/db/schema.py +279 -0
- package/src/learning/learning_db.py +15 -234
- package/src/learning/ranking/__init__.py +33 -0
- package/src/learning/ranking/constants.py +84 -0
- package/src/learning/ranking/helpers.py +278 -0
- package/src/learning/source_quality_scorer.py +66 -65
- package/src/learning/synthetic_bootstrap.py +28 -310
- package/src/memory/__init__.py +36 -0
- package/src/memory/cli.py +205 -0
- package/src/memory/constants.py +39 -0
- package/src/memory/helpers.py +28 -0
- package/src/memory/schema.py +166 -0
- package/src/memory-profiles.py +94 -86
- package/src/memory-reset.py +187 -185
- package/src/memory_compression.py +2 -2
- package/src/memory_store_v2.py +34 -354
- package/src/migrate_v1_to_v2.py +11 -10
- package/src/patterns/analyzers.py +104 -100
- package/src/patterns/learner.py +17 -13
- package/src/patterns/scoring.py +25 -21
- package/src/patterns/store.py +40 -38
- package/src/patterns/terminology.py +53 -51
- package/src/provenance_tracker.py +2 -2
- package/src/qualixar_attribution.py +1 -1
- package/src/search/engine.py +16 -14
- package/src/search/index_loader.py +13 -11
- package/src/setup_validator.py +160 -158
- package/src/subscription_manager.py +20 -18
- package/src/tree/builder.py +66 -64
- package/src/tree/nodes.py +103 -97
- package/src/tree/queries.py +142 -137
- package/src/tree/schema.py +46 -42
- package/src/webhook_dispatcher.py +3 -3
- package/ui_server.py +7 -4
package/src/memory-reset.py
CHANGED
|
@@ -46,7 +46,7 @@ class MemoryReset:
|
|
|
46
46
|
print("⚠ No database found to backup")
|
|
47
47
|
return None
|
|
48
48
|
|
|
49
|
-
def soft_reset(self):
|
|
49
|
+
def soft_reset(self) -> None:
|
|
50
50
|
"""Clear all memories but keep V2 schema structure."""
|
|
51
51
|
print("\n" + "="*60)
|
|
52
52
|
print("SOFT RESET - Clear Memories, Keep Schema")
|
|
@@ -94,7 +94,7 @@ class MemoryReset:
|
|
|
94
94
|
print(" Schema preserved, all memories cleared")
|
|
95
95
|
print(" You can now add new memories to clean system")
|
|
96
96
|
|
|
97
|
-
def hard_reset(self):
|
|
97
|
+
def hard_reset(self) -> None:
|
|
98
98
|
"""Delete database completely and reinitialize with V2 schema."""
|
|
99
99
|
print("\n" + "="*60)
|
|
100
100
|
print("HARD RESET - Delete Everything & Reinitialize")
|
|
@@ -116,7 +116,7 @@ class MemoryReset:
|
|
|
116
116
|
print(" Fresh V2 database created")
|
|
117
117
|
print(" Ready for new memories")
|
|
118
118
|
|
|
119
|
-
def layer_reset(self, layers: list):
|
|
119
|
+
def layer_reset(self, layers: list) -> None:
|
|
120
120
|
"""Reset specific layers only."""
|
|
121
121
|
print("\n" + "="*60)
|
|
122
122
|
print(f"LAYER RESET - Clearing Layers: {', '.join(layers)}")
|
|
@@ -170,188 +170,190 @@ class MemoryReset:
|
|
|
170
170
|
def _initialize_v2_schema(self):
|
|
171
171
|
"""Initialize fresh V2 database schema."""
|
|
172
172
|
conn = sqlite3.connect(self.db_path)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
173
|
+
try:
|
|
174
|
+
cursor = conn.cursor()
|
|
175
|
+
|
|
176
|
+
# Layer 1: Memories table
|
|
177
|
+
cursor.execute('''
|
|
178
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
179
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
180
|
+
content TEXT NOT NULL,
|
|
181
|
+
summary TEXT,
|
|
182
|
+
project_path TEXT,
|
|
183
|
+
project_name TEXT,
|
|
184
|
+
tags TEXT,
|
|
185
|
+
category TEXT,
|
|
186
|
+
memory_type TEXT DEFAULT 'session',
|
|
187
|
+
importance INTEGER DEFAULT 5,
|
|
188
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
189
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
190
|
+
last_accessed TIMESTAMP,
|
|
191
|
+
access_count INTEGER DEFAULT 0,
|
|
192
|
+
content_hash TEXT UNIQUE,
|
|
193
|
+
parent_id INTEGER,
|
|
194
|
+
tree_path TEXT,
|
|
195
|
+
depth INTEGER DEFAULT 0,
|
|
196
|
+
cluster_id INTEGER,
|
|
197
|
+
tier INTEGER DEFAULT 1,
|
|
198
|
+
FOREIGN KEY (parent_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
199
|
+
)
|
|
200
|
+
''')
|
|
201
|
+
print(" ✓ Created memories table")
|
|
202
|
+
|
|
203
|
+
# FTS5 index
|
|
204
|
+
cursor.execute('''
|
|
205
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts
|
|
206
|
+
USING fts5(content, summary, tags, content='memories', content_rowid='id')
|
|
207
|
+
''')
|
|
208
|
+
print(" ✓ Created FTS index")
|
|
209
|
+
|
|
210
|
+
# Layer 2: Tree
|
|
211
|
+
cursor.execute('''
|
|
212
|
+
CREATE TABLE IF NOT EXISTS memory_tree (
|
|
213
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
214
|
+
node_type TEXT NOT NULL,
|
|
215
|
+
name TEXT NOT NULL,
|
|
216
|
+
description TEXT,
|
|
217
|
+
parent_id INTEGER,
|
|
218
|
+
tree_path TEXT NOT NULL,
|
|
219
|
+
depth INTEGER DEFAULT 0,
|
|
220
|
+
memory_count INTEGER DEFAULT 0,
|
|
221
|
+
total_size INTEGER DEFAULT 0,
|
|
222
|
+
last_updated TIMESTAMP,
|
|
223
|
+
memory_id INTEGER,
|
|
224
|
+
FOREIGN KEY (parent_id) REFERENCES memory_tree(id) ON DELETE CASCADE,
|
|
225
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
226
|
+
)
|
|
227
|
+
''')
|
|
228
|
+
print(" ✓ Created memory_tree table")
|
|
229
|
+
|
|
230
|
+
# Layer 3: Graph
|
|
231
|
+
cursor.execute('''
|
|
232
|
+
CREATE TABLE IF NOT EXISTS graph_nodes (
|
|
233
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
234
|
+
memory_id INTEGER UNIQUE NOT NULL,
|
|
235
|
+
entities TEXT,
|
|
236
|
+
embedding_vector TEXT,
|
|
237
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
238
|
+
)
|
|
239
|
+
''')
|
|
240
|
+
|
|
241
|
+
cursor.execute('''
|
|
242
|
+
CREATE TABLE IF NOT EXISTS graph_edges (
|
|
243
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
244
|
+
source_memory_id INTEGER NOT NULL,
|
|
245
|
+
target_memory_id INTEGER NOT NULL,
|
|
246
|
+
relationship_type TEXT,
|
|
247
|
+
weight REAL DEFAULT 1.0,
|
|
248
|
+
shared_entities TEXT,
|
|
249
|
+
similarity_score REAL,
|
|
250
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
251
|
+
FOREIGN KEY (source_memory_id) REFERENCES memories(id) ON DELETE CASCADE,
|
|
252
|
+
FOREIGN KEY (target_memory_id) REFERENCES memories(id) ON DELETE CASCADE,
|
|
253
|
+
UNIQUE(source_memory_id, target_memory_id)
|
|
254
|
+
)
|
|
255
|
+
''')
|
|
256
|
+
|
|
257
|
+
cursor.execute('''
|
|
258
|
+
CREATE TABLE IF NOT EXISTS graph_clusters (
|
|
259
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
260
|
+
name TEXT NOT NULL,
|
|
261
|
+
description TEXT,
|
|
262
|
+
member_count INTEGER DEFAULT 0,
|
|
263
|
+
avg_importance REAL,
|
|
264
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
265
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
266
|
+
)
|
|
267
|
+
''')
|
|
268
|
+
print(" ✓ Created graph tables")
|
|
269
|
+
|
|
270
|
+
# Layer 4: Patterns
|
|
271
|
+
cursor.execute('''
|
|
272
|
+
CREATE TABLE IF NOT EXISTS identity_patterns (
|
|
273
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
274
|
+
pattern_type TEXT NOT NULL,
|
|
275
|
+
key TEXT NOT NULL,
|
|
276
|
+
value TEXT NOT NULL,
|
|
277
|
+
confidence REAL DEFAULT 0.5,
|
|
278
|
+
evidence_count INTEGER DEFAULT 1,
|
|
279
|
+
memory_ids TEXT,
|
|
280
|
+
category TEXT,
|
|
281
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
282
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
283
|
+
UNIQUE(pattern_type, key, category)
|
|
284
|
+
)
|
|
285
|
+
''')
|
|
286
|
+
|
|
287
|
+
cursor.execute('''
|
|
288
|
+
CREATE TABLE IF NOT EXISTS pattern_examples (
|
|
289
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
290
|
+
pattern_id INTEGER NOT NULL,
|
|
291
|
+
memory_id INTEGER NOT NULL,
|
|
292
|
+
example_text TEXT,
|
|
293
|
+
FOREIGN KEY (pattern_id) REFERENCES identity_patterns(id) ON DELETE CASCADE,
|
|
294
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
295
|
+
)
|
|
296
|
+
''')
|
|
297
|
+
print(" ✓ Created pattern tables")
|
|
298
|
+
|
|
299
|
+
# Archive table
|
|
300
|
+
cursor.execute('''
|
|
301
|
+
CREATE TABLE IF NOT EXISTS memory_archive (
|
|
302
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
303
|
+
memory_id INTEGER UNIQUE NOT NULL,
|
|
304
|
+
full_content TEXT NOT NULL,
|
|
305
|
+
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
306
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id) ON DELETE CASCADE
|
|
307
|
+
)
|
|
308
|
+
''')
|
|
309
|
+
print(" ✓ Created archive table")
|
|
310
|
+
|
|
311
|
+
# Sessions table
|
|
312
|
+
cursor.execute('''
|
|
313
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
314
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
315
|
+
session_id TEXT UNIQUE,
|
|
316
|
+
project_path TEXT,
|
|
317
|
+
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
318
|
+
ended_at TIMESTAMP,
|
|
319
|
+
summary TEXT
|
|
320
|
+
)
|
|
321
|
+
''')
|
|
322
|
+
print(" ✓ Created sessions table")
|
|
323
|
+
|
|
324
|
+
# System metadata
|
|
325
|
+
cursor.execute('''
|
|
326
|
+
CREATE TABLE IF NOT EXISTS system_metadata (
|
|
327
|
+
key TEXT PRIMARY KEY,
|
|
328
|
+
value TEXT,
|
|
329
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
330
|
+
)
|
|
331
|
+
''')
|
|
332
|
+
|
|
333
|
+
cursor.execute('''
|
|
334
|
+
INSERT OR REPLACE INTO system_metadata (key, value)
|
|
335
|
+
VALUES ('schema_version', '2.0.0')
|
|
336
|
+
''')
|
|
337
|
+
print(" ✓ Created metadata table")
|
|
338
|
+
|
|
339
|
+
# Create indexes
|
|
340
|
+
indexes = [
|
|
341
|
+
'CREATE INDEX IF NOT EXISTS idx_project ON memories(project_path)',
|
|
342
|
+
'CREATE INDEX IF NOT EXISTS idx_category ON memories(category)',
|
|
343
|
+
'CREATE INDEX IF NOT EXISTS idx_cluster ON memories(cluster_id)',
|
|
344
|
+
'CREATE INDEX IF NOT EXISTS idx_tree_path ON memories(tree_path)',
|
|
345
|
+
'CREATE INDEX IF NOT EXISTS idx_tier ON memories(tier)',
|
|
346
|
+
'CREATE INDEX IF NOT EXISTS idx_graph_source ON graph_edges(source_memory_id)',
|
|
347
|
+
'CREATE INDEX IF NOT EXISTS idx_graph_target ON graph_edges(target_memory_id)',
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
for idx_sql in indexes:
|
|
351
|
+
cursor.execute(idx_sql)
|
|
352
|
+
print(" ✓ Created indexes")
|
|
353
|
+
|
|
354
|
+
conn.commit()
|
|
355
|
+
finally:
|
|
356
|
+
conn.close()
|
|
355
357
|
|
|
356
358
|
def show_stats(self):
|
|
357
359
|
"""Show current database statistics."""
|
|
@@ -45,7 +45,7 @@ class CompressionConfig:
|
|
|
45
45
|
return json.load(f)
|
|
46
46
|
return {}
|
|
47
47
|
|
|
48
|
-
def save(self):
|
|
48
|
+
def save(self) -> None:
|
|
49
49
|
"""Save configuration back to config.json."""
|
|
50
50
|
with open(CONFIG_PATH, 'w') as f:
|
|
51
51
|
json.dump(self.config, f, indent=2)
|
|
@@ -74,7 +74,7 @@ class CompressionConfig:
|
|
|
74
74
|
def preserve_recently_accessed(self) -> bool:
|
|
75
75
|
return self.compression_settings.get('preserve_recently_accessed', True)
|
|
76
76
|
|
|
77
|
-
def initialize_defaults(self):
|
|
77
|
+
def initialize_defaults(self) -> None:
|
|
78
78
|
"""Initialize compression settings in config if not present."""
|
|
79
79
|
if 'compression' not in self.config:
|
|
80
80
|
self.config['compression'] = {
|