superlocalmemory 3.6.9 → 3.6.11

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +112 -10
  2. package/README.md +67 -9
  3. package/package.json +1 -1
  4. package/pyproject.toml +6 -1
  5. package/skills/slm-optimize/README.md +55 -0
  6. package/skills/slm-optimize/SKILL.md +139 -0
  7. package/src/superlocalmemory/__init__.py +1 -1
  8. package/src/superlocalmemory/cli/compress_cmd.py +32 -70
  9. package/src/superlocalmemory/cli/optimize_cmd.py +1 -3
  10. package/src/superlocalmemory/cli/setup_wizard.py +49 -0
  11. package/src/superlocalmemory/mcp/agent_context.py +111 -0
  12. package/src/superlocalmemory/mcp/server.py +4 -0
  13. package/src/superlocalmemory/mcp/tools_active.py +7 -8
  14. package/src/superlocalmemory/mcp/tools_core.py +16 -0
  15. package/src/superlocalmemory/mcp/tools_optimize.py +304 -0
  16. package/src/superlocalmemory/optimize/cache/boundary_store.py +23 -9
  17. package/src/superlocalmemory/optimize/cache/exact.py +7 -4
  18. package/src/superlocalmemory/optimize/cache/key_builder.py +13 -0
  19. package/src/superlocalmemory/optimize/cache/manager.py +70 -8
  20. package/src/superlocalmemory/optimize/cache/semantic.py +10 -5
  21. package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +1 -7
  22. package/src/superlocalmemory/optimize/compress/router.py +82 -87
  23. package/src/superlocalmemory/optimize/config/__init__.py +16 -0
  24. package/src/superlocalmemory/optimize/config/defaults.py +1 -6
  25. package/src/superlocalmemory/optimize/config/schema.py +2 -19
  26. package/src/superlocalmemory/optimize/config/store.py +15 -1
  27. package/src/superlocalmemory/optimize/metrics/counters.py +15 -7
  28. package/src/superlocalmemory/optimize/proxy/_helpers.py +100 -2
  29. package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +12 -0
  30. package/src/superlocalmemory/optimize/proxy/capture.py +243 -0
  31. package/src/superlocalmemory/optimize/proxy/gemini_surface.py +31 -0
  32. package/src/superlocalmemory/optimize/proxy/openai_surface.py +12 -0
  33. package/src/superlocalmemory/optimize/proxy/server.py +29 -0
  34. package/src/superlocalmemory/optimize/storage/db.py +102 -11
  35. package/src/superlocalmemory/optimize/storage/schema.py +11 -0
  36. package/src/superlocalmemory/server/routes/optimize.py +6 -8
  37. package/src/superlocalmemory/server/unified_daemon.py +26 -5
  38. package/src/superlocalmemory/ui/index.html +18 -14
  39. package/src/superlocalmemory/ui/js/auto-settings.js +3 -1
  40. package/src/superlocalmemory/ui/js/ng-shell.js +3 -0
  41. package/src/superlocalmemory/ui/js/optimize.js +9 -9
  42. package/src/superlocalmemory.egg-info/PKG-INFO +69 -10
  43. package/src/superlocalmemory.egg-info/SOURCES.txt +3 -2
  44. package/src/superlocalmemory.egg-info/requires.txt +1 -0
  45. package/src/superlocalmemory/optimize/compress/extractive_code.py +0 -311
  46. package/src/superlocalmemory/optimize/compress/extractive_json.py +0 -72
package/CHANGELOG.md CHANGED
@@ -5,20 +5,122 @@ 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.6.9] - 2026-06-11
8
+ ## [3.6.11] - 2026-06-14 — Optimize Everywhere: three surfaces (proxy · MCP tools · skill)
9
9
 
10
- ### Fixed
11
- - **BUG-A: Health monitor no longer kills the embedding worker under memory pressure.** The watchdog now spares the embedding worker (load-bearing for recall quality) and prefers the reranker instead. The RSS budget defaults to 40% of physical RAM (floor 2500 MB) rather than a hardcoded 2500 MB, preventing thrash on machines with ≥8 GB. `SLM_RSS_BUDGET_MB` env and a new `"health"` config section give full operator control. `HealthConfig` dataclass + `SLMConfig.load()` parsing added so config.json `"health"` keys now actually take effect.
12
- - **#34: Mesh tools no longer block the daemon event loop.** All 8 async mesh tools wrapped `_ensure_registered` and `_mesh_request` in `asyncio.to_thread` so the blocking loopback HTTP calls leave the event loop (v3.6.7 in-process transport made this a self-deadlock). MCP lifespan hardened so a tool-level exception cannot propagate to uvicorn's shutdown handler. `heartbeat_active` and `registered` now return live state instead of hardcoded literals.
13
- - **#35: `session_init` now returns a `session_id`.** Clients pass it to `remember()` and `close_session()`. `store_fast` lifts `session_id` from metadata onto the `MemoryRecord` row so facts are correctly attributed. `close_session` queries the DB for the most recent session instead of chasing a phantom `_last_session_id` that was never assigned — `summary_events_created` now returns real counts.
14
- - **#36-1: HTTP MCP reachable from LAN.** New `SLM_MCP_ALLOWED_HOSTS` (opt-in, default localhost-only) overrides MCP's DNS-rebinding protection. Accepts comma-separated `host:port*` patterns or `*` to disable protection entirely on a trusted LAN.
15
- - **#36-2: `slm mcp` and the HTTP daemon no longer race for port 8765.** `ensure_daemon` now checks TCP connectivity in addition to PID file + HTTP health, detecting systemd-started daemons mid-startup before attempting a second bind. `SLM_DAEMON_PORT` is now fully wired end-to-end (previously only read in `commands.py` URL building, not in the actual uvicorn bind or `_start_daemon_subprocess`).
16
- - **#32: Docs correctly state Python 3.11+ requirement** (was "3.10 or later"). Added Ubuntu 22.04 deadsnakes install instructions and a new `docs/install-linux.md` guide.
10
+ Cache + compress across **every setup** — proxy, MCP tools, or skill. Five new MCP tools land directly inside `slm mcp` (no proxy, full 1M context window preserved). A new `slm-optimize` skill makes compression and routed-result caching zero-config for Claude Code users. Overclaim in prior docs fixed; three-surfaces table added.
11
+
12
+ ### Added Surface B: MCP Optimize Tools (proxy-free)
13
+
14
+ Five new tools registered in `slm mcp` from v3.6.11+:
15
+
16
+ - **`slm_compress`** compress text or tool output. `mode=normalize` is lossless whitespace normalization; `mode=auto`/`aggressive` delegates to the existing CompressRouter engine. Lossy + reversible stores the original in CCR and returns a `ccr_id`. Content >1 MB is stored unreversed. All fail-open.
17
+ - **`slm_retrieve`** — recover the exact original bytes from a `ccr_id` UUID4 returned by `slm_compress`. Validates UUID format before lookup.
18
+ - **`slm_cache_set`** — cache any string result the agent routes through SLM (file reads, bash output, search results, sub-model calls). Key is SHA-256 namespaced `mcpkv:{agent_id}:{key}` — no cross-agent collisions. TTL default 24 h.
19
+ - **`slm_cache_get`** — retrieve a cached result by key. Returns `hit:True/False`. Increments in-module `_kv_hits`/`_kv_misses` counters for stats.
20
+ - **`slm_optimize_stats`** — session compression + cache statistics. Proxy counters read from `CacheDB.metrics_load()` (daemon-persisted, accurate across restarts); KV counters are in-module for this MCP process session.
21
+
22
+ All five are **fail-open**: any internal error returns `{ok: False, note: <error>}` with the original content unchanged — never raises to the agent.
23
+
24
+ ### Added — Surface C: slm-optimize Skill (zero-config)
25
+
26
+ - **`skills/slm-optimize/SKILL.md`** and **`ide/skills/slm-optimize/SKILL.md`** — agent-behavior instruction file. Eight behavioral rules: compress CLAUDE.md at session start, compress large tool outputs via `slm_compress`, KV-cache repeated file reads and bash/search results, recover originals with `slm_retrieve`, never-compress list (secrets, JSON, code/Edit/Write outputs), emit stats on request, fail-open on `ok:False`. Compatible with Claude Code, Cursor, Antigravity, Codex, and any IDE that supports MCP tool calls.
27
+ - **`skills/slm-optimize/README.md`** — human install guide: prerequisites, install steps, activation options, feature table, and explicit "what it does NOT do" section.
28
+
29
+ ### Changed — `CacheDB` (new public method)
30
+
31
+ - **`CacheDB.get_value(cache_key, tenant_id)`** added to `optimize/storage/db.py` — pure `SELECT` lookup with no `hit_count` side-effect (unlike `get()`). Used by `slm_cache_get` to avoid inflating proxy cache counters when agents read KV entries. Fail-open: returns `None` on any SQLite/decryption/zlib error.
32
+
33
+ ### Changed — MCP server registration
34
+
35
+ - Five optimize tool names added to `_ESSENTIAL_TOOLS` frozenset in `mcp/server.py` (v3.6.11 Surface B). Without this the `_FilteredServer` wrapper silently drops tools whose names are not in the set.
36
+ - `register_optimize_tools(_target)` call added after other `register_*` calls.
37
+
38
+ ### Fixed — Overclaim in README / docs
39
+
40
+ - Replaced "Save up to 90% on every LLM API call" headline with accurate three-surfaces framing: proxy (full-turn caching on metered API), MCP tools (routed-result caching + compression), skill (auto-applied compression). Hard constraint documented: primary Claude conversation turn cannot be cached without a proxy — never implied otherwise.
41
+
42
+ ## [3.6.10] - 2026-06-14 — Optimize correctness (cache + lossless compression) · MCP per-agent identity · runtime toggles · benchmark + shadow-capture · Issue #38
43
+
44
+ This release makes the **Optimize** subsystem (the HTTP proxy that caches and compresses LLM API calls) correct, observable, and **independently controllable at runtime**, adds **per-agent identity** to the HTTP MCP transport, ships a **benchmark + shadow-capture** harness that proves the cache and compression behaviour, and fixes GitHub issue #38. Cache and compression remain **default-OFF** and are now separately toggleable from the dashboard.
45
+
46
+ ### Added — Independent runtime control of cache vs compression
47
+
48
+ - **Cache and compression are separate switches**, both live at runtime from the dashboard — enable caching only, compression only, both, or neither, without restarting the daemon. The config watchdog rebuilds the proxy hook chain in place on change.
49
+
50
+ ### Added — MCP per-agent identity over HTTP (`/mcp/{agent_id}`)
51
+
52
+ - **Per-agent attribution without per-agent processes.** The HTTP MCP endpoint accepts an agent-id path segment — `http://127.0.0.1:8765/mcp/claude`, `/mcp/hermes`, `/mcp/gemini`, etc. The daemon extracts it (root_path-aware ASGI wrapper) into a per-request `ContextVar`, so `remember`, `recall`, `observe`, `delete_memory`, `update_memory`, `session_init`, and event emission all tag the correct agent. Many agents share one daemon instead of one `slm mcp` stdio process each. Bare `/mcp/` is unchanged → default `mcp_client` (backward compatible). Precedence: URL path → `SLM_AGENT_ID` env (stdio) → `mcp_client`. URL agent-ids are sanitized (charset-restricted, 64-char cap). See `docs/distributed-deployment.md`.
53
+
54
+ ### Added — Benchmark + shadow-capture (`benchmarks/optimize/`)
55
+
56
+ - **Correctness benchmark** drives the shipped cache + compression code: exact-cache replay is 100% hit + byte-identical, exact false-hit rate is **0** (the wrong-answer guard), semantic-tier wiring honours its threshold, and safe-mode compression is **lossless** for JSON/code/prose (code forwarded unchanged). Enforced in CI by `tests/optimize/test_benchmark.py`.
57
+ - **Shadow-capture mode** (`SLM_OPTIMIZE_CAPTURE=1`): pure-passthrough proxy records real `{request, response, model, tokens, content_type}` exchanges to `~/.superlocalmemory/optimize_capture.jsonl` (0600, `O_NOFOLLOW`, git-ignored, 1 MB/side cap, secrets never recorded) for replay into the benchmark. No cache/compress while capturing.
58
+
59
+ ### Changed — Compression rebuilt on a research-backed layered design
60
+
61
+ - **Removed the homegrown extractive JSON/code compressors** (they truncated JSON strings, capped arrays, and stubbed code bodies — lossy and unsafe). Safe mode is now **lossless** (whitespace + compact-JSON normalization only; code untouched). Aggressive mode adds **LLMLingua-2** (`microsoft/llmlingua-2-xlm-roberta-large-meetingbank`) for **prose only** — never code, numbers, structured data, instructions, or the current turn. Dead `compress_json`/`compress_code` toggles removed.
62
+
63
+ ### Fixed — Cache correctness & observability
64
+
65
+ - **Semantic cache tier is now wired** into the proxy `get/check/set` path (was dead code); default-off, conservative 0.98 return threshold, benchmarked false-hit guard. See `docs/optimize-config.md` for threshold-tuning guidance.
66
+ - **Token accounting corrected** — input tokens (the biggest save) and real output tokens are now counted on cache hits instead of 0/estimates.
67
+ - **Cache survives machine-id changes** — the AES-GCM key/salt is persisted (0600), fixing the total-miss after VM clone / container / OS reinstall.
68
+ - **UI opt-in is real** — a `proxy_enabled` toggle now actually mounts the proxy.
69
+
70
+ ### Fixed — Issue #38 (frontend)
71
+
72
+ - **Brain page no longer stuck on "Couldn't load Brain"** on a healthy backend — pane activation fires `fetchBrain` and reads the install token from the same source as the working endpoints.
73
+ - **"Test Connection" no longer 401s on an empty API key** in no-auth (Mode B) — when the key is empty no `Authorization` header is sent.
74
+
75
+ ### Security (v3.6.10 audit, Stage 8/9)
76
+
77
+ - Capture file: `O_NOFOLLOW` + unconditional `0600` (symlink-append + TOCTOU closed); in-memory stream accumulator bounded (CWE-400); synchronous capture writes offloaded off the event loop; `extract_usage` uses an explicit provider allowlist (no silent mis-parse). URL agent-ids sanitized at the single extraction chokepoint.
78
+
79
+ ## [3.6.9] - 2026-06-11 — Full 7-layer recall quality · event-loop safety · health watchdog
80
+
81
+ This release fixes seven GitHub issues, one critical production incident, five post-implementation audit bugs, and two event-loop deadlocks introduced in v3.6.7. All 7 retrieval layers (semantic, BM25, temporal, spreading activation, Hopfield, entity graph, cross-encoder reranker) now operate at full designed quality with no capability tradeoffs.
82
+
83
+ ### Fixed — Production incident
84
+
85
+ - **BUG-A (CRITICAL): Health monitor RSS watchdog no longer kills the embedding worker.** On machines with <16 GB RAM the hardcoded 2500 MB budget caused the watchdog to kill the ~1 GB ONNX embedding worker during recall bursts. Semantic channel silently scored 0.0, recall fell back to keyword-only FTS5/BM25 ("DEGRADED MODE"), and the v3.6.8 health monitor reported false-healthy because it checked worker liveness rather than semantic signal quality. Fixed by: (1) defaulting the budget to 40% of physical RAM (floor 2500 MB) with `SLM_RSS_BUDGET_MB` env override; (2) protecting the embedder from the kill list — the reranker is targeted first as it can be recreated without losing recall quality; (3) adding `HealthConfig` dataclass and `SLMConfig.load()` parsing so `config.json` `"health"` keys now actually take effect.
86
+
87
+ ### Fixed — GitHub issues
88
+
89
+ - **#34: Mesh tools no longer deadlock the daemon.** All 8 async mesh MCP tools called blocking `urllib.urlopen` loopback HTTP against the daemon's own `/mcp` endpoint introduced in v3.6.7. From inside the event loop this self-deadlocked uvicorn's single-thread executor, causing a graceful-shutdown timeout that killed the daemon. All 8 call sites wrapped in `asyncio.to_thread`. MCP lifespan hardened so a tool-level exception cannot propagate to uvicorn's shutdown handler. `heartbeat_active` and `registered` return live state instead of hardcoded literals.
90
+ - **#35: `session_init` now returns a `session_id`.** Three spots fixed: (1) `tools_active.py` — `session_init` now passes `session_id` through to callers; (2) `engine.py` `store_fast` — lifts `session_id` from metadata onto the `MemoryRecord` row so facts are correctly attributed to sessions; (3) `close_session` — queries the DB for the most recent session instead of chasing a phantom `_last_session_id` that was never assigned, and `summary_events_created` now returns real counts.
91
+ - **#36-1: HTTP MCP now reachable from LAN hosts.** The new `SLM_MCP_ALLOWED_HOSTS` env (opt-in, default localhost-only) overrides FastMCP's DNS-rebinding protection that rejected non-`127.0.0.1` `Host` headers on LAN deployments. Accepts comma-separated `host:port*` patterns or `*`. Security default is unchanged — the endpoint stays localhost-only without explicit opt-in.
92
+ - **#36-2: `slm mcp` and the HTTP daemon no longer race for port 8765.** `ensure_daemon` now checks TCP connectivity in addition to PID file + HTTP health, detecting systemd-started daemons mid-startup before attempting a second bind. `SLM_DAEMON_PORT` is now fully wired end-to-end (previously only read in `commands.py` URL construction, ignored in the actual uvicorn bind and `_start_daemon_subprocess`). Wrapped in `try/except ValueError` so a malformed env value fails with a clear message rather than a silent zero-port bind.
93
+ - **#33 + #37: Environment variable reference table published.** All ~90 `SLM_*` variables documented in `docs/distributed-deployment.md` with type, default, scope, and example. Closes both issues.
94
+ - **#32: Python version requirement corrected.** Docs previously stated "3.10 or later" — the codebase enforces 3.11+. Updated `getting-started.md`, added Ubuntu 22.04 deadsnakes install path and a new `docs/install-linux.md`.
95
+
96
+ ### Fixed — Event-loop blocking (post-v3.6.7 audit)
97
+
98
+ The v3.6.7 in-process HTTP MCP transport changed the execution context of all MCP tools from stdio subprocess threads to async event-loop coroutines. Three core tools made blocking HTTP or I/O calls that safe in a subprocess become event-loop deadlocks in the new context.
99
+
100
+ - **`session_init` no longer blocks the event loop.** `pool_recall` called `DaemonPoolProxy.recall` which uses blocking `urllib.urlopen` internally. Wrapped in `asyncio.to_thread`.
101
+ - **`observe` no longer blocks the event loop.** `auto.capture()` is a synchronous function that makes an internal HTTP call. Wrapped in `asyncio.to_thread`.
102
+ - **`remember` no longer blocks the event loop.** Both `is_daemon_running()` (file-system check + HTTP probe) and `daemon_request()` (blocking HTTP POST) wrapped in `asyncio.to_thread`.
103
+
104
+ ### Fixed — Post-implementation audit (5 bugs)
105
+
106
+ - **`close_session` crash eliminated.** `tools_active.py` `close_session` called `engine._db._get_conn()`, a private method removed in a prior refactor. Changed to the public `engine._db.execute()` API.
107
+ - **`TransportSecuritySettings` import no longer fails on older MCP SDK versions.** The import was at module level in `unified_daemon.py`, causing an `ImportError` on MCP SDK < 1.27. Moved inside the `if _mcp_allowed:` conditional so it only loads when the HTTP transport is actually being activated.
108
+ - **`SLM_DAEMON_PORT` no longer silently becomes 0 on invalid input.** `int(os.environ.get("SLM_DAEMON_PORT", "") or 8765)` evaluated to `int("")` → `ValueError` → port 0. Wrapped in `try/except ValueError` with a fallback to 8765 and a log warning.
109
+ - **Health monitor cmdline truncation increased.** `cmdline[:80]` silently dropped long Python command lines (common with virtualenv paths), producing false "not SLM" negatives. Increased to `cmdline[:200]`.
110
+ - **Daemon `_DEFAULT_PORT` no longer crashes on malformed env.** Same `ValueError` guard added to the module-level `_DEFAULT_PORT` assignment in `cli/daemon.py`.
111
+
112
+ ### Changed — Recall performance (zero quality tradeoff)
113
+
114
+ - **SpreadingActivation: 418ms → 36ms (12×).** Neighbor lookups for each graph node are now cached across propagation iterations. The neighbor list is static within a single recall — re-querying SQL per iteration (up to ~120 queries per propagation) was pure waste. The cache is local to the call, so correctness is unchanged.
115
+ - **`fast=True` deprecated.** `fast=True` was added in v3.4.40 when SpreadingActivation took 418ms. With SA now completing in ~36ms, `fast=True` (which disables SA) is actually *slower* than `fast=False` and reduces recall quality by dropping a full retrieval channel. `MemoryEngine.recall()` now logs a `WARNING` and silently treats `fast=True` as `False`. The parameter is retained for API backward compatibility and will be removed in v3.7.x. All built-in callers already passed `fast=False`.
116
+ - Hopfield `prefilter_candidates` and entity-graph scoring candidates retain their original designed values (1000 and 100 respectively) — no quality tradeoffs were made in pursuit of latency targets.
17
117
 
18
118
  ### Added
119
+
19
120
  - `HealthConfig` dataclass in `core/config.py` and `"health"` section parsing in `SLMConfig.load()`.
20
- - `docs/distributed-deployment.md` complete guide for LXC/container/multi-machine setups, including a full ~90-entry `SLM_*` environment variable reference table (closes #33 + #37).
21
- - `docs/install-linux.md` — Ubuntu 22.04 / Debian install guide with venv, pipx, and pyenv options, plus a systemd unit template.
121
+ - `SLM_RSS_BUDGET_MB` environment variable for operator control of the health watchdog kill threshold.
122
+ - `docs/distributed-deployment.md` — complete guide for LXC/container/multi-machine setups with full `SLM_*` environment variable reference (closes #33 + #37).
123
+ - `docs/install-linux.md` — Ubuntu 22.04 / Debian install guide with venv, pipx, and pyenv paths plus a systemd unit template.
22
124
 
23
125
  ## [3.6.8] - 2026-06-11 — Runtime recall-health monitor (self-healing recall)
24
126
 
package/README.md CHANGED
@@ -2,18 +2,18 @@
2
2
  <img src="https://superlocalmemory.com/assets/logo-mark.png" alt="SuperLocalMemory" width="200"/>
3
3
  </p>
4
4
 
5
- <h1 align="center">SuperLocalMemory V3.6</h1>
6
- <p align="center"><strong>Save up to 90% on every LLM API call. Cache. Compress. Remember.</strong><br/><em>The only local-first memory system that SKIPS repeat calls (100% saved), SHRINKS prompts 60-95%, and REMEMBERS everything locally, for free. For Claude Code, Cursor, Windsurf, and any AI client.</em></p>
7
- <p align="center"><code>v3.6.0 "Optimize"</code> — <strong>Cache & Compress & Align. Save up to 90% on every LLM API call — locally.</strong> One command: <code>slm wrap claude</code><br>Also includes v3.5 Scale-Ready: 6-channel recall &lt;1s, CozoDB + LanceDB, Core Memory Block. Your database auto-migrates.</p>
5
+ <h1 align="center">SuperLocalMemory V3.6.11</h1>
6
+ <p align="center"><strong>Cache. Compress. Remember. Three surfaces proxy, MCP tools, or skill. Every setup covered.</strong><br/><em>The only local-first layer that pairs persistent memory with compression + caching across every Claude plan. Full 1M window preserved in MCP and skill mode.</em></p>
7
+ <p align="center"><code>v3.6.11 "Optimize Everywhere"</code> — <strong>Compress + cache on any plan, three ways in.</strong><br/>Proxy (full-turn cache): <code>slm wrap claude</code> &nbsp;·&nbsp; MCP (proxy-free): add <code>slm_compress</code> to your MCP config &nbsp;·&nbsp; Skill (zero-config): <code>~/.claude/skills/slm-optimize/</code></p>
8
8
  <p align="center"><strong>Backed by 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>
9
9
 
10
10
  <p align="center">
11
- <code>Saves up to 90% on LLM API costs</code> &nbsp;·&nbsp; <code>+10.6pp vs Mem0 zero-LLM</code> &nbsp;·&nbsp; <code>85% Open-Domain (best zero-LLM score)</code> &nbsp;·&nbsp; <code>EU AI Act Ready</code>
11
+ <code>Proxy · MCP tools · Skill three surfaces</code> &nbsp;·&nbsp; <code>+10.6pp vs Mem0 zero-LLM</code> &nbsp;·&nbsp; <code>85% Open-Domain (best zero-LLM score)</code> &nbsp;·&nbsp; <code>EU AI Act Ready</code>
12
12
  </p>
13
13
 
14
14
  <p align="center">
15
15
  <a href="https://arxiv.org/abs/2603.14588"><img src="https://img.shields.io/badge/arXiv-2603.14588-b31b1b?style=for-the-badge&logo=arxiv&logoColor=white" alt="arXiv Paper"/></a>
16
- <a href="https://img.shields.io/badge/Saves_90%25_on_LLM_Costs-22c55e?style=for-the-badge"><img src="https://img.shields.io/badge/Saves_90%25_on_LLM_Costs-22c55e?style=for-the-badge" alt="Saves 90% on LLM Costs"/></a>
16
+ <a href="#three-surfaces-proxy--mcp-tools--skill"><img src="https://img.shields.io/badge/Proxy_|_MCP_|_Skill-22c55e?style=for-the-badge" alt="Three Surfaces: Proxy, MCP Tools, Skill"/></a>
17
17
  <a href="https://pypi.org/project/superlocalmemory/"><img src="https://img.shields.io/pypi/v/superlocalmemory?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI"/></a>
18
18
  <a href="https://www.npmjs.com/package/superlocalmemory"><img src="https://img.shields.io/npm/v/superlocalmemory?style=for-the-badge&logo=npm&logoColor=white" alt="npm"/></a>
19
19
  <a href="https://www.gnu.org/licenses/agpl-3.0"><img src="https://img.shields.io/badge/License-AGPL_v3-blue.svg?style=for-the-badge" alt="AGPL v3"/></a>
@@ -33,18 +33,24 @@
33
33
  <details>
34
34
  <summary><strong>What's New in V3.6 — Optimize: SKIP, SHRINK, DISCOUNT, REMEMBER</strong> (click to expand)</summary>
35
35
 
36
- > V3.6 is the only local-first layer that SKIPS repeat LLM calls (cache: 100% saved), SHRINKS prompts 60-95% (compress: extractive + LLMLingua-2), and DISCOUNTS prefix costs (align: native KV-cache) — and remembers everything — in one install. **Your first cache hit pays for the install time. Hours of coding on repeat, minimal API cost.**
36
+ > V3.6 is the only local-first layer that SKIPS repeat LLM calls (cache: 100% on a hit), SHRINKS tool outputs and injected context (compress: lossless-by-default, opt-in LLMLingua-2), and DISCOUNTS prefix costs (align: native KV-cache) — and remembers everything — in one install.
37
+ >
38
+ > **v3.6.11 "Optimize Everywhere":** Three surfaces. **Proxy** (Surface A) — full-turn cache + compress on transport; needs `ANTHROPIC_BASE_URL`, shrinks the context window. **MCP tools** (Surface B) — `slm_compress`, `slm_retrieve`, `slm_cache_set`, `slm_cache_get`, `slm_optimize_stats`; no proxy, no window shrink, works on any Claude subscription. **Skill** (Surface C) — `slm-optimize` installs in `~/.claude/skills/`; zero-config auto-compress for large tool outputs and CLAUDE.md. No proxy, full 1M window. [See Three Surfaces →](#three-surfaces-proxy--mcp-tools--skill)
39
+ >
40
+ > **v3.6.10:** cache and compression are now **independent runtime switches** (cache-only, compress-only, both, or neither — toggle live from the dashboard, no restart). Compression was rebuilt to be **lossless by default** (the old string/array/code truncation is gone); aggressive mode adds LLMLingua-2 for **prose only** — never code, numbers, structured data, or the current turn.
37
41
 
38
42
  ### The Three Levers
39
43
 
40
44
  | Lever | Mechanism | Saving | Off by default? |
41
45
  |-------|-----------|:------:|:---------------:|
42
- | **Cache** | Skip repeat calls — exact-match SQLite lookup, vCache-gated semantic (opt-in) | **100% on a hit** (input + output) | Cache ON, Semantic OFF |
43
- | **Compress** | Shrink prompts — extractive JSON/code (lossless) + LLMLingua-2 prose (opt-in) | **60–95% on a miss** (input only) | Safe mode ON, Aggressive OFF |
46
+ | **Cache** | Skip repeat calls — exact-match SQLite lookup (zero false hits), vCache-gated semantic (opt-in) | **100% on a hit** (input + output) | Cache ON, Semantic OFF |
47
+ | **Compress** | Shrink prompts — **safe = lossless** normalization; **aggressive = LLMLingua-2 prose only** (opt-in) | Safe: small + lossless · Aggressive: large on prose | Safe mode, Aggressive OFF |
44
48
  | **Align** | Stabilize prefix — maximize provider prefix-cache discounts | **Lossless extra** | ON when compression is ON |
45
49
 
46
50
  **Memory** (v3.5's existing engine) runs in parallel — it shapes *what is in* the prompt (relevant facts); Optimize decides *whether and how* it is sent.
47
51
 
52
+ > **Independent at runtime:** enable caching only, compression only, both, or neither — from the dashboard Optimize tab, applied live (no restart). Each AI client can also get its own memory identity over HTTP MCP via `http://127.0.0.1:8765/mcp/{agent_id}`.
53
+
48
54
  ### Quick Start
49
55
 
50
56
  ```bash
@@ -60,7 +66,7 @@ slm wrap claude
60
66
  |:--------|:-------------|
61
67
  | `slm optimize status\|on\|off\|savings` | Master Optimize control + savings report (USD/INR/tokens) |
62
68
  | `slm cache status\|clear\|invalidate\|ttl\|semantic` | Cache sub-control — exact + semantic tiers |
63
- | `slm compress status\|mode\|code\|prose\|ccr\|align` | Compression control — per-channel toggles |
69
+ | `slm compress status\|mode\|prose` | Compression control — safe (lossless) / aggressive (LLMLingua-2 prose) |
64
70
  | `slm proxy [--port] [--provider]` | Start the interception proxy (port 8765) |
65
71
  | `slm wrap <agent>` | Proxy-activate an agent — one command to start saving |
66
72
  | `slm help-optimize [topic]` | Full developer reference + per-agent setup recipes |
@@ -116,6 +122,57 @@ Full docs:
116
122
 
117
123
  ---
118
124
 
125
+ ## Three Surfaces: Proxy · MCP Tools · Skill
126
+
127
+ v3.6.11 delivers one engine across **three ways in** — choose the surface that fits your setup:
128
+
129
+ | Surface | How you use it | Requires proxy? | Window effect | Cache scope |
130
+ |---------|---------------|:---------------:|:-------------:|-------------|
131
+ | **A — Proxy** | `slm wrap claude` or `ANTHROPIC_BASE_URL=http://127.0.0.1:8765` | **Yes** | Shrinks (proxy intercepts full context) | Full-turn cache — every Claude call |
132
+ | **B — MCP tools** | Add 5 tools to MCP config; call `slm_compress`, `slm_cache_set/get` | **No** | **Preserved** (full 1M) | Results you explicitly route through SLM |
133
+ | **C — Skill** | Copy `skills/slm-optimize/SKILL.md` → `~/.claude/skills/` | **No** | **Preserved** (full 1M) | Auto-applied by the agent per skill rules |
134
+
135
+ **How to choose:**
136
+ - On a **metered API** (pay-per-token) and want to cache every call → **Proxy (A)**
137
+ - On a **Pro/Max/Team subscription** or any plan where you can't or won't run a proxy → **MCP tools (B)** or **Skill (C)**
138
+ - Want zero configuration → **Skill (C)**: install once, auto-compresses CLAUDE.md and large outputs
139
+ - Want agent-controlled caching of repeated file reads and tool outputs → **MCP tools (B)**
140
+
141
+ **The hard constraint:** The primary Claude conversation turn cannot be cached without a proxy — the MCP/skill path caches results you explicitly route through SLM (tool outputs, file reads, sub-model calls).
142
+
143
+ ### MCP Tools Setup (Surface B)
144
+
145
+ Add to your `claude_desktop_config.json` or IDE MCP config alongside your existing SLM entry:
146
+
147
+ ```json
148
+ {
149
+ "mcpServers": {
150
+ "superlocalmemory": {
151
+ "command": "slm",
152
+ "args": ["mcp"]
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ The 5 optimize tools (`slm_compress`, `slm_retrieve`, `slm_cache_set`, `slm_cache_get`, `slm_optimize_stats`) are included automatically from v3.6.11+. Verify with `slm_optimize_stats()`.
159
+
160
+ ### Skill Setup (Surface C)
161
+
162
+ ```bash
163
+ mkdir -p ~/.claude/skills/slm-optimize
164
+ cp $(pip show superlocalmemory | grep Location | awk '{print $2}')/superlocalmemory/skills/slm-optimize/SKILL.md \
165
+ ~/.claude/skills/slm-optimize/SKILL.md
166
+ ```
167
+
168
+ Then reference in your `CLAUDE.md`:
169
+ ```markdown
170
+ ## Context Management
171
+ Use the `slm-optimize` skill to compress large outputs and cache repeated reads.
172
+ ```
173
+
174
+ ---
175
+
119
176
  <details>
120
177
  <summary><strong>What's New in V3.3 — The Living Brain Evolves</strong> (click to expand)</summary>
121
178
 
@@ -292,6 +349,7 @@ No manual commands. No data loss. Zero downtime.
292
349
 
293
350
  | Version | Codename | Key Features |
294
351
  |---|---|---|
352
+ | **v3.6.11** | Optimize Everywhere | **Three surfaces** — Proxy (A: full-turn cache), MCP tools (B: `slm_compress`/`slm_retrieve`/`slm_cache_set`/`slm_cache_get`/`slm_optimize_stats` — proxy-free, 1M window), Skill (C: `slm-optimize` zero-config). `CacheDB.get_value()` (pure KV lookup). 23 new tests. Links: [Three Surfaces →](#three-surfaces-proxy--mcp-tools--skill) · [docs/optimize-overview.md](docs/optimize-overview.md) |
295
353
  | **v3.6.0** | Optimize | **Cache** (skip repeat calls, 100% on hit) · **Compress** (shrink prompts 60-95%) · **Align** (KV-cache stabilization) · `slm optimize\|cache\|compress\|proxy\|wrap` CLI · Live savings dashboard (USD/INR/tokens) · Hot-reload config · Safe defaults · Links: [docs/optimize-overview.md](docs/optimize-overview.md) · [V3.6 Wiki](https://github.com/qualixar/superlocalmemory/wiki/V3.6-Overview) |
296
354
  | **v3.5.0** | Scale-Ready + Context Injection v2 | CozoDB/LanceDB migration, 6-channel recall <1s, Core Memory Block, BM25→FTS5, context injection v2, score normalization |
297
355
  | **v3.4.5** | Scale-Ready (foundation) | Tiered storage (active/warm/cold), graph pruning, BackendOrchestrator scaffolding, CozoDB + LanceDB init + migration code (read path wired in v3.5.0) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.6.9",
3
+ "version": "3.6.11",
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.6.9"
3
+ version = "3.6.11"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "AGPL-3.0-or-later"}
@@ -69,6 +69,11 @@ dependencies = [
69
69
  "scikit-learn==1.8.0",
70
70
  # Vector KNN extension for the semantic channel.
71
71
  "sqlite-vec==0.1.9",
72
+ # v3.6.10: LLMLingua-2 prose compression (aggressive mode, opt-in at runtime).
73
+ # Hard dependency so `pip install superlocalmemory` ships compression-ready;
74
+ # the ~560MB model downloads on first setup/warmup (fail-open). Verified the
75
+ # pin does NOT disturb the transformers/torch/numpy pins above.
76
+ "llmlingua==0.2.2",
72
77
  ]
73
78
 
74
79
  [project.optional-dependencies]
@@ -0,0 +1,55 @@
1
+ # slm-optimize — Context Optimizer Skill
2
+
3
+ Automatically compresses large tool outputs and caches repeated reads, reducing
4
+ context window usage without a proxy and without losing the full 1M window.
5
+
6
+ ## Prerequisites
7
+
8
+ - SuperLocalMemory v3.6.11+
9
+ - `slm mcp` daemon running
10
+ - `slm_compress` visible in `tools/list` (verify with your IDE's MCP tool inspector)
11
+
12
+ ## Install (Claude Code)
13
+
14
+ ```bash
15
+ cp skills/slm-optimize/SKILL.md ~/.claude/skills/slm-optimize/SKILL.md
16
+ ```
17
+
18
+ ## Activate
19
+
20
+ **Option A — On demand:**
21
+ Invoke via the `Skill` tool: `Skill("slm-optimize")`
22
+
23
+ **Option B — Auto-activate:**
24
+ Add to your project or global `CLAUDE.md`:
25
+ ```markdown
26
+ ## Context Management
27
+ Use the `slm-optimize` skill to compress large outputs and cache repeated reads.
28
+ Invoke at session start if context > 50k tokens.
29
+ ```
30
+
31
+ ## Verify
32
+
33
+ After activation, run `slm_optimize_stats()` from Claude Code. If it returns `ok:True`,
34
+ all 5 optimize tools are reachable and the skill is working.
35
+
36
+ ## What it does
37
+
38
+ | Feature | How |
39
+ |---|---|
40
+ | Compresses large tool outputs | `slm_compress` → compressed text + optional `ccr_id` |
41
+ | Caches repeated file reads | `slm_cache_set` / `slm_cache_get` keyed by file path |
42
+ | Caches repeated bash/search | Same KV tools, keyed by command |
43
+ | Recovers exact originals | `slm_retrieve(ccr_id)` when byte-identical content needed |
44
+ | Session stats | `slm_optimize_stats()` |
45
+
46
+ ## What it does NOT do
47
+
48
+ - **Full-turn caching**: impossible without a proxy (`ANTHROPIC_BASE_URL`).
49
+ Use Surface A (proxy mode) for that.
50
+ - **Guarantee savings**: results depend on content type and daemon compress config.
51
+
52
+ ## For Cursor, Antigravity, Codex
53
+
54
+ Same SKILL.md works — all IDEs that support MCP tool calls can use the 5 tools.
55
+ The skill itself is pure Markdown with no IDE-specific code.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: slm-optimize
3
+ description: >
4
+ Context optimizer for Claude Code + SLM. Compresses large outputs via
5
+ slm_compress (reversible CCR), caches repeated reads via slm_cache_set/get,
6
+ recovers originals via slm_retrieve. Works on any Claude plan, no proxy,
7
+ full context window preserved.
8
+ Requires SuperLocalMemory v3.6.11+ with optimize MCP tools enabled.
9
+ version: "3.6.11"
10
+ license: AGPL-3.0-or-later
11
+ triggers:
12
+ - "slm-optimize"
13
+ - "compress context"
14
+ - "optimize context"
15
+ - "reduce tokens"
16
+ ---
17
+
18
+ # slm-optimize: Context Optimizer for Claude Code
19
+
20
+ Reduces context window usage through compression and caching.
21
+ No proxy required. Full 1M window preserved.
22
+
23
+ **What this skill does NOT do:**
24
+ - Cache the primary Claude conversation turn (impossible without a proxy).
25
+ - Guarantee any specific savings percentage — results depend on content type and daemon config.
26
+
27
+ ---
28
+
29
+ ## When This Skill Is Active
30
+
31
+ Apply these rules automatically throughout the session once this skill is loaded.
32
+
33
+ ---
34
+
35
+ ## Decision Rules
36
+
37
+ ### RULE 1 — Session start: compress CLAUDE.md if large
38
+
39
+ At the start of any session where this skill is loaded:
40
+ 1. Read `CLAUDE.md` (or project CLAUDE.md).
41
+ 2. If `len(content) > 3000` characters: call `slm_compress(content=<text>, mode="normalize", reversible=False)`.
42
+ 3. Replace the in-context CLAUDE.md block with the compressed version.
43
+ 4. **Do not modify the actual file** — compress only the in-context representation.
44
+
45
+ ### RULE 2 — Large tool output: compress before processing
46
+
47
+ After any tool call that returns > 2000 characters:
48
+ 1. Call `slm_compress(content=<output>, mode="auto", reversible=True)`.
49
+ 2. Work from `compressed` in the response.
50
+ 3. If `lossy=True`, store the returned `ccr_id` — call `slm_retrieve` only if you need the exact original for verification, diffing, or code parsing.
51
+
52
+ **Never compress** (see RULE 6 for the complete exclusion list).
53
+
54
+ ### RULE 3 — Repeated file reads: KV cache
55
+
56
+ Before calling `Read(file_path)` for a file you have already read this session:
57
+ 1. `slm_cache_get(key=f"file:{file_path}")`.
58
+ 2. If `hit=True` → use `value` directly. Skip the `Read` call.
59
+ 3. If `hit=False` → call `Read`, then `slm_cache_set(key=f"file:{file_path}", value=<content>, ttl_seconds=1800)`.
60
+
61
+ If you edit a file via Edit/Write, immediately update or invalidate the cache entry.
62
+
63
+ ### RULE 4 — Repeated bash/search results: KV cache
64
+
65
+ For any Bash or WebSearch call whose result you expect to reuse:
66
+ 1. `slm_cache_set(key=f"bash:{command[:64]}", value=<output>, ttl_seconds=600)`.
67
+ 2. On the next identical call: `slm_cache_get` first.
68
+
69
+ Use `ttl_seconds=3600` for web search results (more expensive to re-run).
70
+
71
+ ### RULE 5 — Retrieve original via slm_retrieve
72
+
73
+ If you compressed content with `lossy=True` and need the exact original:
74
+ 1. Call `slm_retrieve(ccr_id=<ccr_id from prior compress response>)`.
75
+ 2. Check `size_bytes` before retrieving if context is nearly full.
76
+ 3. Do not retrieve unless you actually need byte-identical content.
77
+
78
+ ### RULE 6 — What NOT to compress or cache
79
+
80
+ - **Code being sent to Edit/Write**: never compress — the editor needs exact bytes.
81
+ - **JSON or structured data you will parse**: compression can alter whitespace and break parsers.
82
+ - **Secrets, API keys, credentials, tokens**: never store via `slm_cache_set`.
83
+ - **CCR IDs**: never cache via `slm_cache_set` — treat as ephemeral session values.
84
+ - **Very short outputs (< 500 chars)**: compression overhead exceeds the gain.
85
+
86
+ ### RULE 7 — Stats and awareness
87
+
88
+ If the user asks "how much context have you saved?" or "what is the optimization status?":
89
+ 1. Call `slm_optimize_stats()`.
90
+ 2. Report `cache_kv_hits`, `compress_runs`, and `tokens_saved_compress` clearly.
91
+ 3. Note that proxy stats are daemon-persisted; KV stats are this session only.
92
+
93
+ ### RULE 8 — Fail-open behavior
94
+
95
+ If any `slm_compress`, `slm_retrieve`, `slm_cache_set`, `slm_cache_get`, or
96
+ `slm_optimize_stats` call returns `ok:False`:
97
+ - Continue with the original (uncompressed/uncached) content.
98
+ - Do not retry. Do not surface the error unless the user asks about optimization.
99
+ - Optimization is always advisory — it must never block any primary task.
100
+
101
+ ---
102
+
103
+ ## Examples
104
+
105
+ ### Compress a large file read
106
+
107
+ ```
108
+ # Instead of working with 8000-char file output directly:
109
+ result = slm_compress(content=<file_content>, mode="auto", reversible=True)
110
+ # Work from result["compressed"]; keep result["ccr_id"] if lossy=True
111
+ ```
112
+
113
+ ### Cache a repeated grep result
114
+
115
+ ```
116
+ cached = slm_cache_get(key="bash:grep -rn MyClass src/")
117
+ if not cached["hit"]:
118
+ output = Bash("grep -rn MyClass src/")
119
+ slm_cache_set(key="bash:grep -rn MyClass src/", value=output, ttl_seconds=600)
120
+ ```
121
+
122
+ ### Recover original when needed
123
+
124
+ ```
125
+ original = slm_retrieve(ccr_id=<ccr_id>)
126
+ # original["content"] is byte-identical to what was compressed
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Stats and Troubleshooting
132
+
133
+ Run `slm_optimize_stats()` to see current session counters.
134
+
135
+ If tools return `ok:False`, the daemon may be down or the optimize module may not be
136
+ configured. Continue with normal tool calls — this skill degrades gracefully.
137
+
138
+ Verify tools are available: check that `slm_compress` appears in your MCP `tools/list`.
139
+ Requires SuperLocalMemory v3.6.11+ with `slm mcp` running.
@@ -32,7 +32,7 @@ if "OMP_NUM_THREADS" not in os.environ:
32
32
  os.environ["OMP_NUM_THREADS"] = "2"
33
33
  # ---------------------------------------------------------------------------
34
34
 
35
- __version__ = "3.6.9"
35
+ __version__ = "3.6.10"
36
36
 
37
37
  _REQUIRED_VERSIONS = {
38
38
  "sentence_transformers": "5.3.0",