superlocalmemory 4.1.6 → 4.1.7
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +19 -0
- package/README.md +3 -3
- package/package.json +3 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- 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-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/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-scope/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 +49 -0
- package/plugin-src/agents/slm-optimize-advisor.md +44 -0
- package/plugin-src/rules/AGENTS.md +1 -1
- 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-governance/SKILL.md +1 -1
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +1 -1
- package/plugin-src/skills/slm-mesh/SKILL.md +1 -1
- package/plugin-src/skills/slm-profile/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-scope/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 +5 -1
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/host_upgrades.py +21 -7
- package/src/superlocalmemory/core/engine.py +7 -1
- package/src/superlocalmemory/core/recall_pipeline.py +13 -6
- package/src/superlocalmemory/core/session_identity.py +14 -1
- package/src/superlocalmemory/hooks/codex_assets.py +165 -45
- package/src/superlocalmemory/learning/bandit.py +22 -2
- package/src/superlocalmemory/learning/engagement_features.py +279 -0
- package/src/superlocalmemory/learning/outcome_queue.py +14 -0
- package/src/superlocalmemory/learning/propensity.py +131 -0
- package/src/superlocalmemory/learning/reward.py +42 -16
- package/src/superlocalmemory/learning/reward_model.py +144 -0
- package/src/superlocalmemory/learning/reward_proxy.py +148 -22
- package/src/superlocalmemory/server/routes/v3_api.py +4 -3
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "AGPL-3.0-or-later",
|
|
22
22
|
"name": "superlocalmemory",
|
|
23
23
|
"source": "./plugin",
|
|
24
|
-
"version": "4.1.
|
|
24
|
+
"version": "4.1.7"
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"author": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"license": "AGPL-3.0-or-later",
|
|
40
40
|
"name": "superlocalmemory-codex",
|
|
41
41
|
"source": "./codex-plugin",
|
|
42
|
-
"version": "4.1.
|
|
42
|
+
"version": "4.1.7"
|
|
43
43
|
}
|
|
44
44
|
]
|
|
45
45
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ All notable changes to SuperLocalMemory 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
|
+
## [4.1.7] — Recall that improves with use
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Adaptive ranking is on by default.** Recall now learns which memories
|
|
12
|
+
actually helped and ranks accordingly. Set `SLM_RANKING=off` to opt out.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Ranking never learned anything.** Recalls were not attributed to the
|
|
16
|
+
conversation they came from, so nothing could tell whether a memory had been
|
|
17
|
+
useful, and every result was scored the same regardless. Recalls are now
|
|
18
|
+
attributed correctly and scored from real use.
|
|
19
|
+
- **Unused results are no longer scored as average.** When there is no evidence
|
|
20
|
+
either way, a result is left unscored instead of being recorded as
|
|
21
|
+
middling — which had made the ranking progressively harder to change.
|
|
22
|
+
- **Frequently shown memories no longer reinforce themselves.** A memory that
|
|
23
|
+
was going to be shown regardless now counts for less than one that was not.
|
|
24
|
+
- **Codex subagents install complete.** Installing from a published package
|
|
25
|
+
produced one-line advisor definitions instead of the full ones.
|
|
26
|
+
|
|
8
27
|
## [4.1.6] — A learning loop that never learns looks identical to one that works
|
|
9
28
|
|
|
10
29
|
### Fixed
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</picture>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
|
-
<h1 align="center">SuperLocalMemory V4.1.
|
|
8
|
+
<h1 align="center">SuperLocalMemory V4.1.7</h1>
|
|
9
9
|
|
|
10
10
|
<h2 align="center">Rent the LLM. Own the memory.</h2>
|
|
11
11
|
|
|
@@ -27,12 +27,12 @@ guarantee here is stated as a falsifiable invariant, tested under an adversarial
|
|
|
27
27
|
negative control, and shipped with the harness that regenerates the evidence:
|
|
28
28
|
<code>python benchmark/run_all.py --trials 200 --output-dir results/</code>. What each experiment
|
|
29
29
|
does <em>not</em> exercise is stated too.</p>
|
|
30
|
-
<p align="center"><code>v4.1.
|
|
30
|
+
<p align="center"><code>v4.1.7</code> — one control plane: <strong>SLM-Mesh</strong> peer coordination · multi-scope memory (personal / shared / global) · profiles · Cache · Compress · 7-layer retrieval · code graph · Entity Explorer · skill evolution · Modes A/B/C · GDPR retention & audit chain · bounded loops — across CLI, MCP, dashboard, the <strong>Claude plugin</strong>, the <strong>Codex add-on</strong>, and documented IDE integrations.<br/>
|
|
31
31
|
Proxy: <code>slm wrap claude</code> · MCP: add <code>slm_compress</code> to your config · Skill: zero-config</p>
|
|
32
32
|
<p align="center"><strong>Four public arXiv preprints</strong> · V4: <a href="https://arxiv.org/abs/2608.08253">arXiv:2608.08253</a> · companion archive: <a href="https://zenodo.org/records/21853302">Zenodo 21853302</a> (<a href="https://doi.org/10.5281/zenodo.21853302">DOI 10.5281/zenodo.21853302</a>) · prior preprints: <a href="https://arxiv.org/abs/2603.02240">2603.02240</a> · <a href="https://arxiv.org/abs/2603.14588">2603.14588</a> · <a href="https://arxiv.org/abs/2604.04514">2604.04514</a>.</p>
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
35
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/v4.1.
|
|
35
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/v4.1.7-Current_Release-2ea44f?style=for-the-badge&logo=checkmarx&logoColor=white" alt="v4.1.7 — Current Release"/></a>
|
|
36
36
|
<a href="https://arxiv.org/abs/2608.08253"><img src="https://img.shields.io/badge/arXiv-2608.08253-b31b1b?style=for-the-badge&logo=arxiv&logoColor=white" alt="SuperLocalMemory 4.0 paper on arXiv:2608.08253"/></a>
|
|
37
37
|
<a href="https://zenodo.org/records/21853302"><img src="https://img.shields.io/badge/Zenodo-10.5281%2Fzenodo.21853302-1682D4?style=for-the-badge&logo=zenodo&logoColor=white" alt="V4 paper on Zenodo: 10.5281/zenodo.21853302"/></a>
|
|
38
38
|
<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>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superlocalmemory",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.7",
|
|
4
4
|
"description": "Local-first agent memory with MCP and an agent-native CLI. Documented clients include Claude Code, Cursor, and Windsurf.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-memory",
|
|
@@ -96,6 +96,8 @@
|
|
|
96
96
|
"plugin-src/skills/slm-scope/SKILL.md",
|
|
97
97
|
"plugin-src/skills/slm-session/SKILL.md",
|
|
98
98
|
"plugin-src/skills/slm-status/SKILL.md",
|
|
99
|
+
"plugin-src/agents/slm-memory-advisor.md",
|
|
100
|
+
"plugin-src/agents/slm-optimize-advisor.md",
|
|
99
101
|
"plugin-src/rules/AGENTS.md",
|
|
100
102
|
"docs/pi-dev-integration.md",
|
|
101
103
|
"pyproject.toml",
|
package/plugin/CLAUDE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- BEGIN SuperLocalMemory v4.1.
|
|
1
|
+
<!-- BEGIN SuperLocalMemory v4.1.7 -->
|
|
2
2
|
|
|
3
3
|
## SuperLocalMemory (SLM) — Agent Rules
|
|
4
4
|
|
|
@@ -39,6 +39,6 @@ slm-recall · slm-remember · slm-session · slm-status · slm-cache · slm-comp
|
|
|
39
39
|
### Subagents
|
|
40
40
|
slm-memory-advisor (memory decisions, session hygiene, scope/profile guidance) · slm-optimize-advisor (context compression + KV cache) · slm-governance-advisor (scope/roles/compliance/GDPR)
|
|
41
41
|
|
|
42
|
-
<!-- END SuperLocalMemory v4.1.
|
|
42
|
+
<!-- END SuperLocalMemory v4.1.7 -->
|
|
43
43
|
|
|
44
|
-
SuperLocalMemory v4.1.
|
|
44
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
|
@@ -77,4 +77,4 @@ slm-scope · slm-governance · slm-profile · slm-remember · slm-recall
|
|
|
77
77
|
# What NOT to do
|
|
78
78
|
Never session_init twice; never forget without dry-run preview; never store secrets; never bypass role checks; never claim an erasure succeeded without verifying via recall.
|
|
79
79
|
|
|
80
|
-
SuperLocalMemory v4.1.
|
|
80
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
|
@@ -46,4 +46,4 @@ slm-recall · slm-remember · slm-session · slm-scope · slm-profile · slm-gov
|
|
|
46
46
|
# What NOT to do
|
|
47
47
|
Never session_init twice; never forget dry_run=False without reporting preview; never dump a whole file into remember; never invent a memory; never claim "saved" without success:true / clean CLI exit; never bypass scope or governance restrictions.
|
|
48
48
|
|
|
49
|
-
SuperLocalMemory v4.1.
|
|
49
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
|
@@ -41,4 +41,4 @@ slm-compress · slm-cache · slm-status · slm-profile
|
|
|
41
41
|
# What NOT to do
|
|
42
42
|
Never compress code-for-edit/JSON-to-parse/<500 chars; never store secrets/ccr_ids; never let optimize failure block/alter the task; never claim a specific savings %; never carry ccr_ids across profile switches.
|
|
43
43
|
|
|
44
|
-
SuperLocalMemory v4.1.
|
|
44
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
package/plugin/requirements.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
superlocalmemory==4.1.
|
|
1
|
+
superlocalmemory==4.1.7
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-memory-advisor
|
|
3
|
+
description: >
|
|
4
|
+
Advises the main agent on using SuperLocalMemory well — when to call
|
|
5
|
+
session_init, remember, recall, and search; how to phrase queries; and how
|
|
6
|
+
to keep memory clean. Delegate here for any "should I save/recall this?"
|
|
7
|
+
decision or when memory results look wrong.
|
|
8
|
+
tools: session_init, recall, search, remember, update_memory, forget, list_recent, Read
|
|
9
|
+
model: inherit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Role
|
|
13
|
+
You are the SuperLocalMemory (SLM) memory advisor. You help the main agent use the local-first memory system correctly across a session. You do not do the user's primary task — you make memory usage disciplined: the right thing saved, the right thing recalled, nothing duplicated, nothing lost between sessions. Core memory tools run against the configured local data root; optional providers, connectors, backup, and downloads have separate network behavior.
|
|
14
|
+
|
|
15
|
+
# When to act
|
|
16
|
+
When the main agent: starts a session and hasn't loaded project context; is about to or just made a decision worth persisting; asks "what did we decide about X"; gets recall results that look irrelevant/empty; needs advice on scope, profile, or governance.
|
|
17
|
+
|
|
18
|
+
# Tools you may use (real SLM MCP tools, core profile)
|
|
19
|
+
- `session_init(project_path, query, max_results, max_age_days)` — ONCE at session start; returns recent decisions + relevant memories.
|
|
20
|
+
- `recall(query, limit, session_id, fast, include_global, include_shared)` — multi-channel semantic + keyword + temporal + contextual retrieval (default limit 10). Leave `include_global`/`include_shared` unset — recall is private-by-default (v3.6.15). Returns fast local results (~1–2s, no server-side LLM round) plus confidence signals: if `no_confident_match` is true or `answer_confidence` is low, advise the main agent to rewrite into 1–3 sharper sub-queries and recall again rather than treating the memory as absent.
|
|
21
|
+
- `search(query, limit, profile_id)` — exact keyword / FTS5 BM25.
|
|
22
|
+
- `remember(content, tags, project, importance, session_id, scope, shared_with)` — store atomic fact; importance 1-10. Leave `scope` unset (defaults to `personal`/private).
|
|
23
|
+
- `update_memory(fact_id, content)` — correct by exact id.
|
|
24
|
+
- `forget(profile_id, dry_run)` — decay cycle; ALWAYS dry_run=True first, report, never apply blind.
|
|
25
|
+
- `list_recent(limit)` — newest first.
|
|
26
|
+
- `Read` — inspect a file before deciding what to remember.
|
|
27
|
+
|
|
28
|
+
# Decision rules
|
|
29
|
+
1. SESSION_INIT FIRST — once, before any recall/remember in a fresh session. Never skip; never twice.
|
|
30
|
+
2. RECALL BEFORE REMEMBER — if it exists, update_memory instead of duplicating.
|
|
31
|
+
3. REMEMBER ATOMIC DURABLE FACTS ONLY — decisions/conventions/constraints/gotchas/stable prefs; one per call; add tags+project; importance 7-10 for blockers/security/architecture.
|
|
32
|
+
4. QUERY PHRASING — concept phrases not vague words; pass session_id when available.
|
|
33
|
+
5. recall vs search — recall for conceptual; search for literal keyword.
|
|
34
|
+
6. EMPTY/LOW results → broaden, try search, or list_recent; never fabricate.
|
|
35
|
+
7. SESSION END — close_session(session_id) when work meaningfully complete.
|
|
36
|
+
8. SCOPE IS OPT-IN (v3.6.15) — every memory is `personal` (private to this profile) by default, and recall returns only this profile's facts. Do NOT set `scope="shared"/"global"` or `include_global`/`include_shared` on your own. Use them ONLY when the user EXPLICITLY asks to share memories across local profiles or to read other profiles' shared/global facts. Default behaviour is identical to single-profile SLM. See slm-scope for the complete sharing model.
|
|
37
|
+
9. PROFILE CONTEXT (v3.8.0) — session_init and all memory ops use the active profile. If the user needs to work in a different workspace, direct them to switch_profile (requires code/full/power profile). See slm-profile.
|
|
38
|
+
10. GOVERNANCE — in a governed workspace (admin/member/viewer roles), respect role restrictions: viewers must not write, members must not write global scope without authorization. See slm-governance.
|
|
39
|
+
|
|
40
|
+
# CLI fallback (MCP unavailable)
|
|
41
|
+
recall→`slm recall "<q>" --limit N` (add `--include-global`/`--include-shared` only on explicit user request) · search→`slm search "<q>"` · remember→`slm remember "<c>" --tags a,b` (project/importance are MCP-only, NOT CLI flags; `--scope shared --shared-with a,b` only when the user asks to share) · list→`slm list --limit N` · forget→`slm forget` (preview first) · status→`slm status`. session_init/close_session are daemon-implicit (no CLI verb) — skip on MCP-down.
|
|
42
|
+
|
|
43
|
+
# Related skills
|
|
44
|
+
slm-recall · slm-remember · slm-session · slm-scope · slm-profile · slm-governance
|
|
45
|
+
|
|
46
|
+
# What NOT to do
|
|
47
|
+
Never session_init twice; never forget dry_run=False without reporting preview; never dump a whole file into remember; never invent a memory; never claim "saved" without success:true / clean CLI exit; never bypass scope or governance restrictions.
|
|
48
|
+
|
|
49
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-optimize-advisor
|
|
3
|
+
description: >
|
|
4
|
+
Applies SuperLocalMemory's context-optimization rules — reversible
|
|
5
|
+
compression of large tool output and KV-caching of repeated reads/searches —
|
|
6
|
+
to stretch the context window with no proxy. Delegate here when context is
|
|
7
|
+
filling up or the same files/searches are read repeatedly. Strictly advisory
|
|
8
|
+
and fail-open: optimization must never block the primary task.
|
|
9
|
+
tools: slm_compress, slm_retrieve, slm_cache_set, slm_cache_get, slm_optimize_stats, Read, Bash
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Role
|
|
14
|
+
You are the SLM optimize advisor. You reduce context-window pressure using Surface-B tools: reversible compression (CCR) and a per-agent KV cache. No proxy; full 1M window preserved on any plan. You apply the same rules as the slm-compress and slm-cache skills. You cannot cache the primary Claude turn (needs a proxy) — only content the agent routes through SLM.
|
|
15
|
+
|
|
16
|
+
# When to act
|
|
17
|
+
Tool/file read >~2000 chars; same file or bash/web search about to be re-read; user asks how much context saved; context tight with large outputs sitting in window.
|
|
18
|
+
|
|
19
|
+
# Tools (real SLM MCP tools, core profile)
|
|
20
|
+
slm_compress(content,mode,reversible,ttl_seconds)→compressed,lossy,ccr_id (mode normalize|auto|aggressive); slm_retrieve(ccr_id); slm_cache_set(key,value,ttl_seconds); slm_cache_get(key)→hit,value; slm_optimize_stats(); Read/Bash to fetch content.
|
|
21
|
+
|
|
22
|
+
# Decision rules (the 8 — apply automatically)
|
|
23
|
+
1. CLAUDE.md >3000 chars → slm_compress(mode="normalize", reversible=False), use compressed IN CONTEXT ONLY; never modify the file.
|
|
24
|
+
2. Tool output >2000 chars → slm_compress(mode="auto", reversible=True); work from compressed; keep ccr_id if lossy.
|
|
25
|
+
3. Repeated file reads → slm_cache_get("file:<path>") first; on miss Read then slm_cache_set("file:<path>", ttl 1800); invalidate on Edit/Write.
|
|
26
|
+
4. Repeated bash/web → slm_cache_set("bash:<cmd[:64]>", ttl 600); web ttl 3600.
|
|
27
|
+
5. Retrieve original only when byte-identical needed.
|
|
28
|
+
6. NEVER compress/cache: code for Edit/Write; JSON to parse; secrets/keys/tokens; ccr_ids; <500 chars.
|
|
29
|
+
7. Stats → slm_optimize_stats() (KV this-session; proxy/compress daemon-persisted).
|
|
30
|
+
8. FAIL-OPEN: ok:false → continue with original, no retry, don't surface unless asked. Never block the task.
|
|
31
|
+
|
|
32
|
+
# Profile context (v3.8.0)
|
|
33
|
+
Cache entries are namespaced per active profile — if the user switches profiles via switch_profile, the cache is effectively fresh for the new profile. Do not carry ccr_id values across profile switches.
|
|
34
|
+
|
|
35
|
+
# CLI fallback
|
|
36
|
+
stats→`slm optimize status`/`savings` · compress→`slm compress` · cache→`slm cache ...`. If CLI also fails, drop optimization silently (rule 8).
|
|
37
|
+
|
|
38
|
+
# Related skills
|
|
39
|
+
slm-compress · slm-cache · slm-status · slm-profile
|
|
40
|
+
|
|
41
|
+
# What NOT to do
|
|
42
|
+
Never compress code-for-edit/JSON-to-parse/<500 chars; never store secrets/ccr_ids; never let optimize failure block/alter the task; never claim a specific savings %; never carry ccr_ids across profile switches.
|
|
43
|
+
|
|
44
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
|
@@ -137,4 +137,4 @@ When the SLM MCP server is unavailable, use these CLI equivalents:
|
|
|
137
137
|
- **slm-optimize-advisor** — context compression and KV cache
|
|
138
138
|
- **slm-governance-advisor** — scope/role compliance, retention policies, GDPR
|
|
139
139
|
|
|
140
|
-
SuperLocalMemory v4.1.
|
|
140
|
+
SuperLocalMemory v4.1.7 · Qualixar · AGPL-3.0-or-later
|
package/pyproject.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "superlocalmemory"
|
|
3
|
-
version = "4.1.
|
|
3
|
+
version = "4.1.7"
|
|
4
4
|
description = "Local-first agent memory with auditable hybrid retrieval"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-or-later"
|
|
@@ -186,6 +186,10 @@ superlocalmemory = ["ui/**/*", "optimize/NOTICE", "contracts/schemas/*.json"]
|
|
|
186
186
|
"share/superlocalmemory/codex/skills/slm-scope" = ["plugin-src/skills/slm-scope/SKILL.md"]
|
|
187
187
|
"share/superlocalmemory/codex/skills/slm-session" = ["plugin-src/skills/slm-session/SKILL.md"]
|
|
188
188
|
"share/superlocalmemory/codex/skills/slm-status" = ["plugin-src/skills/slm-status/SKILL.md"]
|
|
189
|
+
"share/superlocalmemory/codex/agents" = [
|
|
190
|
+
"plugin-src/agents/slm-memory-advisor.md",
|
|
191
|
+
"plugin-src/agents/slm-optimize-advisor.md",
|
|
192
|
+
]
|
|
189
193
|
"share/superlocalmemory/portable-kit/rules" = ["plugin-src/rules/AGENTS.md"]
|
|
190
194
|
|
|
191
195
|
[tool.pytest.ini_options]
|
|
@@ -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__ = "4.1.
|
|
35
|
+
__version__ = "4.1.7"
|
|
36
36
|
|
|
37
37
|
_REQUIRED_VERSIONS = {
|
|
38
38
|
"sentence_transformers": "5.3.0",
|
|
@@ -145,13 +145,27 @@ def _upgrade_host(host: str, *, apply: bool, already_integrated: bool) -> dict[s
|
|
|
145
145
|
if not assets.get("success") or not hooks.get("success"):
|
|
146
146
|
return {"status": "blocked", "detail": "could not refresh SLM-owned Codex assets"}
|
|
147
147
|
action = "would refresh" if not apply else "refreshed"
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
# Name what is actually written. Saying "refreshed skills" while the
|
|
149
|
+
# copies under ~/.agents/skills are not what this Codex reads turns a
|
|
150
|
+
# no-op into a success report.
|
|
151
|
+
written = assets.get("skills_written") or []
|
|
152
|
+
agents_written = assets.get("agents_written") or []
|
|
153
|
+
preserved = assets.get("agents_preserved") or []
|
|
154
|
+
elsewhere = assets.get("skills_read_elsewhere") or []
|
|
155
|
+
|
|
156
|
+
detail = f"{action} {len(written)} skill file(s) and {len(agents_written)} subagent file(s)"
|
|
157
|
+
if written:
|
|
158
|
+
detail += f" under {Path(written[0]).parent.parent}"
|
|
159
|
+
detail += "; hooks refreshed; MCP block preserved"
|
|
160
|
+
if preserved:
|
|
161
|
+
names = ", ".join(Path(x).name for x in preserved)
|
|
162
|
+
detail += f"; preserved {len(preserved)} subagent file(s) not written by SLM ({names})"
|
|
163
|
+
if elsewhere:
|
|
164
|
+
detail += (
|
|
165
|
+
f"; {len(elsewhere)} skill path(s) under ~/.codex/skills resolve outside "
|
|
166
|
+
f"the written location and were NOT refreshed ({Path(elsewhere[0]).parent})"
|
|
167
|
+
)
|
|
168
|
+
return {"status": "updated" if apply else "preview", "detail": detail}
|
|
155
169
|
|
|
156
170
|
if already_integrated:
|
|
157
171
|
return {
|
|
@@ -24,6 +24,7 @@ import time
|
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
from typing import Any
|
|
26
26
|
|
|
27
|
+
from superlocalmemory.core.session_identity import synthetic_session_id
|
|
27
28
|
from superlocalmemory.core.config import CANONICAL_RECALL_LIMIT, SLMConfig
|
|
28
29
|
from superlocalmemory.core.engine_capabilities import Capabilities, CapabilityError
|
|
29
30
|
from superlocalmemory.core.modes import get_capabilities
|
|
@@ -138,7 +139,12 @@ class MemoryEngine:
|
|
|
138
139
|
# one is dropped by the queue, which is how 34 of 35 recall paths came
|
|
139
140
|
# to leave no record at all.
|
|
140
141
|
self._last_session_id: str = ""
|
|
141
|
-
|
|
142
|
+
# Minted through the shared helper so this id is registered as
|
|
143
|
+
# invented rather than received; continuity and the reward pipeline
|
|
144
|
+
# both ask session_identity, and a hand-built prefix is invisible to it.
|
|
145
|
+
self._ambient_session_id: str = synthetic_session_id(
|
|
146
|
+
"engine", str(os.getpid()),
|
|
147
|
+
)
|
|
142
148
|
self._initialized = False
|
|
143
149
|
|
|
144
150
|
self._db = None
|
|
@@ -340,16 +340,23 @@ class _ReadOnlyLearningView:
|
|
|
340
340
|
def _resolve_ranking_mode(env: "dict[str, str] | os._Environ[str]") -> str:
|
|
341
341
|
"""Map the ``SLM_RANKING`` env var to a canonical mode.
|
|
342
342
|
|
|
343
|
-
``SLM_RANKING`` is an explicit operator policy.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
343
|
+
``SLM_RANKING`` is an explicit operator policy. Absence of that policy now
|
|
344
|
+
means the full pipeline, not ``off``.
|
|
345
|
+
|
|
346
|
+
It defaulted to ``off`` because a stored signal that had gone stale must
|
|
347
|
+
not start reordering results merely because someone upgraded. That risk
|
|
348
|
+
depended on a settler that scored a recall it could not observe, which no
|
|
349
|
+
longer happens: an unobserved recall leaves the ranking untouched instead
|
|
350
|
+
of being recorded as an average one, and each observation counts for less
|
|
351
|
+
the more predictable it was. A ranking layer nobody switches on is a
|
|
352
|
+
ranking layer that never learns, so the default now enables it.
|
|
353
|
+
|
|
354
|
+
Set ``SLM_RANKING=off`` to opt out.
|
|
348
355
|
"""
|
|
349
356
|
raw = (env.get("SLM_RANKING", "") or "").strip().lower()
|
|
350
357
|
if raw in _RANKING_MODES:
|
|
351
358
|
return raw
|
|
352
|
-
return "
|
|
359
|
+
return "v2-ensemble"
|
|
353
360
|
|
|
354
361
|
|
|
355
362
|
def apply_ranking(
|
|
@@ -49,7 +49,20 @@ __all__ = [
|
|
|
49
49
|
#:
|
|
50
50
|
#: The colon is deliberate: a real client id is a uuid or a hex string and does
|
|
51
51
|
#: not contain one, so a genuine id cannot be mistaken for an invented one.
|
|
52
|
-
|
|
52
|
+
#: ``engine:`` names the daemon process itself, not a caller. It is shared by
|
|
53
|
+
#: every client that reaches one daemon and changes on every restart, so it is
|
|
54
|
+
#: synthetic in exactly the way this module exists to catch: it was minted by
|
|
55
|
+
#: hand in ``core/engine.py`` rather than through ``synthetic_session_id``, and
|
|
56
|
+
#: so passed ``is_conversation`` for as long as it existed. While it did, every
|
|
57
|
+
#: recall that named no session filed its outcome under a process id that no
|
|
58
|
+
#: tool event could ever carry, and the reward pipeline had nothing to join on.
|
|
59
|
+
#: ``agent:`` and ``api:`` name the calling agent and the workspace, and are
|
|
60
|
+
#: shared by every request from either — ``agent:mcp_client`` alone held 24
|
|
61
|
+
#: outcomes from unrelated callers. Both were hand-minted in
|
|
62
|
+
#: ``server/routes/v3_api.py``, which is why neither was listed here.
|
|
63
|
+
SYNTHETIC_PREFIXES: tuple[str, ...] = (
|
|
64
|
+
"http:", "mcp:", "cli:", "probe:", "engine:", "agent:", "api:",
|
|
65
|
+
)
|
|
53
66
|
|
|
54
67
|
|
|
55
68
|
def synthetic_session_id(kind: str, discriminator: str = "") -> str:
|