superlocalmemory 4.1.20 → 4.1.22
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 +3 -3
- package/CHANGELOG.md +217 -0
- package/README.md +258 -58
- package/package.json +3 -1
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/.cursor-plugin/plugin.json +24 -0
- 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/assets/logo.svg +36 -0
- package/plugin/cursor-skills/slm-bot-memory/SKILL.md +139 -0
- package/plugin/cursor-skills/slm-getting-started-bot/SKILL.md +138 -0
- package/plugin/cursor-skills/slm-recall/SKILL.md +333 -0
- package/plugin/cursor-skills/slm-remember/SKILL.md +273 -0
- package/plugin/cursor-skills/slm-scope/SKILL.md +176 -0
- package/plugin/cursor-skills/slm-session/SKILL.md +271 -0
- package/plugin/hooks/hooks.json +9 -9
- package/plugin/mcp.cursor.json +23 -0
- package/plugin/requirements-cpu-torch.txt +13 -0
- package/plugin/requirements.txt +1 -1
- package/plugin/scripts/ensure-venv.sh +45 -3
- package/plugin/scripts/slm-launch +93 -9
- package/plugin/scripts/torch-cpu-resolve.sh +86 -0
- package/plugin/skills/slm-bot-memory/SKILL.md +139 -0
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-getting-started-bot/SKILL.md +138 -0
- 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 +5 -4
- 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 +1 -1
- package/plugin-src/agents/slm-optimize-advisor.md +1 -1
- package/plugin-src/rules/AGENTS.md +3 -3
- package/plugin-src/skills/slm-bot-memory/SKILL.md +139 -0
- 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-getting-started-bot/SKILL.md +138 -0
- 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 +5 -4
- 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/scripts/postinstall.js +107 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-bot-memory
|
|
3
|
+
description: Cross-bot memory on a shared computer (Grok Bot, Cursor plugin, any host where several agents share one machine). Explains agent_id attribution vs. profile/scope access, how to namespace by agent_id + profile + scope, and what must never be written to memory. Read this before the first remember/recall on a new Grok-Bot-style host.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
- First session on a Grok Bot computer or any shared-bot host
|
|
6
|
+
- "Will my other bots see this memory?"
|
|
7
|
+
- "How do I keep this bot's notes separate from that one?"
|
|
8
|
+
- Deciding whether to store something that looks like a secret or personal data
|
|
9
|
+
- Setting up a second bot on a computer that already has SLM configured
|
|
10
|
+
allowed-tools: remember, recall, search, session_init, switch_profile
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# slm-bot-memory — Cross-Bot Memory on a Shared Host
|
|
14
|
+
|
|
15
|
+
SuperLocalMemory ships as an MCP server. On a single-user laptop, one bot is
|
|
16
|
+
the only thing talking to it. On a **shared-bot host** — Grok Bot's "one
|
|
17
|
+
computer, shared by all your Bots" model, several Cursor windows, or any
|
|
18
|
+
setup where more than one agent process points at the same install — several
|
|
19
|
+
agents can reach the same memory store at once. This skill is about that
|
|
20
|
+
case: what is actually isolated, what is not, and what must never be written
|
|
21
|
+
regardless.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Three things that sound like isolation and are not the same
|
|
26
|
+
|
|
27
|
+
| Setting | What it controls | Does it hide memories from another bot? |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `SLM_AGENT_ID` | **Attribution** — who gets credit for a memory in logs and summaries | **No.** It is metadata, never an authenticated principal (verified in `mcp/agent_context.py`'s own docstring). Any bot that can query the same store can read a memory written under a different `agent_id`. |
|
|
30
|
+
| `SLM_DATA_DIR` (profile root) | **Which database file** the daemon opens | **Yes.** Two bots pointed at different `SLM_DATA_DIR` values have fully separate, independent memory stores — nothing is shared unless you explicitly configure sharing. |
|
|
31
|
+
| `scope` (`personal` / `shared` / `global`, see `slm-scope`) | **Visibility inside one store**, between profiles that share that store | Only the way you set it. `personal` (the default) stays within the writing profile; `shared`/`global` are explicit, user-initiated opt-ins. |
|
|
32
|
+
|
|
33
|
+
The practical rule: **`SLM_AGENT_ID` tells you who wrote something; `SLM_DATA_DIR`
|
|
34
|
+
and `scope` decide who can read it.** If two bots on the same Grok Bot computer
|
|
35
|
+
use the same `SLM_DATA_DIR` (the common case — it is a shared filesystem, and
|
|
36
|
+
nothing in Grok Bot's plugin model points different bots at different data
|
|
37
|
+
directories by default), they see each other's `personal`-scope memories too,
|
|
38
|
+
the same way two terminal sessions on one laptop would. Giving two bots
|
|
39
|
+
different `SLM_AGENT_ID` values does not change that — it only changes whose
|
|
40
|
+
name shows up on the memory.
|
|
41
|
+
|
|
42
|
+
If you need one bot's memories genuinely unreachable from another, that bot
|
|
43
|
+
needs its **own `SLM_DATA_DIR`** (or its own profile within a store that has
|
|
44
|
+
governance/roles configured — see `slm-governance`), not just its own
|
|
45
|
+
`SLM_AGENT_ID`.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Namespacing that actually works
|
|
50
|
+
|
|
51
|
+
Use all three dimensions together, each for what it is good at:
|
|
52
|
+
|
|
53
|
+
1. **`agent_id`** (`SLM_AGENT_ID` env, or the `agent_id` parameter on
|
|
54
|
+
`remember`/`recall` directly) — so a human or another agent reading
|
|
55
|
+
`get_memory_summary` or the stored facts later can tell which bot said
|
|
56
|
+
what. Set it to something stable and specific: `grok_bot_support`,
|
|
57
|
+
`grok_bot_release_notes`, not a generic `bot`.
|
|
58
|
+
2. **`profile_id`** / `SLM_DATA_DIR` — the real isolation boundary. One
|
|
59
|
+
store per bot that genuinely needs privacy from the others.
|
|
60
|
+
3. **`scope`** (see `slm-scope`) — inside a store two or more bots
|
|
61
|
+
legitimately share, keep writes `personal` by default and only promote to
|
|
62
|
+
`shared`/`global` when a fact is meant for every bot on that store.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
remember(
|
|
66
|
+
content="Deploy window for the support bot is Tue/Thu 14:00-16:00 UTC",
|
|
67
|
+
tags="ops,schedule",
|
|
68
|
+
agent_id="grok_bot_support",
|
|
69
|
+
session_id="<sid>",
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
recall(
|
|
75
|
+
query="deploy window",
|
|
76
|
+
agent_id="grok_bot_support",
|
|
77
|
+
session_id="<sid>",
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Recall is not filtered by `agent_id` automatically — it is attribution on the
|
|
82
|
+
written record, not a query filter. If you need "only what this bot wrote",
|
|
83
|
+
say so in the query text or check the `saved_by`/attribution field on the
|
|
84
|
+
results, the same way you would read any shared log.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## What never goes into memory, on any host
|
|
89
|
+
|
|
90
|
+
This is not Grok-Bot-specific — it is the baseline for every SLM host — but
|
|
91
|
+
it matters more here because a shared computer means a shared blast radius if
|
|
92
|
+
it is violated:
|
|
93
|
+
|
|
94
|
+
- **Secrets, API keys, tokens, passwords, certificates.** Never pass them to
|
|
95
|
+
`remember`, even "just this once" or "temporarily." If a fact needs to
|
|
96
|
+
reference that a credential exists, store the *fact of its existence and
|
|
97
|
+
where to rotate it*, never the value.
|
|
98
|
+
- **Personal data about identifiable people** that was not already something
|
|
99
|
+
the user explicitly asked to be remembered about themselves (names,
|
|
100
|
+
emails, addresses, health, financial details of third parties).
|
|
101
|
+
- **Anything from Grok Bot's shared filesystem you did not write yourself**
|
|
102
|
+
and were not asked to remember. "Files are visible to every Bot" on that
|
|
103
|
+
computer (Grok Bot's own docs) — a file being readable is not the same as
|
|
104
|
+
having permission to copy its contents into long-term memory that other
|
|
105
|
+
bots and later sessions will see.
|
|
106
|
+
- **Command-line credentials.** Grok Bot's own docs note these are shared
|
|
107
|
+
across bots on the computer; SLM must not become a second, more durable
|
|
108
|
+
copy of them.
|
|
109
|
+
|
|
110
|
+
If you are unsure whether something is a secret, treat it as one and ask the
|
|
111
|
+
user before storing anything derived from it.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Checklist for a new bot on an existing shared host
|
|
116
|
+
|
|
117
|
+
1. Confirm `SLM_DATA_DIR` — is this bot meant to share the existing store, or
|
|
118
|
+
does it need its own? (`slm status` or `session_init` shows the active
|
|
119
|
+
store's identity.)
|
|
120
|
+
2. Set a specific `SLM_AGENT_ID` for this bot before the first `remember`.
|
|
121
|
+
3. Read `slm-scope` before writing anything with `scope="shared"` or
|
|
122
|
+
`scope="global"` — those are machine-wide, not just cross-bot.
|
|
123
|
+
4. Read the "never goes into memory" list above once, out loud if you are
|
|
124
|
+
unsure, before the first write on this host.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Related skills
|
|
129
|
+
|
|
130
|
+
- `slm-getting-started-bot` — first-session setup for a headless bot host
|
|
131
|
+
- `slm-scope` — the personal/shared/global visibility model this skill
|
|
132
|
+
namespaces on top of
|
|
133
|
+
- `slm-profile` — switching the active workspace/tool-tier within one store
|
|
134
|
+
- `slm-governance` — role-based access when a store has multiple human/bot
|
|
135
|
+
members and real access control, not just convention
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
*SuperLocalMemory v4.1.22 · Qualixar · AGPL-3.0-or-later*
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-getting-started-bot
|
|
3
|
+
description: First-session orientation for SuperLocalMemory on a headless bot host (Grok Bot, or any Cursor-format plugin install with no hooks, no dashboard, and no interactive setup wizard). What is different here vs. Claude Code/Codex, which 18 tools are actually available, and the first three calls to make.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
- The very first session after SLM is installed as a Grok Bot / Cursor plugin
|
|
6
|
+
- "What can I do with SuperLocalMemory here?"
|
|
7
|
+
- A recall or remember call fails and you are not sure why on this host
|
|
8
|
+
- Comparing what works here vs. what the other skills describe for Claude Code
|
|
9
|
+
allowed-tools: session_init, remember, recall, switch_profile
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# slm-getting-started-bot — First Session on a Headless Bot Host
|
|
13
|
+
|
|
14
|
+
You are talking to SuperLocalMemory through its MCP server, started as
|
|
15
|
+
`uvx --from superlocalmemory==<version> slm mcp` by the plugin manifest. This
|
|
16
|
+
skill is for the ways that is different from a Claude Code or Codex install —
|
|
17
|
+
read it once per new host, not once per session.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What is NOT available here
|
|
22
|
+
|
|
23
|
+
Grok Bot (and Cursor's plugin host generally) reads only two parts of a
|
|
24
|
+
plugin: `mcpServers` and `skills`. It does not run:
|
|
25
|
+
|
|
26
|
+
- **Hooks** — no automatic session-start context load, no automatic
|
|
27
|
+
checkpoint on session end. Call `session_init` yourself at the start of a
|
|
28
|
+
session if you want prior context; nothing injects it for you.
|
|
29
|
+
- **Slash commands or sub-agents** — the `commands/` and `agents/` components
|
|
30
|
+
other SLM plugins ship are Claude-Code-shaped and are not part of this
|
|
31
|
+
install. Everything you can do here, you do through the MCP tools
|
|
32
|
+
directly.
|
|
33
|
+
- **A dashboard.** There is no browser UI to check on this host. `slm status`
|
|
34
|
+
style information comes back from the tools themselves (`session_init`'s
|
|
35
|
+
response, or asking `recall` for recent memories) — there is nothing to
|
|
36
|
+
click.
|
|
37
|
+
- **`ANTHROPIC_BASE_URL` or any Claude-specific proxy behavior.** SLM does not
|
|
38
|
+
depend on it anywhere; nothing to configure here either way.
|
|
39
|
+
|
|
40
|
+
None of this is a degraded mode — it is the whole surface. Do not tell the
|
|
41
|
+
user a feature is "missing" when it was simply never wired to this host
|
|
42
|
+
format in the first place.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What IS available: the core profile (18 tools)
|
|
47
|
+
|
|
48
|
+
This plugin sets `SLM_MCP_PROFILE=core`, the smallest tool tier, on purpose —
|
|
49
|
+
a shared, memory-tight computer should not load tool descriptions or RAM for
|
|
50
|
+
tiers it will not use. The 18 tools:
|
|
51
|
+
|
|
52
|
+
`remember`, `recall`, `search`, `fetch`, `list_recent`, `update_memory`,
|
|
53
|
+
`forget`, `session_init`, `close_session`, `slm_compress`, `slm_retrieve`,
|
|
54
|
+
`slm_cache_set`, `slm_cache_get`, `slm_optimize_stats`, `review_correction`,
|
|
55
|
+
`list_corrections`, `get_memory_summary`, `switch_profile`.
|
|
56
|
+
|
|
57
|
+
If you are looking at another skill that mentions a tool NOT in this list
|
|
58
|
+
(`build_code_graph`, `mesh_send`, anything governance/compliance-shaped), that
|
|
59
|
+
skill describes a different, larger profile (`code`, `full`, `power`) — it is
|
|
60
|
+
accurate for Claude Code or Codex installs, not for this one, unless someone
|
|
61
|
+
has deliberately reconfigured `SLM_MCP_PROFILE`.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## The first three calls on a new host
|
|
66
|
+
|
|
67
|
+
1. **`session_init`** — nothing runs this automatically here (no hooks), so
|
|
68
|
+
call it yourself at the start of the first real session:
|
|
69
|
+
```
|
|
70
|
+
session_init(project_path="<where you are working>", query="")
|
|
71
|
+
```
|
|
72
|
+
Returns recent relevant memories and a session id to pass to later calls.
|
|
73
|
+
|
|
74
|
+
2. **`remember`** one real fact, before doing anything else, as a smoke test:
|
|
75
|
+
```
|
|
76
|
+
remember(content="First session on this host, verifying setup.", tags="setup", session_id="<sid>")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
3. **`recall`** it back:
|
|
80
|
+
```
|
|
81
|
+
recall(query="first session verifying setup", session_id="<sid>")
|
|
82
|
+
```
|
|
83
|
+
If this returns the fact, the daemon, the embedding path, and the
|
|
84
|
+
CPU-only torch install all worked. If it does not, the result still tells
|
|
85
|
+
you something — see Troubleshooting below.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Cold start is slower here than on a warm laptop
|
|
90
|
+
|
|
91
|
+
The first `remember`/`recall` on a fresh `SLM_DATA_DIR` has to: resolve
|
|
92
|
+
`uvx`'s pinned `superlocalmemory` package, start the daemon, and warm an
|
|
93
|
+
embedding model (and, unless this is the lite profile, a reranker model) —
|
|
94
|
+
tens of seconds, not milliseconds. A `recall` that comes back marked
|
|
95
|
+
`"incomplete"` or with a channel reporting not-ready in that window is not a
|
|
96
|
+
bug; it means the embedding worker had not finished loading yet. Retry once
|
|
97
|
+
rather than assuming something is broken.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## This host already runs the lite bot-host profile
|
|
102
|
+
|
|
103
|
+
Unless something overrode it, `mcp.cursor.json` sets `SLM_RERANKER_ENABLED=
|
|
104
|
+
false`, `SLM_RERANKER_IDLE_TIMEOUT=120`, and `SLM_MAX_EMBEDDING_WORKERS=1` —
|
|
105
|
+
the RAM-conscious default for a computer shared by every bot on it. Recall
|
|
106
|
+
still runs every other channel (BM25, semantic, entity graph, temporal,
|
|
107
|
+
spreading activation, Hopfield) and fuses them; it just skips the
|
|
108
|
+
cross-encoder re-ranking pass. If recall quality seems to matter more than
|
|
109
|
+
RAM headroom for your use case, the user can set `SLM_RERANKER_ENABLED=true`
|
|
110
|
+
in the manifest's env block — ask before changing it, since it trades RAM for
|
|
111
|
+
quality on a shared box.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Troubleshooting
|
|
116
|
+
|
|
117
|
+
- **A tool call returns a "profile" or "tool not available" style error** —
|
|
118
|
+
you are probably calling a tool outside the 18-tool core set. Check the
|
|
119
|
+
list above before assuming the server is broken.
|
|
120
|
+
- **Everything times out on the very first call of a session** — likely the
|
|
121
|
+
cold-start warmup described above. Wait and retry once before reporting a
|
|
122
|
+
failure.
|
|
123
|
+
- **You are not sure whether another bot on this computer can see what you
|
|
124
|
+
just stored** — read `slm-bot-memory` before storing anything you would
|
|
125
|
+
not want another bot on this machine to read.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Related skills
|
|
130
|
+
|
|
131
|
+
- `slm-bot-memory` — cross-bot namespacing and what must never be stored
|
|
132
|
+
- `slm-remember` / `slm-recall` — full parameter reference for the two tools
|
|
133
|
+
you will use the most
|
|
134
|
+
- `slm-session` — what `session_init`/`close_session` actually do
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
*SuperLocalMemory v4.1.22 · Qualixar · AGPL-3.0-or-later*
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slm-recall
|
|
3
|
+
description: Search and retrieve facts, decisions, and past context from SuperLocalMemory. Use when the user asks to recall, find, search, or "what did we decide/say about X". Triggers multi-channel semantic retrieval with reranking; always call before storing anything new.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
- "What did we decide about X?"
|
|
6
|
+
- "Recall anything about Y"
|
|
7
|
+
- "Do we have context on the Z feature?"
|
|
8
|
+
- "Find stored information about authentication / the database / error handling"
|
|
9
|
+
- "Search for what I said about Y"
|
|
10
|
+
- Automatically before any non-trivial task, to surface prior context
|
|
11
|
+
allowed-tools: recall, search, fetch, list_recent, Bash
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# slm-recall — Search & Retrieve Memory
|
|
15
|
+
|
|
16
|
+
Retrieve stored facts, decisions, and past context from SuperLocalMemory using
|
|
17
|
+
multi-channel retrieval. The golden rule: **recall before you remember**.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to use recall vs search vs fetch vs list_recent
|
|
22
|
+
|
|
23
|
+
| Situation | Tool |
|
|
24
|
+
|-----------|------|
|
|
25
|
+
| Conceptual or paraphrase query ("what did we agree on for auth?") | `recall` — full multi-channel retrieval + rerank |
|
|
26
|
+
| Exact keyword match needed ("find facts containing BM25") | `search` — FTS5 BM25 only, lower latency |
|
|
27
|
+
| You have a specific `fact_id` from a prior result | `fetch` — exact lookup, full detail |
|
|
28
|
+
| Browse newest entries without a query | `list_recent` |
|
|
29
|
+
|
|
30
|
+
Use `recall` as the default. `search` is a fallback for zero-result recall on a
|
|
31
|
+
known exact term. `fetch` is for when you already know the ID.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Recall-before-remember discipline
|
|
36
|
+
|
|
37
|
+
Before storing anything new, always call `recall` first. If a near-duplicate
|
|
38
|
+
fact already exists, call `update_memory(fact_id, content)` to refine it
|
|
39
|
+
rather than creating a duplicate. Duplicates degrade retrieval quality for
|
|
40
|
+
every future session.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## MCP-first workflow
|
|
45
|
+
|
|
46
|
+
### 1. Standard recall
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
recall(
|
|
50
|
+
query="authentication strategy decision",
|
|
51
|
+
limit=20, # default 20; reduce to 5 for quick pre-task checks
|
|
52
|
+
session_id="<sid>", # pass the session_id returned by session_init
|
|
53
|
+
fast=None, # leave unset; see "Fast mode" below for what it controls
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Real response shape (`--json` equivalent):
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"success": true,
|
|
61
|
+
"results": [
|
|
62
|
+
{
|
|
63
|
+
"fact_id": "f8a2bc91",
|
|
64
|
+
"content": "Decided to use JWT with 1h expiry for API auth (2026-06-10)",
|
|
65
|
+
"score": 0.87,
|
|
66
|
+
"confidence": 0.91,
|
|
67
|
+
"trust_score": 0.84,
|
|
68
|
+
"fact_type": "semantic",
|
|
69
|
+
"channel_scores": {
|
|
70
|
+
"semantic": 0.88,
|
|
71
|
+
"bm25": 0.61,
|
|
72
|
+
"temporal": 0.72,
|
|
73
|
+
"hopfield": 0.55
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"count": 1,
|
|
78
|
+
"query_type": "semantic",
|
|
79
|
+
"channel_weights": {
|
|
80
|
+
"semantic": 0.4,
|
|
81
|
+
"bm25": 0.2,
|
|
82
|
+
"temporal": 0.2,
|
|
83
|
+
"hopfield": 0.2
|
|
84
|
+
},
|
|
85
|
+
"channel_status": {
|
|
86
|
+
"semantic": "ok",
|
|
87
|
+
"bm25": "ok",
|
|
88
|
+
"temporal": "empty",
|
|
89
|
+
"hopfield": "ok",
|
|
90
|
+
"spreading_activation": "no_candidates",
|
|
91
|
+
"entity_graph": "no_embedding",
|
|
92
|
+
"profile": "disabled"
|
|
93
|
+
},
|
|
94
|
+
"incomplete_channels": [],
|
|
95
|
+
"retrieval_time_ms": 134,
|
|
96
|
+
"no_confident_match": false,
|
|
97
|
+
"calibration_status": "uncalibrated",
|
|
98
|
+
"calibration_id": null,
|
|
99
|
+
"answer_confidence": null,
|
|
100
|
+
"abstained": false,
|
|
101
|
+
"abstention_reason": null
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Read `channel_status` before concluding that nothing is stored.** It reports
|
|
106
|
+
what each retrieval channel did on this query. `channel_weights` says how much
|
|
107
|
+
each channel counts; `channel_status` says whether it ran at all.
|
|
108
|
+
|
|
109
|
+
| status | meaning |
|
|
110
|
+
|---|---|
|
|
111
|
+
| `ok` | the channel ran and contributed candidates |
|
|
112
|
+
| `empty` | it ran and there was genuinely nothing to return |
|
|
113
|
+
| `no_candidates` | it ran but nothing survived fusion |
|
|
114
|
+
| `error` | it raised — **its results are missing from this answer** |
|
|
115
|
+
| `timeout` | it exceeded its guard — **results missing** |
|
|
116
|
+
| `no_embedding` | the query could not be embedded, so it could not run |
|
|
117
|
+
| `disabled` | switched off by configuration |
|
|
118
|
+
| `not_configured` | the backing service is not set up |
|
|
119
|
+
|
|
120
|
+
`semantic`, `bm25`, `temporal`, `hopfield` and `spreading_activation` each
|
|
121
|
+
search and return their own candidates. `profile` is a shortcut that runs before
|
|
122
|
+
them and can answer directly. `entity_graph` produces nothing of its own — it
|
|
123
|
+
re-scores what the others found, by how well each result connects to the
|
|
124
|
+
entities in your question, which is why it reports `no_candidates` when the
|
|
125
|
+
rest come back empty.
|
|
126
|
+
|
|
127
|
+
`empty`, `no_candidates`, `disabled` and `not_configured` are normal. `error`,
|
|
128
|
+
`timeout` and `no_embedding` mean the answer is **incomplete, not negative** —
|
|
129
|
+
say so to the user rather than reporting "no memories found". `incomplete_channels`
|
|
130
|
+
carries the same warning as a plain list.
|
|
131
|
+
|
|
132
|
+
**Refine on low confidence.** `recall` returns confidence signals with every result. If `no_confident_match` is `true` (or `answer_confidence` is low / `abstained` is `true`), do NOT invent a memory — rewrite the query into 1–3 more specific sub-queries (split multi-hop questions; try entity names, synonyms, or broader phrasing) and call `recall` again before concluding nothing was found. A confident match → use it directly. SLM answers from this machine in about 1–2 s, with no server-side LLM round — unless the user turned on the online answer check, which adds one request to that service per recall — and lets you, the calling model, drive this refinement.
|
|
133
|
+
|
|
134
|
+
**`abstained` means the results shown do not answer the question.** If `abstained` is `true`, say you don't have it, or ask — never present the returned memories as the answer anyway. `abstention_reason` distinguishes why: `"judged_insufficient"` means candidates were found and scored, but none of them actually answers this question; `"evidence_floor"` / `"no_candidates"` means nothing was found at all. `answer_confidence` is a measurement, not a guarantee — treat a low number the same way you'd treat `abstained: true`. `calibration_status: "uncalibrated"` means no judge is configured for this recall; in that case `abstained` only ever reflects the older "nothing found" signal.
|
|
135
|
+
|
|
136
|
+
### 2. Passing session_id
|
|
137
|
+
|
|
138
|
+
Pass the `session_id` returned by `session_init`, on **every** recall in that
|
|
139
|
+
session. It does two things.
|
|
140
|
+
|
|
141
|
+
1. **It carries the conversation forward.** Each recall offers its five
|
|
142
|
+
best-ranked results to a small per-session working set of seven slots. A
|
|
143
|
+
memory that keeps coming back is reinforced rather than duplicated, and the
|
|
144
|
+
least-activated slot is the one evicted, so something referenced across
|
|
145
|
+
several turns is hard to lose. Later recalls in the same session rank the
|
|
146
|
+
held memories higher, and turn three is not as cold as turn one. The bias is
|
|
147
|
+
deliberately small — it nudges the order, it never overrides an exact match.
|
|
148
|
+
2. **It attributes engagement to the session**, so a later `report_outcome`
|
|
149
|
+
can close the loop on the right recall.
|
|
150
|
+
|
|
151
|
+
Omitting it costs both: recall still returns correct results, but every turn
|
|
152
|
+
starts cold and no feedback is attributable.
|
|
153
|
+
|
|
154
|
+
**Use the real id, not a made-up one.** An id beginning `http:`, `mcp:`, `cli:`
|
|
155
|
+
or `probe:` is treated as a synthetic per-request label, not a conversation, and
|
|
156
|
+
is excluded from the working set — inventing one per call would otherwise fill
|
|
157
|
+
the registry and evict genuine conversations.
|
|
158
|
+
|
|
159
|
+
### 3. Fast mode
|
|
160
|
+
|
|
161
|
+
`fast` controls **one** thing: whether the server runs its own internal LLM
|
|
162
|
+
reformulation round. It does **not** disable any retrieval channel — every
|
|
163
|
+
channel and the reranker run either way. There are four always: meaning,
|
|
164
|
+
keyword, entity graph and time. Spreading activation and Hopfield register as a
|
|
165
|
+
fifth and sixth when their prerequisites are present, so a store sees up to six.
|
|
166
|
+
|
|
167
|
+
Leave it unset. Unset resolves to "skip the internal round", because you are the
|
|
168
|
+
reasoner: you refine the query yourself using the confidence signals above, and
|
|
169
|
+
you do it better than a local model would. Pass `fast=False` only when SLM is
|
|
170
|
+
deployed with no capable client in front of it.
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
recall(query="rate limiting approach", limit=5, session_id="<sid>")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 4. Keyword fallback via search
|
|
177
|
+
|
|
178
|
+
When `recall` returns zero results on a specific term, try `search`:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
search(query="BM25 indexing", limit=10, profile_id="")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`profile_id=""` uses the active profile. Response has `success`, `results`,
|
|
185
|
+
and `count` but no `channel_scores` or `query_type`.
|
|
186
|
+
|
|
187
|
+
### 5. Pull full detail for a known fact
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
fetch(fact_ids="f8a2bc91,d4c1e203")
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Returns the full record for each ID: `entities`, `lifecycle`, `access_count`,
|
|
194
|
+
`importance`, `observation_date`, `referenced_date`. Use this when the recall
|
|
195
|
+
summary (120-char truncation in `list_recent`) is not enough.
|
|
196
|
+
|
|
197
|
+
### 6. Browse recent memories
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
list_recent(limit=20, profile_id="")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Returns facts newest-first. Content is truncated to 120 chars. Use `fetch`
|
|
204
|
+
once you have the `fact_id` for full content.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### 7. Close the loop — say which memories helped
|
|
209
|
+
|
|
210
|
+
Retrieval ranks a memory partly on whether it has actually been useful before.
|
|
211
|
+
That evidence only exists if you supply it.
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
report_outcome(
|
|
215
|
+
memory_ids="f8a2bc91,c31d0f77", # the ids you actually used
|
|
216
|
+
outcome="success", # "success" | "failure" | "partial"
|
|
217
|
+
context="used the JWT expiry decision to write the refresh handler",
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Call it when a recall visibly changed what you did: you applied the decision,
|
|
222
|
+
followed the convention, or avoided the gotcha. Report `failure` when a
|
|
223
|
+
confidently-returned memory turned out to be wrong or stale — a negative signal
|
|
224
|
+
is worth as much as a positive one, and it is the only way a stale memory stops
|
|
225
|
+
being promoted.
|
|
226
|
+
|
|
227
|
+
Report only ids you genuinely used. Reporting every returned id marks the
|
|
228
|
+
irrelevant ones useful and trains the ranker toward noise.
|
|
229
|
+
|
|
230
|
+
`report_feedback(fact_id, feedback, query)` is the finer-grained form for a
|
|
231
|
+
single fact and the query that surfaced it.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## How multi-channel retrieval works
|
|
236
|
+
|
|
237
|
+
`recall` runs multiple candidate producers in parallel — semantic vector similarity,
|
|
238
|
+
keyword matching, temporal recency weighting, and contextual graph channels — then
|
|
239
|
+
fuses and reranks the combined results, with an optional entity-graph score
|
|
240
|
+
enhancement. The `channel_weights` field in the response shows how each channel
|
|
241
|
+
contributed for that query. Weights adapt over time based on engagement signals
|
|
242
|
+
attributed via `session_id`.
|
|
243
|
+
|
|
244
|
+
To inspect per-channel scores for a real query against your own data:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
slm trace "<query>" [--limit N] [--json]
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
No benchmark numbers are cited here; performance is workload-dependent.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## CLI fallback (when MCP is unavailable)
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Multi-channel semantic recall
|
|
258
|
+
slm recall "<query>" [--limit N] [--fast] [--json]
|
|
259
|
+
|
|
260
|
+
# Opt into shared/global facts for one query (v3.6.15 — off by default)
|
|
261
|
+
slm recall "<query>" --include-global --include-shared
|
|
262
|
+
|
|
263
|
+
# Keyword/FTS5 search (alias: slm search)
|
|
264
|
+
slm search "<query>" [--limit N] [--json]
|
|
265
|
+
|
|
266
|
+
# Per-channel score breakdown
|
|
267
|
+
slm trace "<query>" [--limit N] [--json]
|
|
268
|
+
|
|
269
|
+
# Browse recent memories
|
|
270
|
+
slm list [--limit N] [--json]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Flags verified in source (main.py):
|
|
274
|
+
- `slm recall`: `--limit`, `--fast`, `--json`, `--include-global` / `--no-global`, `--include-shared` / `--no-shared`
|
|
275
|
+
- `slm search`: `--limit`, `--json`
|
|
276
|
+
- `slm trace`: `--limit`, `--json`
|
|
277
|
+
- `slm list`: `--limit` / `-n`, `--json`
|
|
278
|
+
|
|
279
|
+
> **Multi-scope (v3.6.15, opt-in):** recall is shared-OFF by default — it returns only
|
|
280
|
+
> this profile's facts. Pass `--include-global` / `--include-shared` (or the MCP
|
|
281
|
+
> `include_global` / `include_shared` args) to opt in for a query, or set the defaults in
|
|
282
|
+
> your `mode_a/b/c.json` config. See [docs/shared-memory.md](../../../docs/shared-memory.md).
|
|
283
|
+
|
|
284
|
+
**Flags that do NOT exist** (fabricated in old skills — never write these):
|
|
285
|
+
`--min-score`, `--format`, `--project`, `--tags` on recall or search.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Never fabricate a memory
|
|
290
|
+
|
|
291
|
+
After re-querying with refined sub-queries (see **Refine on low confidence** above), if `no_confident_match` is still `true` or results are empty, report it plainly.
|
|
292
|
+
Never construct a response as if a memory was found when it was not. The user
|
|
293
|
+
trusts that what you surface came from the store.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Multi-scope retrieval (v3.6.15+, opt-in)
|
|
298
|
+
|
|
299
|
+
By default `recall` returns only memories in the active profile (personal scope).
|
|
300
|
+
To also surface memories shared from other profiles, pass the scope flags:
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
recall(
|
|
304
|
+
query="...",
|
|
305
|
+
include_global=True, # include global-scope memories (visible to all profiles)
|
|
306
|
+
include_shared=True, # include shared-scope memories (shared with this profile)
|
|
307
|
+
session_id="<sid>",
|
|
308
|
+
)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Scope flags are **off by default**. Only enable them when the user explicitly asks
|
|
312
|
+
to see shared or global facts. See `slm-scope` for the full sharing model.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Profile-aware retrieval (v3.8.0+)
|
|
317
|
+
|
|
318
|
+
`recall` always queries the currently active profile. To query a different
|
|
319
|
+
workspace, use `switch_profile` (requires `code`, `full`, or `power` MCP profile)
|
|
320
|
+
before recalling, then switch back. See `slm-profile` for workspace switching.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Related skills
|
|
325
|
+
|
|
326
|
+
- `slm-remember` — store the decisions and facts that recall surfaces later
|
|
327
|
+
- `slm-session` — session lifecycle (must call before first recall)
|
|
328
|
+
- `slm-scope` — multi-scope sharing model (personal / shared / global)
|
|
329
|
+
- `slm-profile` — workspace isolation and profile switching
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
*SuperLocalMemory v4.1.22 · Qualixar · AGPL-3.0-or-later*
|