superlocalmemory 3.5.0 → 3.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.5.0",
3
+ "version": "3.5.2",
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superlocalmemory"
3
- version = "3.5.0"
3
+ version = "3.5.2"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "AGPL-3.0-or-later"}
@@ -554,10 +554,12 @@ class DaemonHandler(BaseHTTPRequestHandler):
554
554
  for r in response.results[:limit]:
555
555
  fact_type = getattr(r.fact, "fact_type", None)
556
556
  lifecycle = getattr(r.fact, "lifecycle", None)
557
+ # v3.5.1: sanitize control chars that break JSON (newlines, tabs in content).
558
+ clean = r.fact.content.replace("\r", " ").replace("\n", " ").replace("\t", " ")
557
559
  results.append({
558
560
  "fact_id": r.fact.fact_id,
559
561
  "memory_id": r.fact.memory_id,
560
- "content": r.fact.content[:300],
562
+ "content": clean,
561
563
  "source_content": memory_map.get(r.fact.memory_id, ""),
562
564
  "score": round(r.score, 4),
563
565
  "confidence": round(r.confidence, 4),
@@ -617,18 +617,20 @@ async def lifespan(application: FastAPI):
617
617
  Named 'recall-warmup' so it appears clearly in thread dumps.
618
618
  """
619
619
  import time as _t
620
- # Wait for embedder to finish first (embed is needed by semantic channel)
621
620
  for _ in range(60):
622
621
  if _embedding_warm:
623
622
  break
624
623
  _t.sleep(0.5)
625
624
  try:
626
625
  t0 = _t.monotonic()
627
- response = engine.recall("memory recall performance", limit=1)
626
+ # Fire 2 warmup queries: one to load the graph page cache,
627
+ # second to warm the reranker subprocess + all 6 channels.
628
+ # Without this, dashboard POST /api/search hits 11s cold.
629
+ for wq in ("memory recall performance", "context injection retrieval"):
630
+ engine.recall(wq, limit=5)
628
631
  elapsed = round((_t.monotonic() - t0) * 1000)
629
632
  logger.info(
630
- "Recall engine pre-warmed in %dms — graph page cache now hot "
631
- "(results=%d)", elapsed, len(response.results),
633
+ "Recall engine pre-warmed in %dms", elapsed,
632
634
  )
633
635
  except Exception as exc:
634
636
  logger.warning("Recall warmup failed (non-fatal): %s", exc)
@@ -1794,14 +1796,14 @@ def _start_pending_materializer() -> None:
1794
1796
  if not _waiting_logged:
1795
1797
  logger.info("Materializer: waiting for engine to init...")
1796
1798
  _waiting_logged = True
1797
- time.sleep(2.0)
1799
+ time.sleep(0.5)
1798
1800
  continue
1799
1801
  if not _engine_logged:
1800
1802
  logger.info("Materializer: engine acquired, starting drain loop")
1801
1803
  _engine_logged = True
1802
- pending = get_pending(limit=5)
1804
+ pending = get_pending(limit=50)
1803
1805
  if not pending:
1804
- time.sleep(2.0)
1806
+ time.sleep(1.0)
1805
1807
  continue
1806
1808
  logger.info("Materializer: processing %d pending memories", len(pending))
1807
1809
  for item in pending:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superlocalmemory
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Information-geometric agent memory with mathematical guarantees
5
5
  Author-email: Varun Pratap Bhardwaj <admin@superlocalmemory.com>
6
6
  License: AGPL-3.0-or-later