superlocalmemory 3.5.8 → 3.6.1

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 (72) hide show
  1. package/ATTRIBUTION.md +24 -0
  2. package/CHANGELOG.md +86 -0
  3. package/README.md +142 -35
  4. package/package.json +1 -1
  5. package/pyproject.toml +2 -1
  6. package/src/superlocalmemory/__init__.py +1 -1
  7. package/src/superlocalmemory/cli/cache_cmd.py +198 -0
  8. package/src/superlocalmemory/cli/commands.py +80 -2
  9. package/src/superlocalmemory/cli/compress_cmd.py +179 -0
  10. package/src/superlocalmemory/cli/help_cmd.py +197 -0
  11. package/src/superlocalmemory/cli/main.py +122 -0
  12. package/src/superlocalmemory/cli/optimize_cmd.py +178 -0
  13. package/src/superlocalmemory/cli/optimize_constants.py +31 -0
  14. package/src/superlocalmemory/cli/proxy_cmd.py +104 -0
  15. package/src/superlocalmemory/core/config.py +5 -0
  16. package/src/superlocalmemory/core/engine.py +23 -0
  17. package/src/superlocalmemory/core/mcp_embedder_proxy.py +89 -0
  18. package/src/superlocalmemory/llm/backbone.py +10 -4
  19. package/src/superlocalmemory/mcp/server.py +34 -0
  20. package/src/superlocalmemory/mcp/tools_v3.py +6 -2
  21. package/src/superlocalmemory/optimize/NOTICE +11 -0
  22. package/src/superlocalmemory/optimize/__init__.py +0 -0
  23. package/src/superlocalmemory/optimize/adapters/__init__.py +68 -0
  24. package/src/superlocalmemory/optimize/adapters/_agent_registry.py +120 -0
  25. package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +115 -0
  26. package/src/superlocalmemory/optimize/adapters/openai_adapter.py +125 -0
  27. package/src/superlocalmemory/optimize/adapters/wrap.py +218 -0
  28. package/src/superlocalmemory/optimize/cache/__init__.py +31 -0
  29. package/src/superlocalmemory/optimize/cache/boundary_store.py +455 -0
  30. package/src/superlocalmemory/optimize/cache/centroid_store.py +158 -0
  31. package/src/superlocalmemory/optimize/cache/context_key.py +67 -0
  32. package/src/superlocalmemory/optimize/cache/exact.py +85 -0
  33. package/src/superlocalmemory/optimize/cache/invalidation.py +36 -0
  34. package/src/superlocalmemory/optimize/cache/key_builder.py +98 -0
  35. package/src/superlocalmemory/optimize/cache/manager.py +452 -0
  36. package/src/superlocalmemory/optimize/cache/semantic.py +568 -0
  37. package/src/superlocalmemory/optimize/cache/stampede.py +50 -0
  38. package/src/superlocalmemory/optimize/compress/__init__.py +17 -0
  39. package/src/superlocalmemory/optimize/compress/align.py +153 -0
  40. package/src/superlocalmemory/optimize/compress/ccr.py +157 -0
  41. package/src/superlocalmemory/optimize/compress/extractive_code.py +311 -0
  42. package/src/superlocalmemory/optimize/compress/extractive_json.py +72 -0
  43. package/src/superlocalmemory/optimize/compress/prose_llmlingua.py +77 -0
  44. package/src/superlocalmemory/optimize/compress/router.py +548 -0
  45. package/src/superlocalmemory/optimize/config/__init__.py +35 -0
  46. package/src/superlocalmemory/optimize/config/defaults.py +48 -0
  47. package/src/superlocalmemory/optimize/config/schema.py +255 -0
  48. package/src/superlocalmemory/optimize/config/store.py +209 -0
  49. package/src/superlocalmemory/optimize/metrics/__init__.py +8 -0
  50. package/src/superlocalmemory/optimize/metrics/counters.py +138 -0
  51. package/src/superlocalmemory/optimize/metrics/estimator.py +90 -0
  52. package/src/superlocalmemory/optimize/metrics/exporters.py +77 -0
  53. package/src/superlocalmemory/optimize/metrics/persistence.py +115 -0
  54. package/src/superlocalmemory/optimize/proxy/__init__.py +28 -0
  55. package/src/superlocalmemory/optimize/proxy/_helpers.py +257 -0
  56. package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +171 -0
  57. package/src/superlocalmemory/optimize/proxy/gemini_surface.py +121 -0
  58. package/src/superlocalmemory/optimize/proxy/lifecycle.py +126 -0
  59. package/src/superlocalmemory/optimize/proxy/openai_surface.py +125 -0
  60. package/src/superlocalmemory/optimize/proxy/server.py +151 -0
  61. package/src/superlocalmemory/optimize/storage/__init__.py +0 -0
  62. package/src/superlocalmemory/optimize/storage/db.py +1016 -0
  63. package/src/superlocalmemory/optimize/storage/schema.py +184 -0
  64. package/src/superlocalmemory/server/routes/optimize.py +167 -0
  65. package/src/superlocalmemory/server/routes/v3_api.py +63 -1
  66. package/src/superlocalmemory/server/unified_daemon.py +105 -0
  67. package/src/superlocalmemory/ui/index.html +98 -0
  68. package/src/superlocalmemory/ui/js/ng-shell.js +5 -1
  69. package/src/superlocalmemory/ui/js/optimize.js +173 -0
  70. package/src/superlocalmemory.egg-info/PKG-INFO +144 -36
  71. package/src/superlocalmemory.egg-info/SOURCES.txt +51 -0
  72. package/src/superlocalmemory.egg-info/requires.txt +1 -0
package/ATTRIBUTION.md CHANGED
@@ -59,5 +59,29 @@ SuperLocalMemory uses the following open-source libraries:
59
59
  - scikit-learn (BSD-3-Clause) — TF-IDF vectorization and similarity search
60
60
  - SQLite (Public Domain) — Local database storage
61
61
  - NumPy (BSD-3-Clause) — Numerical operations
62
+ - SciPy (BSD-3-Clause) — Numerical optimization (used by vCache MLE logistic refit)
62
63
 
63
64
  See [requirements.txt](requirements.txt) for the full dependency list.
65
+
66
+ ### Optimize Module — Research Citations (v3.6)
67
+
68
+ The Optimize module (LLD-03 / LLD-04) builds on peer-reviewed work.
69
+ The Implementer verified each arXiv ID against arxiv.org before citation.
70
+
71
+ | Component | Source | License / Note |
72
+ |---|---|---|
73
+ | **vCache** (per-item learned thresholds, online MLE) | arXiv:2502.03771 (ICLR 2026, Berkeley/TUM) | Eq. 9 (sigmoid), Eq. 10 (BCE MLE), Eq. 11 (confidence-band τ̂), Algorithm 2, Theorem 4.1 (≥1-δ correctness guarantee) |
74
+ | **CacheAttack** (86% response hijack, 90.6% agentic) | arXiv:2601.23088 | Threat model. The 90.6% figure is [UNVERIFIED — body-only, RA-18]; the 86% figure is verified from the abstract. |
75
+ | **SAFE-CACHE** (centroid-based adversarial defense) | Nature Scientific Reports 2026 | [CITATION-NEEDED-ONLINE — exact paper verified, but exact defense figures are body-only.] Defense reduced attack success from 52.77% to 14.27% per the paper. |
76
+ | **ContextCache** (multi-turn context-aware keys) | arXiv:2506.22791 | §3 — context-aware cache keys prevent false reuse across semantically overlapping but conversationally distinct turns. |
77
+ | **LLMLingua-2** (prose compression) | arXiv:2403.12968 (Microsoft Research) | MIT license. Models: `microsoft/llmlingua-2-bert-base-multilingual-cased-meetingbank` (default) and `microsoft/llmlingua-2-xlm-roberta-large-meetingbank`. Off by default, opt-in via `compress_prose=True` + `compress_mode="aggressive"`. **Originals always stored in CCR before lossy compression — reversible via `headroom_retrieve`.** |
78
+ | **LongLLMLingua** (RAG compression) | arXiv:2310.06839 | Not used in Phase 3. Documented for Phase 4 RAG integration. |
79
+ | **Headroom** (router, JSON handler, code handler, aligner) | github.com/qualixar/headroom (Apache-2.0) | Patterns adapted with attribution: `ContentRouter`, `JSONStructureHandler`, `CodeLanguage` enum, `CacheAligner._classify_token`. |
80
+ | **omnicache-ai** (test fixture patterns) | github.com/qualixar/omnicache-ai (Apache-2.0) | Deterministic hash-to-vector embedding fixture for tests. |
81
+
82
+ **Two fabricated arXiv IDs were caught and fixed during the LLD-10 audit:**
83
+ `2501.05064` and `2404.12693` (both previously wrong vCache labels). The
84
+ verified ID is **arXiv:2502.03771**.
85
+
86
+ If you see an arXiv ID in the Optimize module not listed above, treat it
87
+ as suspect.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,92 @@ 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.1] - 2026-06-07 — Optimize module fixes: proxy liveness probe, UI tab init, PyPI CI unblock
9
+
10
+ ### Fixed
11
+ - **`slm proxy` AttributeError — wrong lifecycle function name:** `proxy_cmd.py` called
12
+ `lifecycle.ensure_running(port=port)` which does not exist. The function signature is
13
+ `ensure_proxy_running()` and is designed for daemon-internal use only (requires
14
+ `_store` to be initialised via `_set_config_store()`). In CLI subprocess context
15
+ `_store is None`, so `get_optimize_config()` returns `DEFAULT_OPTIMIZE_CONFIG` with
16
+ `proxy_enabled=False`, causing the function to return `False` immediately. Fix: replaced
17
+ the entire implementation with a direct `urllib.request` HTTP probe to
18
+ `http://127.0.0.1:8765/health` — correct in all execution contexts without any import
19
+ of `lifecycle`. Also corrected missing `proxy_enabled: True` in the fields dict written
20
+ to ConfigStore when `slm proxy --providers ...` is invoked.
21
+ - **`slm optimize status` always showed "Proxy: not running":** `optimize_cmd.py` called
22
+ `lifecycle.proxy_is_running()` which does not exist either. The call was caught by a
23
+ broad `except Exception: pass`, so `proxy_running` was silently always `False`. Fix:
24
+ same pattern — direct HTTP health probe to `http://127.0.0.1:8765/health` with a 1s
25
+ timeout. `slm optimize status` now accurately reflects proxy liveness.
26
+ - **Optimize pane UI always showing all toggles OFF:** `ng-shell.js`'s `triggerTabLoad()`
27
+ switch statement was completely missing the `'optimize-pane'` case. `initOptimizeTab()`
28
+ is defined and populates the UI from the live API, but it was never called when the user
29
+ switched to the Optimize tab — the pane rendered HTML defaults (all OFF) forever.
30
+ Fix: added `case 'optimize-pane': if (typeof initOptimizeTab === 'function') initOptimizeTab(); break;`
31
+ to the switch. Hard-refresh (`Cmd+Shift+R`) required after install.
32
+ - **`ConfigUpdateRequest` missing `proxy_enabled` field:** `server/routes/optimize.py`'s
33
+ `ConfigUpdateRequest` Pydantic model did not include `proxy_enabled`, so the UI could
34
+ not toggle proxy via the `PATCH /api/optimize/config` endpoint. Added
35
+ `proxy_enabled: bool | None = None` with the existing nullable pattern.
36
+ - **`pytest` `import file mismatch` blocking ALL PyPI CI since v3.5.6:** `tests/test_cli.py`
37
+ (a legacy file with 6 basic tests) coexisted with `tests/test_cli/` (a package directory
38
+ with `__init__.py`). Python 3.12 on Ubuntu resolves the package name `test_cli` to the
39
+ directory — pytest then tries to collect the file under a conflicting module path and
40
+ raises `import file mismatch: imported module 'tests.test_cli' has this __file__ ...
41
+ which is not the same as the test file`. Every PyPI publish attempt since v3.5.6 failed
42
+ silently at this step (npm publishes succeeded because the npm CI workflow skips pytest).
43
+ Fix: `git mv tests/test_cli.py tests/test_cli_core.py` — no tests dropped, no changes
44
+ to test logic, collision eliminated.
45
+
46
+ ## [3.6.0] - 2026-06-07 — Optimize module: cache, compress, proxy (3-lever token-saving system)
47
+
48
+ ### Added
49
+ - **Optimize module** — a 3-lever system for reducing LLM token spend through an SLM-hosted
50
+ proxy at `http://localhost:8765`. Levers: (1) **Cache** — exact and semantic caching of
51
+ LLM calls with separate TTLs; (2) **Compress** — prompt compression via CCR/code/prose
52
+ strategies; (3) **Align** — model routing. Proxy intercepts calls routed via
53
+ `ANTHROPIC_BASE_URL=http://localhost:8765` or the `withSLM(Anthropic())` SDK adapter.
54
+ - `slm optimize status|on|off|savings` CLI subcommands.
55
+ - `slm proxy` CLI to start/stop the proxy and configure providers.
56
+ - Dashboard Optimize pane at `http://localhost:8765/#optimize-pane` with live toggle UI.
57
+ - Separate `llmcache.db` for cache storage — never writes to `memory.db`.
58
+
59
+ ## [3.5.9] - 2026-06-07 — Community bug fixes (issues #28, #29, PR #30) + zombie process hardening
60
+
61
+ ### Fixed
62
+ - **MCP zombie processes — stdin EOF monitor (macOS):** `slm mcp` now self-terminates when
63
+ the IDE closes the stdio pipe without quitting the parent app (e.g. "start new session"
64
+ in Claude Code or Antigravity). Uses `kqueue` `KQ_EV_EOF` so it detects the hangup without
65
+ consuming bytes needed by FastMCP's asyncio stdin reader. Complements the existing parent
66
+ watchdog (which only fires on process death). Previously 22+ orphan MCP sessions were
67
+ accumulating on the M5 Pro causing 12 GB of swap.
68
+ - **`slm reap --all`** (new flag): kills every `slm mcp` process except the caller, regardless
69
+ of orphan status. Use this after switching IDEs to clear all stale sessions in one command.
70
+ `slm reap --force` still kills only confirmed orphans. JSON output now lists this option in
71
+ `next_actions`.
72
+ - **MCP embedder NULL (PR #30):** `MemoryEngine(Capabilities.LIGHT)` permanently left
73
+ `_embedder=None`, causing memories stored via MCP tools to have no embeddings — semantic
74
+ search was silently broken and `health()` reported the embedder as `unavailable`. Root
75
+ cause correctly diagnosed by @kotys2022 in PR #30. Fix: after LIGHT init, engine now tries
76
+ to attach a `McpEmbedderProxy` that delegates `embed_batch()` to the daemon's
77
+ `/api/v3/embed` endpoint over localhost HTTP. One ONNX worker total across all sessions.
78
+ If the daemon is unreachable, the engine gracefully degrades to keyword-only recall (same
79
+ behaviour as before, but now honest). `health()` reports `source: daemon_proxy` so users
80
+ can distinguish proxy from local embedder.
81
+ - **`base_dir` ignored in config (issue #28):** `SLMConfig.load()` no longer ignores a custom
82
+ `base_dir` in `config.json` — it now passes it to `for_mode()` so `db_path` and all
83
+ derivative paths are built from the user's directory, not `~/.superlocalmemory`. `save()`
84
+ now persists `base_dir` so the setting survives daemon restarts.
85
+ - **Local model auth deadlock (issue #29):** Three interlocking fixes for `llama.cpp` / LM
86
+ Studio / other unauthenticated endpoints under the `openai` provider:
87
+ 1. `LLMBackbone._build_openai()` omits the `Authorization: Bearer` header when `api_key` is
88
+ empty — unauthenticated local servers no longer reject with HTTP 401.
89
+ 2. `_build_openai()` appends `/chat/completions` when `base_url` does not already end in
90
+ that path, fixing the `/v1/v1/chat/completions` duplication reported in the issue.
91
+ 3. `POST /api/v3/provider/test` now accepts an empty `api_key` when a custom `base_url` or
92
+ `endpoint` is provided, and probes the actual endpoint instead of hard-coding OpenAI's URL.
93
+
8
94
  ## [3.5.8] - 2026-06-06 — MCP zombie process fix
9
95
 
10
96
  ### Fixed
package/README.md CHANGED
@@ -2,17 +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.5</h1>
6
- <p align="center"><strong>Every other AI forgets. Yours won't.</strong><br/><em>Infinite memory for Claude Code, Cursor, Windsurf, and any MCP-compatible AI client.</em></p>
7
- <p align="center"><code>v3.5.0 "Scale-Ready + Context Injection v2"</code> — <strong>Your database auto-migrates. 6-channel recall in &lt;1s. Core Memory Block + explicit pinning. CozoDB + LanceDB on the recall path.</strong><br>No manual migrations. No data loss. One command: <code>pip install -U superlocalmemory && slm restart</code></p>
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>
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>+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>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>
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
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>
17
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>
18
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>
@@ -29,31 +30,89 @@
29
30
 
30
31
  ---
31
32
 
32
- ## Why SuperLocalMemory?
33
+ <details>
34
+ <summary><strong>What's New in V3.6 — Optimize: SKIP, SHRINK, DISCOUNT, REMEMBER</strong> (click to expand)</summary>
33
35
 
34
- Every **hosted** AI memory platform Mem0 Cloud, Zep Cloud, Letta Cloud, EverMemOS Cloud sends your data to cloud LLMs by default. Their self-hosted variants exist (Mem0 OpenMemory, Letta self-hosted, Graphiti) but require Docker + a separate graph DB or Ollama config, and most still default to OpenAI until you flip env vars. After **August 2, 2026**, any of those cloud paths becomes a compliance problem under the EU AI Act.
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.**
35
37
 
36
- SuperLocalMemory V3 takes a different approach: **mathematics instead of cloud compute.** Three techniques from differential geometry, algebraic topology, and stochastic analysis replace the work that other systems need LLMs to do — similarity scoring, contradiction detection, and lifecycle management. The result is an agent memory that ships local-first out of the box — no Docker, no graph DB, no API keys — on CPU.
38
+ ### The Three Levers
37
39
 
38
- **The numbers** (evaluated on [LoCoMo](https://arxiv.org/abs/2402.09714), the standard long-conversation memory benchmark). Published numbers as of April 2026:
40
+ | Lever | Mechanism | Saving | Off by default? |
41
+ |-------|-----------|:------:|:---------------:|
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 |
44
+ | **Align** | Stabilize prefix — maximize provider prefix-cache discounts | **Lossless extra** | ON when compression is ON |
39
45
 
40
- | System | Score | Config | Cloud LLM required? | Open Source | Source |
41
- |:-------|:-----:|:-------|:-------------------:|:-----------:|:-------|
42
- | EverMemOS | 93.05% | Cloud (proprietary) | Yes | Core only | [evermind.ai](https://evermind.ai/) (Feb 2026) |
43
- | Hindsight (LoComo10) | 92.0% | Cloud | Yes | No | [benchmarks.hindsight.vectorize.io](https://benchmarks.hindsight.vectorize.io) (Apr 2026) |
44
- | Mem0 (token-efficient) | 91.6% | Hybrid (Cohere/OpenAI) | Yes | Partial | [mem0.ai blog](https://mem0.ai/blog/mem0-the-token-efficient-memory-algorithm) (Apr 16 2026) |
45
- | **SLM V3 Mode C** | **87.7%** | Local + optional LLM | Optional (Ollama OK) | **Yes (AGPL-3.0)** | In-house, repro script in `docs/benchmarks/` |
46
- | Zep v3 Cloud | 85.2% | Cloud | Yes | Community deprecated | [getzep.com](https://www.getzep.com/) |
47
- | **SLM V3 Mode A** | **74.8%** | **Local, CPU-only, zero-LLM** | **No** | **Yes (AGPL-3.0)** | In-house, repro script in `docs/benchmarks/` |
48
- | Mem0 (zero-retrieval-LLM) | 64.2% | Local baseline | No | Partial | Mem0 paper, zero-LLM row |
46
+ **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.
49
47
 
50
- > **How to read this table.** Scores from different papers use different LoCoMo splits, judge models, and prompt variants. We do NOT claim these numbers are apples-to-apples across rows. The rows we re-ran in-house are marked "In-house"; cited rows link to the vendor's public source and date. Mode A is the only zero-LLM configuration in the list, so the comparison that is apples-to-apples is **Mode A 74.8% vs Mem0 zero-retrieval-LLM 64.2%** (+10.6pp). Mem0's 91.6% and EverMemOS's 93.05% use cloud LLMs; Mode C uses a local LLM (Ollama). BEAM-10M, the emerging successor benchmark, will be added in a future release.
48
+ ### Quick Start
51
49
 
52
- **What Mode A is**: CPU-only, SQLite-only, zero-LLM retrieval pipeline on published LoCoMo questions. To the best of our knowledge it is the only publicly-released local-first memory that clears Mem0's zero-LLM baseline on this benchmark. If another fully-local system hits similar numbers, please open an issue so we can update the table.
50
+ ```bash
51
+ # One command to start saving
52
+ slm wrap claude
53
+ # Your first repeat prompt → CACHE HIT → $0.00
54
+ # Your first long prompt → COMPRESSED 70% → $0.00 per token saved
55
+ ```
53
56
 
54
- Mathematical layers contribute **+12.7 percentage points** on average across 6 conversations (n=832 questions), with up to **+19.9pp on the most challenging dialogues**. This isn't more compute — it's better math.
57
+ ### New CLI Commands (6 total)
55
58
 
56
- > **Upgrading from V2 (2.8.6)?** V3 is a complete architectural reinvention — new mathematical engine, new retrieval pipeline, new storage schema. Your existing data is preserved but requires migration. After installing V3, run `slm migrate` to upgrade your data. Read the [Migration Guide](https://github.com/qualixar/superlocalmemory/wiki/Migration-from-V2) before upgrading. Backup is created automatically.
59
+ | Command | What It Does |
60
+ |:--------|:-------------|
61
+ | `slm optimize status\|on\|off\|savings` | Master Optimize control + savings report (USD/INR/tokens) |
62
+ | `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 |
64
+ | `slm proxy [--port] [--provider]` | Start the interception proxy (port 8765) |
65
+ | `slm wrap <agent>` | Proxy-activate an agent — one command to start saving |
66
+ | `slm help-optimize [topic]` | Full developer reference + per-agent setup recipes |
67
+
68
+ ### Savings Dashboard
69
+
70
+ All metrics tracked and displayed live — from the dashboard (Optimize tab) or CLI:
71
+
72
+ ```bash
73
+ slm optimize savings --since 7
74
+ # Savings (last 7 days):
75
+ # Exact cache hits: 43 (127,580 input tokens saved)
76
+ # Tokens saved (total): 153,096
77
+ # Estimated savings: ~$2.30 (at $3.00/M tokens — Anthropic rates)
78
+ ```
79
+
80
+ ### Enable / Disable
81
+
82
+ ```bash
83
+ slm optimize on # Enable cache + compress
84
+ slm optimize off # Disable (proxy passes through)
85
+ slm cache semantic on # Enable semantic cache (needs embedding model)
86
+ slm compress mode aggressive # Enable prose compression (with safety warning)
87
+ ```
88
+
89
+ **Safety defaults:** Optimize ON. Safe mode ON (extractive only — lossless, production-safe). Semantic OFF. Aggressive OFF. No behavior change until you explicitly enable features.
90
+
91
+ ### How It Works
92
+
93
+ ```
94
+ Your App → Proxy/SDK/Wrap → Cache Check → HIT → Return Cached (0 tokens)
95
+ |
96
+ MISS
97
+ |
98
+ Compress → Provider → Store in Cache
99
+ 60-95% + Align
100
+ ```
101
+
102
+ - **Fail-open** — any error passes through. Your calls never break.
103
+ - **Separate database** — `llmcache.db` never touches `memory.db`. AES-256-GCM at rest.
104
+ - **Hot-reload config** — UI/CLI writes `~/.superlocalmemory/optimize.json`, daemon reloads in 2s.
105
+
106
+ ### Links
107
+
108
+ Full docs:
109
+ - [Optimize Product Overview](docs/optimize-overview.md)
110
+ - [Optimize CLI Reference](docs/optimize-cli.md)
111
+ - [Optimize Config Reference](docs/optimize-config.md)
112
+ - [Wiki: V3.6 Overview](https://github.com/qualixar/superlocalmemory/wiki/V3.6-Overview)
113
+ - [Website: v3.6 Optimize](https://superlocalmemory.com/optimize)
114
+
115
+ </details>
57
116
 
58
117
  ---
59
118
 
@@ -148,21 +207,31 @@ slm config set v33_features.all true
148
207
 
149
208
  ---
150
209
 
151
- <details>
152
- <summary><strong>What's New in V3.2 — The Living Brain</strong> (click to expand)</summary>
210
+ ## Why SuperLocalMemory?
153
211
 
154
- 100x faster recall (<10ms at 10K facts), automatic memory surfacing, associative retrieval (5th channel), temporal intelligence with bi-temporal validity, sleep-time consolidation, and core memory blocks. All features default OFF, zero breaking changes.
212
+ Every **hosted** AI memory platform Mem0 Cloud, Zep Cloud, Letta Cloud, EverMemOS Cloud sends your data to cloud LLMs by default. Their self-hosted variants exist (Mem0 OpenMemory, Letta self-hosted, Graphiti) but require Docker + a separate graph DB or Ollama config, and most still default to OpenAI until you flip env vars. After **August 2, 2026**, any of those cloud paths becomes a compliance problem under the EU AI Act.
155
213
 
156
- | Metric | V3.0 | V3.2 | Change |
157
- |:-------|:----:|:----:|:------:|
158
- | Recall latency (10K facts) | ~500ms | <10ms | **100x faster** |
159
- | Retrieval channels | 4 | 5 | +spreading activation |
160
- | MCP tools | 24 | 29 | +5 new |
161
- | DB tables | 9 | 18 | +9 new |
214
+ SuperLocalMemory V3 takes a different approach: **mathematics instead of cloud compute.** Three techniques from differential geometry, algebraic topology, and stochastic analysis replace the work that other systems need LLMs to do — similarity scoring, contradiction detection, and lifecycle management. The result is an agent memory that ships local-first out of the box — no Docker, no graph DB, no API keys — on CPU.
162
215
 
163
- Enable with `slm config set v32_features.all true`. See the [V3.2 Overview](https://github.com/qualixar/superlocalmemory/wiki/V3.2-Overview) wiki page for details.
216
+ **The numbers** (evaluated on [LoCoMo](https://arxiv.org/abs/2402.09714), the standard long-conversation memory benchmark). Published numbers as of April 2026:
164
217
 
165
- </details>
218
+ | System | Score | Config | Cloud LLM required? | Open Source | Source |
219
+ |:-------|:-----:|:-------|:-------------------:|:-----------:|:-------|
220
+ | EverMemOS | 93.05% | Cloud (proprietary) | Yes | Core only | [evermind.ai](https://evermind.ai/) (Feb 2026) |
221
+ | Hindsight (LoComo10) | 92.0% | Cloud | Yes | No | [benchmarks.hindsight.vectorize.io](https://benchmarks.hindsight.vectorize.io) (Apr 2026) |
222
+ | Mem0 (token-efficient) | 91.6% | Hybrid (Cohere/OpenAI) | Yes | Partial | [mem0.ai blog](https://mem0.ai/blog/mem0-the-token-efficient-memory-algorithm) (Apr 16 2026) |
223
+ | **SLM V3 Mode C** | **87.7%** | Local + optional LLM | Optional (Ollama OK) | **Yes (AGPL-3.0)** | In-house, repro script in `docs/benchmarks/` |
224
+ | Zep v3 Cloud | 85.2% | Cloud | Yes | Community deprecated | [getzep.com](https://www.getzep.com/) |
225
+ | **SLM V3 Mode A** | **74.8%** | **Local, CPU-only, zero-LLM** | **No** | **Yes (AGPL-3.0)** | In-house, repro script in `docs/benchmarks/` |
226
+ | Mem0 (zero-retrieval-LLM) | 64.2% | Local baseline | No | Partial | Mem0 paper, zero-LLM row |
227
+
228
+ > **How to read this table.** Scores from different papers use different LoCoMo splits, judge models, and prompt variants. We do NOT claim these numbers are apples-to-apples across rows. The rows we re-ran in-house are marked "In-house"; cited rows link to the vendor's public source and date. Mode A is the only zero-LLM configuration in the list, so the comparison that is apples-to-apples is **Mode A 74.8% vs Mem0 zero-retrieval-LLM 64.2%** (+10.6pp). Mem0's 91.6% and EverMemOS's 93.05% use cloud LLMs; Mode C uses a local LLM (Ollama). BEAM-10M, the emerging successor benchmark, will be added in a future release.
229
+
230
+ **What Mode A is**: CPU-only, SQLite-only, zero-LLM retrieval pipeline on published LoCoMo questions. To the best of our knowledge it is the only publicly-released local-first memory that clears Mem0's zero-LLM baseline on this benchmark. If another fully-local system hits similar numbers, please open an issue so we can update the table.
231
+
232
+ Mathematical layers contribute **+12.7 percentage points** on average across 6 conversations (n=832 questions), with up to **+19.9pp on the most challenging dialogues**. This isn't more compute — it's better math.
233
+
234
+ > **Upgrading from V2 (2.8.6)?** V3 is a complete architectural reinvention — new mathematical engine, new retrieval pipeline, new storage schema. Your existing data is preserved but requires migration. After installing V3, run `slm migrate` to upgrade your data. Read the [Migration Guide](https://github.com/qualixar/superlocalmemory/wiki/Migration-from-V2) before upgrading. Backup is created automatically.
166
235
 
167
236
  ---
168
237
 
@@ -183,9 +252,18 @@ slm warmup # Pre-download embedding model (~500MB, optional)
183
252
  pip install superlocalmemory
184
253
  ```
185
254
 
186
- ### Upgrading to v3.5.0 "Scale-Ready CozoDB + LanceDB"
255
+ ### Start Saving on LLM Costs (v3.6 Optimize)
187
256
 
188
- **Migration is automatic.** Upgrade the package, restart the daemon — CozoDB, LanceDB, and the vector store all self-migrate in the background.
257
+ ```bash
258
+ # Wrap your agent — starts proxy + sets environment + launches agent
259
+ slm wrap claude
260
+ # Your first repeat prompt → CACHE HIT → $0.00 saved
261
+ # See savings: slm optimize savings --since 1
262
+ ```
263
+
264
+ ### Upgrading to v3.6 "Optimize" + v3.5.0 "Scale-Ready"
265
+
266
+ **Migration is automatic.** Upgrade the package, restart the daemon — all migrations run in the background.
189
267
 
190
268
  ```bash
191
269
  pip install -U superlocalmemory
@@ -193,7 +271,13 @@ slm restart
193
271
  slm doctor
194
272
  ```
195
273
 
196
- No manual commands. No data loss. Your database upgrades in-place. The daemon applies all migrations (including CozoDB graph, LanceDB vector, and the `pinned` column for Core Memory) on first start after upgrade.
274
+ No manual commands. No data loss. Zero downtime.
275
+
276
+ **What you get after upgrading to v3.6.0:**
277
+ - **Cache** — skip repeat LLM calls entirely. Exact-match + vCache-gated semantic. **100% cost saved on hit.**
278
+ - **Compress** — shrink prompts 60-95% before sending. Extractive JSON/code (lossless) + LLMLingua-2 prose (opt-in). CCR reversible.
279
+ - **Align** — stabilize prompt prefix for native provider KV-cache discounts (Anthropic 90%, OpenAI 50%).
280
+ - **Savings dashboard** — live USD/INR/tokens saved displayed in the Optimize tab.
197
281
 
198
282
  **What you get after upgrading to v3.5.0:**
199
283
  - **CozoDB on the recall path** — entity_graph channel routes through the CozoDB backend (auto-detected, no config needed). Millions of graph edges indexed and traversed in milliseconds.
@@ -208,6 +292,7 @@ No manual commands. No data loss. Your database upgrades in-place. The daemon ap
208
292
 
209
293
  | Version | Codename | Key Features |
210
294
  |---|---|---|
295
+ | **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) |
211
296
  | **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 |
212
297
  | **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) |
213
298
  | **v3.4.51** | Recency Intelligence | Ebbinghaus decay + FSRS stability, age gate, session context time-awareness |
@@ -527,6 +612,20 @@ All 8 mesh tools work seamlessly across machines:
527
612
 
528
613
  ## Features
529
614
 
615
+ ### LLM Cost Optimization (v3.6 Optimize)
616
+ - **Exact Cache** — byte-identical repeat calls served from local SQLite. SHA-256 key derivation, stampede shield, tag-based invalidation. **100% cost saved on hit** (input + output tokens).
617
+ - **Semantic Cache** (opt-in) — vCache-powered learned thresholds with SAFE-CACHE centroid defense. Near-duplicate queries served within error bound. CacheAttack 86% hijack class blocked.
618
+ - **Extractive Compression** — structure-preserving compression for JSON, code (AST-aware: Python/JS/Go/Rust/Java/C++), and tool outputs. **60-95% fewer input tokens**, zero accuracy regression.
619
+ - **LLMLingua-2 Prose** (opt-in) — extractive prose summarization for open-ended chat. Safety-warned before enable.
620
+ - **CCR (Compressed Context Retrieval)** — pre-compression originals stored for byte-exact reversal under UUID. Every compressed block recoverable.
621
+ - **CacheAligner** — detects volatile tokens (UUIDs, timestamps, JWTs) in system prompts. Maximizes native provider prefix-cache discounts (Anthropic 90%, OpenAI 50%).
622
+ - **Interception Proxy** — HTTP proxy on port 8765 serving Anthropic, OpenAI, and Gemini surfaces. Zero-code integration — just set `base_url`.
623
+ - **Agent Wrapping** — `slm wrap claude` — one command starts proxy + sets environment + launches agent. 10 supported agents.
624
+ - **Savings Dashboard** — live USD/INR/tokens saved, hit rate, compression ratio, cache size. CLI + UI.
625
+ - **Hot-Reload Config** — UI/CLI writes `optimize.json`; daemon reloads in 2 seconds. No restart.
626
+ - **Fail-open** — any cache/compress/proxy error passes through. Your calls never break.
627
+ - **Data isolation** — separate `llmcache.db` with AES-256-GCM encryption. Never touches `memory.db`.
628
+
530
629
  ### Retrieval
531
630
  - 5-channel hybrid: Semantic (Fisher-Rao) + BM25 + Entity Graph + Temporal + Hopfield (associative / partial-query completion)
532
631
  - RRF fusion + cross-encoder reranking
@@ -579,6 +678,14 @@ All 8 mesh tools work seamlessly across machines:
579
678
 
580
679
  | Command | What It Does |
581
680
  |:--------|:-------------|
681
+ | `slm optimize status` | Show all Optimize settings (cache, compress, proxy, config version) |
682
+ | `slm optimize on\|off` | Enable/disable all Optimize features (hot-reload, no restart) |
683
+ | `slm optimize savings [--since N] [--provider P] [--json]` | Token/cost savings report — live USD/INR |
684
+ | `slm cache status\|clear\|invalidate\|ttl\|semantic` | Cache sub-control — exact + semantic tiers, TTL management |
685
+ | `slm compress status\|mode\|code\|prose\|ccr\|align` | Compression control — per-channel toggle, safe/aggressive mode |
686
+ | `slm proxy [--port] [--provider] [--no-compress] [--semantic]` | Start interception proxy (port 8765) |
687
+ | `slm wrap <agent> [options]` | Proxy-activate an agent — one command to start saving |
688
+ | `slm help-optimize [topic]` | Full developer reference + per-agent setup recipes |
582
689
  | `slm remember "..."` | Store a memory |
583
690
  | `slm recall "..."` | Search memories |
584
691
  | `slm forget "..."` | Delete matching memories |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "3.5.8",
3
+ "version": "3.6.1",
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.8"
3
+ version = "3.6.1"
4
4
  description = "Information-geometric agent memory with mathematical guarantees"
5
5
  readme = "README.md"
6
6
  license = {text = "AGPL-3.0-or-later"}
@@ -55,6 +55,7 @@ dependencies = [
55
55
  "psutil==7.2.2",
56
56
  "structlog==25.5.0",
57
57
  "portalocker==3.2.0",
58
+ "cryptography==45.0.2",
58
59
  # Semantic search + cross-encoder reranker. Do NOT use
59
60
  # sentence-transformers[onnx] — its extras pull optimum which
60
61
  # overrides the sentence-transformers pin via transitive deps.
@@ -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.5.8"
31
+ __version__ = "3.6.1"
32
32
 
33
33
  _REQUIRED_VERSIONS = {
34
34
  "sentence_transformers": "5.3.0",
@@ -0,0 +1,198 @@
1
+ # Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
2
+ # Licensed under AGPL-3.0-or-later - see LICENSE file
3
+ # Part of SuperLocalMemory V3 | https://qualixar.com | https://varunpratap.com
4
+
5
+ """Handlers for ``slm cache status|clear|invalidate|ttl|semantic``."""
6
+
7
+ from __future__ import annotations
8
+
9
+ import dataclasses
10
+ import json
11
+ import sys
12
+ from argparse import Namespace
13
+
14
+
15
+ def _get_store():
16
+ from superlocalmemory.optimize.config.store import ConfigStore
17
+ return ConfigStore()
18
+
19
+
20
+ def _get_cache_db():
21
+ from superlocalmemory.optimize.storage.db import CacheDB
22
+ return CacheDB()
23
+
24
+
25
+ def _write_config(**fields) -> None:
26
+ """5-step immutable config-write."""
27
+ store = _get_store()
28
+ cfg = store.get()
29
+ try:
30
+ cfg = dataclasses.replace(cfg, **fields)
31
+ store.save(cfg)
32
+ except ValueError as e:
33
+ print(f"Error: {e}", file=sys.stderr)
34
+ sys.exit(1)
35
+ except OSError as e:
36
+ print(f"Error writing config: {e}", file=sys.stderr)
37
+ sys.exit(1)
38
+
39
+
40
+ def cmd_cache(args: Namespace) -> None:
41
+ """Top-level dispatcher for ``slm cache <subcommand>``."""
42
+ sub = getattr(args, "cache_command", None)
43
+ _dispatch = {
44
+ "status": cmd_cache_status,
45
+ "clear": cmd_cache_clear,
46
+ "invalidate": cmd_cache_invalidate,
47
+ "ttl": cmd_cache_ttl,
48
+ "semantic": cmd_cache_semantic,
49
+ }
50
+ handler = _dispatch.get(sub or "")
51
+ if handler:
52
+ handler(args)
53
+ else:
54
+ print("Usage: slm cache status|clear|invalidate|ttl|semantic [options]")
55
+ sys.exit(0)
56
+
57
+
58
+ def cmd_cache_status(args: Namespace) -> None:
59
+ """Print cache status from CacheDB + ConfigStore."""
60
+ use_json = getattr(args, "json", False)
61
+ tenant = getattr(args, "tenant", "default")
62
+
63
+ cfg = _get_store().get()
64
+ db = _get_cache_db()
65
+ entry_count = db.entry_count(tenant)
66
+ db_size = db.db_size_bytes()
67
+ snap = db.metrics_load()
68
+
69
+ if use_json:
70
+ data = {
71
+ "status": "ok",
72
+ "entries_exact": entry_count,
73
+ "db_size_bytes": db_size,
74
+ "ttl_exact": cfg.ttl.exact_seconds,
75
+ "ttl_semantic": cfg.ttl.semantic_seconds,
76
+ "hits": snap.hits,
77
+ "misses": snap.misses,
78
+ "hit_rate": snap.hit_rate,
79
+ }
80
+ print(json.dumps(data, indent=2))
81
+ return
82
+
83
+ print("Cache status:")
84
+ print(f" Entries (exact): {entry_count} (not expired)")
85
+ semantic_state = "OFF" if not cfg.semantic_enabled else "ON"
86
+ print(f" Semantic index: {semantic_state}")
87
+ size_mb = db_size / (1024 * 1024)
88
+ print(f" DB size: {size_mb:.1f} MB (~/.superlocalmemory/llmcache.db)")
89
+ print(f" TTL (exact): {cfg.ttl.exact_seconds}s")
90
+ print(f" TTL (semantic): {cfg.ttl.semantic_seconds}s")
91
+ print(f" Hits: {snap.hits}")
92
+ print(f" Misses: {snap.misses}")
93
+ print(f" Hit rate: {snap.hit_rate:.1%}")
94
+
95
+
96
+ def cmd_cache_clear(args: Namespace) -> None:
97
+ """Delete all cache entries for a tenant."""
98
+ use_json = getattr(args, "json", False)
99
+ tenant = getattr(args, "tenant", "default")
100
+
101
+ db = _get_cache_db()
102
+ deleted = db.clear_tenant(tenant)
103
+
104
+ if use_json:
105
+ print(json.dumps({"status": "ok", "deleted": deleted}))
106
+ return
107
+
108
+ print(f"Cache cleared: {deleted} entries deleted.")
109
+ print("Hot-reload: daemon will pick up config change within 2s.")
110
+
111
+
112
+ def cmd_cache_invalidate(args: Namespace) -> None:
113
+ """Delete entries matching a tag."""
114
+ use_json = getattr(args, "json", False)
115
+ tag = getattr(args, "tag", None)
116
+
117
+ if not tag:
118
+ print("Error: --tag is required.", file=sys.stderr)
119
+ sys.exit(1)
120
+
121
+ db = _get_cache_db()
122
+ deleted = db.invalidate_by_tag(tag)
123
+
124
+ if use_json:
125
+ print(json.dumps({"status": "ok", "deleted": deleted, "tag": tag}))
126
+ return
127
+
128
+ print(f"Invalidated: {deleted} entries with tag \"{tag}\".")
129
+
130
+
131
+ def cmd_cache_ttl(args: Namespace) -> None:
132
+ """Set exact-cache and/or semantic-cache TTL."""
133
+ use_json = getattr(args, "json", False)
134
+ ttl_set = getattr(args, "ttl_set", None)
135
+ ttl_semantic = getattr(args, "ttl_semantic", None)
136
+
137
+ if ttl_set is not None and ttl_set <= 0:
138
+ print("Error: --set must be a positive integer.", file=sys.stderr)
139
+ sys.exit(1)
140
+ if ttl_semantic is not None and ttl_semantic <= 0:
141
+ print("Error: --semantic must be a positive integer.", file=sys.stderr)
142
+ sys.exit(1)
143
+
144
+ store = _get_store()
145
+ cfg = store.get()
146
+
147
+ fields: dict = {}
148
+ if ttl_set is not None:
149
+ new_ttl = dataclasses.replace(cfg.ttl, exact_seconds=ttl_set)
150
+ fields["ttl"] = new_ttl
151
+ if ttl_semantic is not None:
152
+ new_ttl = dataclasses.replace(cfg.ttl, semantic_seconds=ttl_semantic)
153
+ fields["ttl"] = new_ttl
154
+
155
+ if not fields:
156
+ print("Error: specify --set and/or --semantic.", file=sys.stderr)
157
+ sys.exit(1)
158
+
159
+ try:
160
+ cfg = dataclasses.replace(cfg, **fields)
161
+ store.save(cfg)
162
+ except (ValueError, OSError) as e:
163
+ print(f"Error: {e}", file=sys.stderr)
164
+ sys.exit(1)
165
+
166
+ if use_json:
167
+ result: dict = {"status": "ok"}
168
+ if ttl_set is not None:
169
+ result["ttl_exact"] = ttl_set
170
+ if ttl_semantic is not None:
171
+ result["ttl_semantic"] = ttl_semantic
172
+ print(json.dumps(result, indent=2))
173
+ return
174
+
175
+ if ttl_set is not None:
176
+ print(f"TTL (exact) set to {ttl_set}s.")
177
+ if ttl_semantic is not None:
178
+ print(f"TTL (semantic) set to {ttl_semantic}s.")
179
+ print("Daemon hot-reload: active within 2s. No restart required.")
180
+
181
+
182
+ def cmd_cache_semantic(args: Namespace) -> None:
183
+ """Enable or disable semantic cache."""
184
+ use_json = getattr(args, "json", False)
185
+ value = getattr(args, "semantic_value", "off")
186
+
187
+ _write_config(semantic_enabled=(value == "on"))
188
+
189
+ if use_json:
190
+ print(json.dumps({"status": "ok", "semantic_enabled": value == "on"}))
191
+ return
192
+
193
+ if value == "on":
194
+ print("Semantic cache: ENABLED.")
195
+ print("Note: requires embedding model (~500MB). Run `slm warmup` if not already done.")
196
+ else:
197
+ print("Semantic cache: DISABLED.")
198
+ print("Daemon hot-reload: active within 2s.")