superlocalmemory 3.6.16 → 3.6.18
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 +25 -0
- package/README.md +3 -2
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/agents/slm-memory-advisor.md +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/manifest.json +1 -1
- package/plugin-src/requirements.txt +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/rules/CLAUDE.md.fragment +3 -3
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/pyproject.toml +3 -2
- package/scripts/build-plugin.js +1 -1
- package/scripts/postinstall-interactive.js +94 -7
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/setup_wizard.py +34 -0
- package/src/superlocalmemory/core/embeddings.py +5 -0
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +4 -0
- package/src/superlocalmemory/hooks/adapter_base.py +10 -3
- package/src/superlocalmemory/hooks/claude_code_hooks.py +40 -4
- package/src/superlocalmemory/hooks/copilot_adapter.py +78 -9
- package/src/superlocalmemory/hooks/hook_handlers.py +59 -1
- package/src/superlocalmemory/hooks/memory_protocol.py +102 -0
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +23 -5
- package/src/superlocalmemory/infra/event_bus.py +4 -0
- package/src/superlocalmemory/learning/feedback.py +59 -0
- package/src/superlocalmemory/learning/outcome_queue.py +10 -2
- package/src/superlocalmemory/llm/backbone.py +8 -1
- package/src/superlocalmemory/retrieval/reranker.py +5 -0
- package/src/superlocalmemory/server/routes/learning.py +2 -0
- package/src/superlocalmemory/server/routes/v3_api.py +11 -0
- package/src/superlocalmemory/server/unified_daemon.py +78 -0
- package/src/superlocalmemory/storage/database.py +34 -7
- package/src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py +79 -0
- package/src/superlocalmemory.egg-info/PKG-INFO +4 -3
- package/src/superlocalmemory.egg-info/SOURCES.txt +2 -0
- package/plugin-src/commands/slm-optimize.md +0 -22
- package/plugin-src/commands/slm-recall.md +0 -16
- package/plugin-src/commands/slm-remember.md +0 -16
- package/plugin-src/commands/slm-status.md +0 -15
|
@@ -12,7 +12,7 @@ Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
-
import json, logging, sqlite3, threading, time
|
|
15
|
+
import json, logging, os, sqlite3, threading, time
|
|
16
16
|
from contextlib import contextmanager
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from types import ModuleType
|
|
@@ -27,10 +27,16 @@ from superlocalmemory.storage.models import (
|
|
|
27
27
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
_MISSING = object()
|
|
31
|
+
|
|
32
|
+
def _jl(raw: Any, default: Any = _MISSING) -> Any:
|
|
33
|
+
"""JSON-load a value, returning *default* on None/empty.
|
|
34
|
+
|
|
35
|
+
_jl(raw) -> [] when raw is None/empty (list fields)
|
|
36
|
+
_jl(raw, None) -> None when raw is None/empty (optional fields)
|
|
37
|
+
"""
|
|
32
38
|
if raw is None or raw == "":
|
|
33
|
-
return
|
|
39
|
+
return [] if default is _MISSING else default
|
|
34
40
|
return json.loads(raw)
|
|
35
41
|
|
|
36
42
|
def _jd(val: Any) -> str | None:
|
|
@@ -38,9 +44,30 @@ def _jd(val: Any) -> str | None:
|
|
|
38
44
|
return json.dumps(val) if val is not None else None
|
|
39
45
|
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
def _env_int(name: str, default: int) -> int:
|
|
48
|
+
"""Read a positive int from the environment, falling back on bad/absent."""
|
|
49
|
+
try:
|
|
50
|
+
val = int(os.environ.get(name, "").strip())
|
|
51
|
+
return val if val > 0 else default
|
|
52
|
+
except (ValueError, AttributeError):
|
|
53
|
+
return default
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _env_float(name: str, default: float) -> float:
|
|
57
|
+
"""Read a positive float from the environment, falling back on bad/absent."""
|
|
58
|
+
try:
|
|
59
|
+
val = float(os.environ.get(name, "").strip())
|
|
60
|
+
return val if val > 0 else default
|
|
61
|
+
except (ValueError, AttributeError):
|
|
62
|
+
return default
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# SQLite endurance tuning. Defaults preserve prior hard-coded behaviour exactly;
|
|
66
|
+
# operators on slow/contended I/O can raise them via env (issue #53) without a
|
|
67
|
+
# code change. Unset env => byte-identical to the previous constants.
|
|
68
|
+
_BUSY_TIMEOUT_MS = _env_int("SLM_DB_BUSY_TIMEOUT_MS", 10_000) # wait for writers
|
|
69
|
+
_MAX_RETRIES = _env_int("SLM_DB_MAX_RETRIES", 5) # retry on SQLITE_BUSY
|
|
70
|
+
_RETRY_BASE_DELAY = _env_float("SLM_DB_RETRY_BASE_DELAY", 0.1) # backoff base (s)
|
|
44
71
|
|
|
45
72
|
|
|
46
73
|
def _scope_where(
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
2
|
+
# Licensed under AGPL-3.0-or-later - see LICENSE file
|
|
3
|
+
# Part of SuperLocalMemory v3.6.18
|
|
4
|
+
|
|
5
|
+
"""M017 — scope column on ccq_consolidated_blocks.
|
|
6
|
+
|
|
7
|
+
The cognitive-consolidation queue table (``ccq_consolidated_blocks``) was
|
|
8
|
+
created before the M016 multi-scope migration and therefore has no ``scope``
|
|
9
|
+
column. Without it, consolidation summaries are always stored as
|
|
10
|
+
``personal`` regardless of the source facts' scope — a silent data-loss edge
|
|
11
|
+
case when a user has opted into global or shared memory.
|
|
12
|
+
|
|
13
|
+
Fix: add a ``scope TEXT NOT NULL DEFAULT 'personal'`` column plus a
|
|
14
|
+
``(profile_id, scope)`` covering index for scope-filtered queries.
|
|
15
|
+
|
|
16
|
+
Deferred (like M006, M011, M013, M016): the CCQ table is created by the
|
|
17
|
+
engine, not by migration DDL, so we apply after engine init via
|
|
18
|
+
``apply_deferred``.
|
|
19
|
+
|
|
20
|
+
Author: Varun Pratap Bhardwaj / Qualixar
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import sqlite3
|
|
26
|
+
|
|
27
|
+
NAME = "M017_ccq_scope_column"
|
|
28
|
+
DB_TARGET = "memory"
|
|
29
|
+
|
|
30
|
+
TABLE = "ccq_consolidated_blocks"
|
|
31
|
+
|
|
32
|
+
DDL = (
|
|
33
|
+
f"ALTER TABLE {TABLE} ADD COLUMN scope TEXT NOT NULL DEFAULT 'personal';"
|
|
34
|
+
f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_scope ON {TABLE}(scope);"
|
|
35
|
+
f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_profile_scope ON {TABLE}(profile_id, scope);"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _table_exists(conn: sqlite3.Connection, table: str) -> bool:
|
|
40
|
+
return conn.execute(
|
|
41
|
+
"SELECT 1 FROM sqlite_master WHERE type='table' AND name=?", (table,)
|
|
42
|
+
).fetchone() is not None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _column_names(conn: sqlite3.Connection, table: str) -> set[str]:
|
|
46
|
+
return {r[1] for r in conn.execute(f"PRAGMA table_info({table})").fetchall()}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def apply(conn: sqlite3.Connection) -> None:
|
|
50
|
+
"""Idempotently add scope column + indexes to ccq_consolidated_blocks.
|
|
51
|
+
|
|
52
|
+
Skips silently when the table doesn't exist yet (engine hasn't created it)
|
|
53
|
+
or when the column is already present (re-apply or fresh install).
|
|
54
|
+
"""
|
|
55
|
+
if not _table_exists(conn, TABLE):
|
|
56
|
+
return
|
|
57
|
+
cols = _column_names(conn, TABLE)
|
|
58
|
+
if "scope" not in cols:
|
|
59
|
+
conn.execute(
|
|
60
|
+
f"ALTER TABLE {TABLE} ADD COLUMN scope TEXT NOT NULL DEFAULT 'personal'"
|
|
61
|
+
)
|
|
62
|
+
conn.execute(f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_scope ON {TABLE}(scope)")
|
|
63
|
+
conn.execute(
|
|
64
|
+
f"CREATE INDEX IF NOT EXISTS idx_{TABLE}_profile_scope ON {TABLE}(profile_id, scope)"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def verify(conn: sqlite3.Connection) -> bool:
|
|
69
|
+
"""Applied when ccq_consolidated_blocks has the scope column and index."""
|
|
70
|
+
if not _table_exists(conn, TABLE):
|
|
71
|
+
return True # table absent — apply() skips it; nothing to verify
|
|
72
|
+
cols = _column_names(conn, TABLE)
|
|
73
|
+
if "scope" not in cols:
|
|
74
|
+
return False
|
|
75
|
+
idx = conn.execute(
|
|
76
|
+
"SELECT 1 FROM sqlite_master WHERE type='index' AND name=?",
|
|
77
|
+
(f"idx_{TABLE}_scope",),
|
|
78
|
+
).fetchone()
|
|
79
|
+
return idx is not None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superlocalmemory
|
|
3
|
-
Version: 3.6.
|
|
3
|
+
Version: 3.6.18
|
|
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
|
|
@@ -96,10 +96,10 @@ Dynamic: license-file
|
|
|
96
96
|
<img src="https://superlocalmemory.com/assets/logo-mark.png" alt="SuperLocalMemory" width="200"/>
|
|
97
97
|
</p>
|
|
98
98
|
|
|
99
|
-
<h1 align="center">SuperLocalMemory V3.6.
|
|
99
|
+
<h1 align="center">SuperLocalMemory V3.6.18</h1>
|
|
100
100
|
<p align="center"><strong>Cache. Compress. Remember. Three surfaces — proxy, MCP tools, or skill. Every setup covered.</strong><br/>
|
|
101
101
|
<em>To the best of our knowledge, the only zero-cloud agent memory that beats Mem0's zero-LLM score on LoCoMo. Mode A: 74.8% vs Mem0 64.2% — no GPU, no API key, on CPU.</em></p>
|
|
102
|
-
<p align="center"><code>v3.6.
|
|
102
|
+
<p align="center"><code>v3.6.18</code> — <strong>Plugin-native. Profile-aware. Distributed-ready.</strong><br/>
|
|
103
103
|
Proxy: <code>slm wrap claude</code> · MCP: add <code>slm_compress</code> to your config · Skill: zero-config</p>
|
|
104
104
|
<p align="center"><strong>3 published research papers</strong> (arXiv preprints + Zenodo-archived) · <a href="https://arxiv.org/abs/2603.02240">arXiv:2603.02240</a> · <a href="https://arxiv.org/abs/2603.14588">arXiv:2603.14588</a> · <a href="https://arxiv.org/abs/2604.04514">arXiv:2604.04514</a></p>
|
|
105
105
|
|
|
@@ -401,6 +401,7 @@ slm dashboard # Opens at http://localhost:8765
|
|
|
401
401
|
|
|
402
402
|
| Version | Codename | Key Features |
|
|
403
403
|
|---|---|---|
|
|
404
|
+
| **v3.6.17** | Community | 8 contributor PRs (observability events, marker-bounded adapter writes, daemon port discovery, anthropic `api_base`, OpenMP workers, atomic-write rehash, `_jl` sentinel, LFS pointer); dashboard-feedback fix (#53/#59); env-tunable SQLite knobs + idle backoff; remote LLM test-probe (#40) |
|
|
404
405
|
| **v3.6.16** | Docs | Corrected Claude Code plugin install — adds the required `/plugin marketplace add` step; clarifies plugin vs pip/npm delivery |
|
|
405
406
|
| **v3.6.15** | Multi-scope | **Opt-in [shared memory](docs/shared-memory.md)** (personal/shared/global, off by default), default-deny scope at every read path, recall scope-race fix, contributor PRs #42/#43/#44, fixes #46–#49 |
|
|
406
407
|
| **v3.6.14** | Plugin-native | Claude Code Plugin (WP-06), MCP profiles (WP-01), IDE connect (WP-08), asset consolidation, UI polish (WP-12) |
|
|
@@ -177,6 +177,7 @@ src/superlocalmemory/hooks/cursor_adapter.py
|
|
|
177
177
|
src/superlocalmemory/hooks/hook_daemon.py
|
|
178
178
|
src/superlocalmemory/hooks/hook_handlers.py
|
|
179
179
|
src/superlocalmemory/hooks/ide_connector.py
|
|
180
|
+
src/superlocalmemory/hooks/memory_protocol.py
|
|
180
181
|
src/superlocalmemory/hooks/portable_kit.py
|
|
181
182
|
src/superlocalmemory/hooks/post_tool_async_hook.py
|
|
182
183
|
src/superlocalmemory/hooks/post_tool_outcome_hook.py
|
|
@@ -434,6 +435,7 @@ src/superlocalmemory/storage/migrations/M013_bi_temporal_columns.py
|
|
|
434
435
|
src/superlocalmemory/storage/migrations/M014_v345_scale_ready.py
|
|
435
436
|
src/superlocalmemory/storage/migrations/M015_add_pinned_column.py
|
|
436
437
|
src/superlocalmemory/storage/migrations/M016_add_scope_support.py
|
|
438
|
+
src/superlocalmemory/storage/migrations/M017_ccq_scope_column.py
|
|
437
439
|
src/superlocalmemory/storage/migrations/__init__.py
|
|
438
440
|
src/superlocalmemory/trust/__init__.py
|
|
439
441
|
src/superlocalmemory/trust/gate.py
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Apply SLM context-optimization (compress large output / cache repeats) and report savings.
|
|
3
|
-
argument-hint: [stats]
|
|
4
|
-
allowed-tools: slm_compress, slm_cache_set, slm_cache_get, slm_optimize_stats, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Apply SuperLocalMemory context-optimization. Arguments: $ARGUMENTS
|
|
8
|
-
|
|
9
|
-
If arguments are empty or "stats":
|
|
10
|
-
- Call `slm_optimize_stats()` and report: cache_kv_hits, compress_runs, tokens_saved_compress.
|
|
11
|
-
|
|
12
|
-
If there is large output to compress (>2000 chars):
|
|
13
|
-
- Call `slm_compress(content=<output>, mode="auto", reversible=True)`.
|
|
14
|
-
- Work from the compressed form; retain ccr_id if the result is lossy.
|
|
15
|
-
|
|
16
|
-
Rules (apply strictly):
|
|
17
|
-
- Rule 6 — NEVER compress/cache: code intended for Edit/Write; JSON being parsed; secrets/keys/tokens; ccr_ids; content <500 chars.
|
|
18
|
-
- Rule 8 — FAIL-OPEN: if ok:false, continue with original; do not retry; do not surface the error unless the user asks.
|
|
19
|
-
|
|
20
|
-
MCP unavailable → CLI fallback: `slm optimize status`.
|
|
21
|
-
|
|
22
|
-
SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Recall relevant facts and decisions from SuperLocalMemory by query.
|
|
3
|
-
argument-hint: <what to recall>
|
|
4
|
-
allowed-tools: recall, search, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Recall from SuperLocalMemory using the query: $ARGUMENTS
|
|
8
|
-
|
|
9
|
-
1. Call `recall(query="$ARGUMENTS", limit=10)` via MCP.
|
|
10
|
-
2. If no confident match or count==0, also call `search("$ARGUMENTS", 10)`.
|
|
11
|
-
3. Present results concisely — fact, tags, importance, date. Never invent or fabricate a memory.
|
|
12
|
-
4. If MCP is unavailable, fall back to CLI:
|
|
13
|
-
- `slm recall "$ARGUMENTS" --limit 10`
|
|
14
|
-
- then `slm search "$ARGUMENTS"`
|
|
15
|
-
|
|
16
|
-
SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Save an atomic fact or decision to SuperLocalMemory.
|
|
3
|
-
argument-hint: <the fact> [#tag1,tag2]
|
|
4
|
-
allowed-tools: recall, remember, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Save to SuperLocalMemory: $ARGUMENTS
|
|
8
|
-
|
|
9
|
-
1. First call `recall("$ARGUMENTS", 5)` — dedupe check. If a near-identical memory exists, tell the user and stop; delegate to slm-memory-advisor to update_memory if a correction is needed.
|
|
10
|
-
2. Extract tags from any trailing `#tag1,tag2` pattern in the arguments.
|
|
11
|
-
3. Determine importance: use 8 for blockers/security/architecture decisions; use 7 for conventions and constraints; use 5 for general facts.
|
|
12
|
-
4. Call `remember(content="$ARGUMENTS", tags=<extracted tags>, importance=<n>)`.
|
|
13
|
-
5. Confirm only on success:true. If success is not true, report the error — never claim "saved."
|
|
14
|
-
6. MCP unavailable → CLI fallback: `slm remember "$ARGUMENTS" --tags <tags>` (note: `--importance` is MCP-only, not a CLI flag).
|
|
15
|
-
|
|
16
|
-
SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Show SuperLocalMemory health and optimization counters.
|
|
3
|
-
argument-hint: (no arguments)
|
|
4
|
-
allowed-tools: slm_optimize_stats, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Show SuperLocalMemory status and optimization counters.
|
|
8
|
-
|
|
9
|
-
1. Run `slm status` via Bash — this is the canonical health check (memory count, profile, daemon state, integrity).
|
|
10
|
-
2. Also call `slm_optimize_stats()` via MCP for Surface-B counters (cache_kv_hits, compress_runs, tokens_saved_compress). If ok:false, omit silently — do not surface the error.
|
|
11
|
-
3. Summarize both outputs in a concise report. Flag any integrity warnings from `slm status`.
|
|
12
|
-
|
|
13
|
-
Note: MCP get_status is intentionally NOT used here — it is outside the core profile and would error. Use `slm status` (CLI) + `slm_optimize_stats` (MCP) only.
|
|
14
|
-
|
|
15
|
-
SuperLocalMemory v3.6.16 · Qualixar · AGPL-3.0-or-later
|