superlocalmemory 3.4.42 → 3.4.44
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/CHANGELOG.md +102 -0
- package/README.md +41 -0
- package/package.json +1 -1
- package/pyproject.toml +43 -38
- package/scripts/install.ps1 +19 -10
- package/scripts/install.sh +15 -21
- package/scripts/postinstall.js +9 -77
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/commands.py +57 -27
- package/src/superlocalmemory/core/embedding_worker.py +9 -8
- package/src/superlocalmemory/core/engine_wiring.py +10 -29
- package/src/superlocalmemory/hooks/before_web_hook.py +128 -0
- package/src/superlocalmemory/hooks/claude_code_hooks.py +57 -15
- package/src/superlocalmemory/hooks/hook_handlers.py +27 -15
- package/src/superlocalmemory/hooks/topic_shift_hook.py +272 -0
- package/src/superlocalmemory/server/unified_daemon.py +36 -3
|
@@ -1342,7 +1342,7 @@ def _start_memory_watchdog() -> None:
|
|
|
1342
1342
|
"""
|
|
1343
1343
|
import threading
|
|
1344
1344
|
|
|
1345
|
-
MAX_WORKER_MB =
|
|
1345
|
+
MAX_WORKER_MB = int(os.environ.get("SLM_MAX_WORKER_MB", "2500"))
|
|
1346
1346
|
|
|
1347
1347
|
def watchdog_loop():
|
|
1348
1348
|
while True:
|
|
@@ -1418,12 +1418,23 @@ def _start_pending_materializer() -> None:
|
|
|
1418
1418
|
for item in pending:
|
|
1419
1419
|
if _materializer_stop.is_set():
|
|
1420
1420
|
break
|
|
1421
|
-
# Yield to recalls: wait until none in flight
|
|
1422
1421
|
waits = 0
|
|
1423
1422
|
while _recalls_in_flight() > 0 and waits < 60:
|
|
1424
1423
|
time.sleep(0.5)
|
|
1425
1424
|
waits += 1
|
|
1426
1425
|
try:
|
|
1426
|
+
import hashlib
|
|
1427
|
+
content = item["content"]
|
|
1428
|
+
# Dedup: skip if identical content already stored.
|
|
1429
|
+
content_hash = hashlib.md5(content.encode()).hexdigest()
|
|
1430
|
+
dup = engine._db.execute(
|
|
1431
|
+
"SELECT 1 FROM atomic_facts WHERE "
|
|
1432
|
+
"content = ? LIMIT 1",
|
|
1433
|
+
(content,),
|
|
1434
|
+
)
|
|
1435
|
+
if dup:
|
|
1436
|
+
mark_done(item["id"])
|
|
1437
|
+
continue
|
|
1427
1438
|
import json as _json
|
|
1428
1439
|
md_str = item.get("metadata") or "{}"
|
|
1429
1440
|
try:
|
|
@@ -1432,7 +1443,29 @@ def _start_pending_materializer() -> None:
|
|
|
1432
1443
|
md = {}
|
|
1433
1444
|
if item.get("tags"):
|
|
1434
1445
|
md.setdefault("tags", item["tags"])
|
|
1435
|
-
|
|
1446
|
+
# Create memory row (FK target for atomic_facts)
|
|
1447
|
+
from datetime import datetime, timezone
|
|
1448
|
+
from superlocalmemory.storage.models import (
|
|
1449
|
+
AtomicFact, FactType,
|
|
1450
|
+
)
|
|
1451
|
+
mem_id = content_hash[:16]
|
|
1452
|
+
engine._db.execute(
|
|
1453
|
+
"INSERT OR IGNORE INTO memories "
|
|
1454
|
+
"(memory_id, profile_id, content, "
|
|
1455
|
+
"session_id, speaker, role, created_at, "
|
|
1456
|
+
"metadata_json) VALUES (?,?,?,?,?,?,?,?)",
|
|
1457
|
+
(mem_id, engine._profile_id, content,
|
|
1458
|
+
"", "", "user",
|
|
1459
|
+
datetime.now(timezone.utc).isoformat(),
|
|
1460
|
+
_json.dumps(md)),
|
|
1461
|
+
)
|
|
1462
|
+
fact = AtomicFact(
|
|
1463
|
+
content=content,
|
|
1464
|
+
fact_type=FactType.EPISODIC,
|
|
1465
|
+
memory_id=mem_id,
|
|
1466
|
+
profile_id=engine._profile_id,
|
|
1467
|
+
)
|
|
1468
|
+
engine.store_fact_direct(fact)
|
|
1436
1469
|
mark_done(item["id"])
|
|
1437
1470
|
except Exception as exc:
|
|
1438
1471
|
logger.warning(
|