superlocalmemory 3.4.61 → 3.4.62
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
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to SuperLocalMemory V3 will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.4.62] - 2026-05-31 — Recall engine pre-warm on startup
|
|
9
|
+
|
|
10
|
+
Adds a `recall-warmup` background thread that fires one full 6-channel recall
|
|
11
|
+
immediately after daemon startup. This loads the graph_edges table (~100 MB,
|
|
12
|
+
347K rows) into SQLite's page cache before the first user query arrives.
|
|
13
|
+
|
|
14
|
+
Without this, cold first query = 15-24s (reading graph_edges from disk).
|
|
15
|
+
After this warmup, all queries hit warm cache at <2s — for both MCP and dashboard.
|
|
16
|
+
Warmup is non-blocking (daemon stays available), fires after embedding warm.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- `server/unified_daemon.py`: `_warmup_recall()` thread fires after `_warmup_embedder()`
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
8
23
|
## [3.4.61] - 2026-05-31 — Dashboard search fix (in-process engine)
|
|
9
24
|
|
|
10
25
|
**Fixes dashboard search always timing out** with "signal is aborted without reason".
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superlocalmemory",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.62",
|
|
4
4
|
"description": "Information-geometric agent memory with mathematical guarantees. 4-channel retrieval, Fisher-Rao similarity, zero-LLM mode, EU AI Act compliant. Works with Claude, Cursor, Windsurf, and 17+ AI tools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-memory",
|
package/pyproject.toml
CHANGED
|
@@ -28,7 +28,7 @@ if "OMP_NUM_THREADS" not in os.environ:
|
|
|
28
28
|
os.environ["OMP_NUM_THREADS"] = "2"
|
|
29
29
|
# ---------------------------------------------------------------------------
|
|
30
30
|
|
|
31
|
-
__version__ = "3.4.
|
|
31
|
+
__version__ = "3.4.62"
|
|
32
32
|
|
|
33
33
|
_REQUIRED_VERSIONS = {
|
|
34
34
|
"sentence_transformers": "5.3.0",
|
|
@@ -574,7 +574,37 @@ async def lifespan(application: FastAPI):
|
|
|
574
574
|
logger.info("Embedding worker pre-warmed (model resident, keep_alive=-1)")
|
|
575
575
|
except Exception as exc:
|
|
576
576
|
logger.warning("Embedding warmup failed: %s", exc)
|
|
577
|
+
|
|
578
|
+
def _warmup_recall():
|
|
579
|
+
"""v3.4.62: Fire a full 6-channel recall after embedding warms up.
|
|
580
|
+
|
|
581
|
+
Loads the graph_edges table (347K rows, ~100 MB) into the SQLite
|
|
582
|
+
page cache. Without this, the first user query takes 15-24s because
|
|
583
|
+
it reads graph_edges from disk. After this warmup completes, all
|
|
584
|
+
subsequent queries hit the warm page cache at <2s.
|
|
585
|
+
|
|
586
|
+
Runs after embedding warm (embed first so recall can use it).
|
|
587
|
+
Named 'recall-warmup' so it appears clearly in thread dumps.
|
|
588
|
+
"""
|
|
589
|
+
import time as _t
|
|
590
|
+
# Wait for embedder to finish first (embed is needed by semantic channel)
|
|
591
|
+
for _ in range(60):
|
|
592
|
+
if _embedding_warm:
|
|
593
|
+
break
|
|
594
|
+
_t.sleep(0.5)
|
|
595
|
+
try:
|
|
596
|
+
t0 = _t.monotonic()
|
|
597
|
+
response = engine.recall("memory recall performance", limit=1)
|
|
598
|
+
elapsed = round((_t.monotonic() - t0) * 1000)
|
|
599
|
+
logger.info(
|
|
600
|
+
"Recall engine pre-warmed in %dms — graph page cache now hot "
|
|
601
|
+
"(results=%d)", elapsed, len(response.results),
|
|
602
|
+
)
|
|
603
|
+
except Exception as exc:
|
|
604
|
+
logger.warning("Recall warmup failed (non-fatal): %s", exc)
|
|
605
|
+
|
|
577
606
|
threading.Thread(target=_warmup_embedder, daemon=True, name="embed-warmup").start()
|
|
607
|
+
threading.Thread(target=_warmup_recall, daemon=True, name="recall-warmup").start()
|
|
578
608
|
|
|
579
609
|
# v3.4.37: QueueConsumer uses daemon's engine directly via adapter.
|
|
580
610
|
# Previously routed through WorkerPool → recall_worker subprocess,
|