opencode-memory-pro 1.3.0
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/LICENSE +24 -0
- package/README.md +409 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +398 -0
- package/dist/embedder.d.ts +26 -0
- package/dist/embedder.js +260 -0
- package/dist/extract.d.ts +4 -0
- package/dist/extract.js +181 -0
- package/dist/graph.js +701 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +953 -0
- package/dist/llm.d.ts +14 -0
- package/dist/llm.js +212 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +126 -0
- package/dist/ports.d.ts +34 -0
- package/dist/ports.js +129 -0
- package/dist/preference.d.ts +10 -0
- package/dist/preference.js +125 -0
- package/dist/scope.d.ts +2 -0
- package/dist/scope.js +48 -0
- package/dist/store.d.ts +194 -0
- package/dist/store.js +2738 -0
- package/dist/summarize.d.ts +52 -0
- package/dist/summarize.js +350 -0
- package/dist/tools/episodic.d.ts +68 -0
- package/dist/tools/episodic.js +145 -0
- package/dist/tools/feedback.d.ts +51 -0
- package/dist/tools/feedback.js +112 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +3 -0
- package/dist/tools/memory.d.ts +293 -0
- package/dist/tools/memory.js +1487 -0
- package/dist/types.d.ts +489 -0
- package/dist/types.js +54 -0
- package/dist/utils.d.ts +18 -0
- package/dist/utils.js +214 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Todd (opencode-memory-pro contributors)
|
|
4
|
+
|
|
5
|
+
Fork of lancedb-opencode-pro (c) tryweb — MIT licensed.
|
|
6
|
+
Original: https://github.com/tryweb/lancedb-opencode-pro
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# opencode-memory-pro
|
|
2
|
+
|
|
3
|
+
Long-term memory subsystem for [OpenCode](https://opencode.ai) — a maintained,
|
|
4
|
+
standalone fork of `lancedb-opencode-pro`. It stores memories in LanceDB,
|
|
5
|
+
embeds them locally or via OpenAI, builds an offline entity graph to boost and
|
|
6
|
+
expand recall, tracks its own effectiveness, and ships a full lifecycle toolkit
|
|
7
|
+
(backup, digests, retention, scoping, episodic learning). No source patching
|
|
8
|
+
required: install the package directly.
|
|
9
|
+
|
|
10
|
+
## Highlights
|
|
11
|
+
|
|
12
|
+
- **LanceDB vector store** with IVF + hybrid (vector ✚ BM25) retrieval, real
|
|
13
|
+
recency/importance/feedback scoring, and automatic compaction.
|
|
14
|
+
- **Offline entity graph (no LLM)** — sqlite-backed co-occurrence + typed
|
|
15
|
+
relation edges (`uses`, `depends_on`, ...), BFS graph-expansion recall, and a
|
|
16
|
+
`[graph+X%/n]` boost on search results.
|
|
17
|
+
- **Hybrid capture** — offline keyword heuristics by default, or LLM-quality
|
|
18
|
+
structured extraction and abstractive digests via the OpenCode SDK (no API
|
|
19
|
+
keys in plugin config).
|
|
20
|
+
- **Memory lifecycle tools** — export/import, summarize/digest, expiry,
|
|
21
|
+
dedup consolidation, scoping (promote/demote), citations, and a retention
|
|
22
|
+
policy that *digests then hides* — it never deletes memories.
|
|
23
|
+
- **Self-observing** — effectiveness events, KPI dashboard, weekly learning
|
|
24
|
+
summary, and feedback wiring (`memory_feedback_*`) that feeds recall scoring.
|
|
25
|
+
- **Episodic learning** — session/task episodes, similar-task recall, retry
|
|
26
|
+
budget and recovery-strategy suggestions, success-pattern persistence.
|
|
27
|
+
- **Correct OpenCode ≥ 1.x wiring** — `session.created` / `session.deleted`,
|
|
28
|
+
per-session scoping, and fault-tolerant capture (falls back to heuristics
|
|
29
|
+
when the LLM or embedder is offline).
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
From a local tarball (or point at the repo):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm pack # -> opencode-memory-pro-<version>.tgz
|
|
37
|
+
opencode plugin ./opencode-memory-pro-<version>.tgz -g
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or from npm once published:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
opencode plugin opencode-memory-pro
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Remove the old plugin pin at the same time:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
opencode plugin lancedb-opencode-pro -g # removes pin (if installed)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
The sidecar file `opencode-memory-pro.json` is resolved from (first match
|
|
55
|
+
wins, then depth-merges):
|
|
56
|
+
|
|
57
|
+
1. `~/.opencode/opencode-memory-pro.json`
|
|
58
|
+
2. `~/.config/opencode/opencode-memory-pro.json`
|
|
59
|
+
3. `<worktree>/.opencode/opencode-memory-pro.json`
|
|
60
|
+
4. `OPENCODE_MEMORY_PRO_CONFIG_PATH` (explicit path; set
|
|
61
|
+
`OPENCODE_MEMORY_PRO_SKIP_SIDECAR=true` to disable sidecar loading entirely)
|
|
62
|
+
|
|
63
|
+
Legacy `config.memory` blocks in `opencode.json` are still honored and
|
|
64
|
+
deep-merged underneath the sidecar. Every setting below has an
|
|
65
|
+
`OPENCODE_MEMORY_PRO_*` environment override that always wins over the file.
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"provider": "opencode-memory-pro",
|
|
70
|
+
"dbPath": "~/.opencode/memory/lancedb",
|
|
71
|
+
"embedding": { "provider": "openai", "model": "openai/text-embedding-3-small" },
|
|
72
|
+
"graph": { "enabled": true },
|
|
73
|
+
"retention": { "memory": { "enabled": true } }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Embedding
|
|
78
|
+
|
|
79
|
+
| Key | Default | Description |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `embedding.provider` | `"ollama"` | `"ollama"` or `"openai"`. |
|
|
82
|
+
| `embedding.model` | `"nomic-embed-text"` (ollama) / required (openai) | Embedding model. |
|
|
83
|
+
| `embedding.baseUrl` | `http://127.0.0.1:11434` / `https://api.openai.com/v1` | API base URL. |
|
|
84
|
+
| `embedding.apiKey` | — | OpenAI only; required (or via env). |
|
|
85
|
+
| `embedding.timeoutMs` | `6000` | Request timeout (min 500). |
|
|
86
|
+
| `embedding.retry.enabled` | `true` | Retry failed embedding calls. |
|
|
87
|
+
| `embedding.retry.maxAttempts` | `3` | Max attempts. |
|
|
88
|
+
| `embedding.retry.initialDelayMs` | `1000` | Initial backoff delay. |
|
|
89
|
+
| `embedding.retry.backoffMultiplier` | `2` | Exponential backoff factor. |
|
|
90
|
+
|
|
91
|
+
Env: `OPENCODE_MEMORY_PRO_EMBEDDING_PROVIDER`, `..._EMBEDDING_MODEL`,
|
|
92
|
+
`..._OPENAI_BASE_URL`, `..._OLLAMA_BASE_URL`, `..._OPENAI_API_KEY`,
|
|
93
|
+
`..._OPENAI_MODEL`, `..._OPENAI_TIMEOUT_MS` / `..._EMBEDDING_TIMEOUT_MS`,
|
|
94
|
+
`..._EMBEDDING_RETRY_ENABLED`, `..._EMBEDDING_RETRY_MAX_ATTEMPTS`,
|
|
95
|
+
`..._EMBEDDING_RETRY_INITIAL_DELAY_MS`, `..._EMBEDDING_RETRY_BACKOFF_MULTIPLIER`.
|
|
96
|
+
|
|
97
|
+
If the embedder is unreachable, recall falls back to pure BM25 over the FTS
|
|
98
|
+
index and capture still works — the plugin is offline-tolerant by design.
|
|
99
|
+
|
|
100
|
+
### Retrieval
|
|
101
|
+
|
|
102
|
+
| Key | Default | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `retrieval.mode` | `"hybrid"` | `"hybrid"` (vector+BM25 RRF) or `"vector"`. |
|
|
105
|
+
| `retrieval.vectorWeight` | `0.7` | Vector/BM25 ratio before normalization. |
|
|
106
|
+
| `retrieval.bm25Weight` | `0.3` | (Weights are normalized to sum 1.) |
|
|
107
|
+
| `retrieval.minScore` | `0.2` | Minimum score for a result to qualify. |
|
|
108
|
+
| `retrieval.rrfK` | `60` | RRF constant. |
|
|
109
|
+
| `retrieval.recencyBoost` | `true` | Boost recently recalled/created memories. |
|
|
110
|
+
| `retrieval.recencyHalfLifeHours` | `72` | Half-life of the recency boost. |
|
|
111
|
+
| `retrieval.importanceWeight` | `0.4` | Weight of stored importance in scoring (0–2). |
|
|
112
|
+
| `retrieval.feedbackWeight` | `0.3` | Weight of feedback history in scoring (0–1). |
|
|
113
|
+
|
|
114
|
+
Env: `OPENCODE_MEMORY_PRO_RETRIEVAL_MODE`, `..._VECTOR_WEIGHT`,
|
|
115
|
+
`..._BM25_WEIGHT`, `..._MIN_SCORE`, `..._RRF_K`, `..._RECENCY_BOOST`,
|
|
116
|
+
`..._RECENCY_HALF_LIFE_HOURS`, `..._IMPORTANCE_WEIGHT`, `..._FEEDBACK_WEIGHT`.
|
|
117
|
+
|
|
118
|
+
### Injection
|
|
119
|
+
|
|
120
|
+
How memories are injected into the model context.
|
|
121
|
+
|
|
122
|
+
| Key | Default | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `injection.mode` | `"fixed"` | `"fixed"` (n memories), `"budget"` (fill token budget), `"adaptive"` (score-aware). |
|
|
125
|
+
| `injection.maxMemories` | `3` | Max memories injected (fixed mode). |
|
|
126
|
+
| `injection.minMemories` | `1` | Min memories always injected. |
|
|
127
|
+
| `injection.budgetTokens` | `4096` | Token budget (budget/adaptive modes). |
|
|
128
|
+
| `injection.maxCharsPerMemory` | `1200` | Per-memory character cap. |
|
|
129
|
+
| `injection.summarization` | `"none"` | `"none"` / `"truncate"` / `"extract"` / `"auto"`. |
|
|
130
|
+
| `injection.summaryTargetChars` | `300` | Target length for summarized memories. |
|
|
131
|
+
| `injection.scoreDropTolerance` | `0.15` | Allowed score drop when filling a budget. |
|
|
132
|
+
| `injection.injectionFloor` | `0.2` | Hard score floor for injected memories. |
|
|
133
|
+
| `injection.codeSummarization.enabled` | `true` | Summarize code-heavy memories on injection. |
|
|
134
|
+
| `injection.codeSummarization.pureCodeThreshold` | `500` | Chars of pure code that trigger it. |
|
|
135
|
+
| `injection.codeSummarization.maxCodeLines` | `15` | Max code lines kept. |
|
|
136
|
+
| `injection.codeSummarization.codeTruncationMode` | `"smart"` | `"smart"` / `"signature"` / `"preserve"`. |
|
|
137
|
+
| `injection.codeSummarization.preserveComments` | `true` | Keep leading comments. |
|
|
138
|
+
| `injection.codeSummarization.preserveImports` | `false` | Keep import statements. |
|
|
139
|
+
| `injection.taskTypeProfiles.*` | per-type | Per task type: `maxMemories`, `budgetTokens`, `summaryTargetChars`, `categoryWeights`. |
|
|
140
|
+
|
|
141
|
+
Task types: `coding`, `documentation`, `review`, `release`, `general`.
|
|
142
|
+
|
|
143
|
+
Env (subset): `OPENCODE_MEMORY_PRO_INJECTION_MODE`, `..._INJECTION_MAX_MEMORIES`,
|
|
144
|
+
`..._INJECTION_MIN_MEMORIES`, `..._INJECTION_BUDGET_TOKENS`,
|
|
145
|
+
`..._INJECTION_MAX_CHARS`, `..._INJECTION_SUMMARIZATION`,
|
|
146
|
+
`..._INJECTION_SUMMARY_TARGET_CHARS`, `..._INJECTION_SCORE_DROP_TOLERANCE`,
|
|
147
|
+
`..._INJECTION_FLOOR`, `..._CODE_SUMMARIZATION_ENABLED`, plus
|
|
148
|
+
`..._INJECTION_{CODING,DOCS,REVIEW,RELEASE,GENERAL}_{MAX_MEMORIES,BUDGET_TOKENS,SUMMARY_CHARS}`.
|
|
149
|
+
|
|
150
|
+
### Dedup
|
|
151
|
+
|
|
152
|
+
| Key | Default | Description |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `dedup.enabled` | `true` | Write-time dedup + consolidation. |
|
|
155
|
+
| `dedup.writeThreshold` | `0.92` | Cosine similarity that blocks a duplicate write. |
|
|
156
|
+
| `dedup.consolidateThreshold` | `0.95` | Similarity that merges duplicates during consolidation. |
|
|
157
|
+
| `dedup.candidateLimit` | `50` | ANN candidates considered per row (10–200, clamped). |
|
|
158
|
+
|
|
159
|
+
Env: `OPENCODE_MEMORY_PRO_DEDUP_ENABLED`, `..._DEDUP_WRITE_THRESHOLD`,
|
|
160
|
+
`..._DEDUP_CONSOLIDATE_THRESHOLD`, `..._DEDUP_CANDIDATE_LIMIT`.
|
|
161
|
+
|
|
162
|
+
Consolidation runs automatically on `session.idle` (throttled to a 30-min
|
|
163
|
+
cooldown), `session.deleted` (forced final pass), and `session.compacted`.
|
|
164
|
+
Recent memories (last-recalled within 5 min) and already-merged rows are
|
|
165
|
+
skipped. The batch size of the ANN consolidation queries is tunable via
|
|
166
|
+
`OPENCODE_MEMORY_PRO_QUERY_BATCH` (default `16`).
|
|
167
|
+
|
|
168
|
+
### Entity graph
|
|
169
|
+
|
|
170
|
+
| Key | Default | Description |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `graph.enabled` | `true` | Enable the offline entity graph. |
|
|
173
|
+
| `graph.dbPath` | `~/.opencode/memory/graph.db` | sqlite location. |
|
|
174
|
+
| `graph.boostLambda` | `0.3` | Entity-overlap score boost (0–1). |
|
|
175
|
+
| `graph.maxEntitiesPerMemory` | `20` | Max entities extracted per memory/query. |
|
|
176
|
+
| `graph.maxEdgeProvenance` | `20` | Max memories backing an edge (bounds stored weight). |
|
|
177
|
+
| `graph.typedEdges` | `true` | Emit typed relation edges (`uses`, `depends_on`, ...). |
|
|
178
|
+
| `graph.expansionEnabled` | `true` | BFS graph-expansion recall. |
|
|
179
|
+
| `graph.maxHops` | `2` | BFS depth (1–4). |
|
|
180
|
+
| `graph.expansionLimit` | `5` | Max expanded candidates. |
|
|
181
|
+
| `graph.expansionLambda` | `0.3` | Expansion score weight (0–1). |
|
|
182
|
+
|
|
183
|
+
Env: `OPENCODE_MEMORY_PRO_GRAPH_ENABLED`, `..._GRAPH_DB_PATH`,
|
|
184
|
+
`..._GRAPH_BOOST_LAMBDA`, `..._GRAPH_TYPED_EDGES`, `..._GRAPH_EXPANSION_ENABLED`,
|
|
185
|
+
`..._GRAPH_MAX_HOPS`, `..._GRAPH_EXPANSION_LIMIT`, `..._GRAPH_EXPANSION_LAMBDA`.
|
|
186
|
+
|
|
187
|
+
Expansion fetches each entity's strongest, most-recent edges first and applies
|
|
188
|
+
a ranking-only recency decay (edges ≥ 1 year old fade to a 0.35 floor), so
|
|
189
|
+
stale connections lose influence without ever being deleted.
|
|
190
|
+
|
|
191
|
+
### Capture modes
|
|
192
|
+
|
|
193
|
+
`capture.mode` selects how session content becomes memories (and how
|
|
194
|
+
`memory_summarize` / `memory_expire` build digests):
|
|
195
|
+
|
|
196
|
+
- **`"heuristics"`** (default) — offline keyword-signal detection (success,
|
|
197
|
+
decision, fact, preference signals), zero LLM cost, works with the embedder
|
|
198
|
+
offline.
|
|
199
|
+
- **`"llm"`** — structured extraction: on `session.idle`, the session buffer is
|
|
200
|
+
sent to the configured LLM (via an ephemeral OpenCode SDK session; tools
|
|
201
|
+
disabled), which returns `[{content, type, importance}]` JSON; each item is
|
|
202
|
+
embedded, dedup-checked, stored, and graph-indexed. Digests become
|
|
203
|
+
LLM-written abstractive summaries (`digestKind: "llm"` in metadata).
|
|
204
|
+
Preference extraction is unaffected (it runs at recall time, offline).
|
|
205
|
+
On any LLM failure the pipeline **falls back to heuristics** and records a
|
|
206
|
+
`llm-fallback` capture event.
|
|
207
|
+
|
|
208
|
+
The LLM is addressed by **OpenCode provider + model IDs** — OpenCode owns
|
|
209
|
+
routing, auth, and base URLs, so no API key or baseUrl lives in the plugin
|
|
210
|
+
config. The provider must be resolvable in your `opencode.json`.
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"capture": {
|
|
215
|
+
"mode": "llm",
|
|
216
|
+
"llm": { "provider": "openrouter", "model": "z-ai/glm-5.3-flash" }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Env: `OPENCODE_MEMORY_PRO_CAPTURE_MODE`,
|
|
222
|
+
`OPENCODE_MEMORY_PRO_CAPTURE_LLM_PROVIDER`,
|
|
223
|
+
`OPENCODE_MEMORY_PRO_CAPTURE_LLM_MODEL`.
|
|
224
|
+
|
|
225
|
+
Capture thresholds: `OPENCODE_MEMORY_PRO_MIN_CAPTURE_CHARS` (default `80`,
|
|
226
|
+
min 30) and `OPENCODE_MEMORY_PRO_MAX_ENTRIES_PER_SCOPE` (default `3000`,
|
|
227
|
+
min 50) bound what gets captured.
|
|
228
|
+
|
|
229
|
+
### Summarize & retention
|
|
230
|
+
|
|
231
|
+
`memory_summarize` builds digests of old memories; `memory_expire` runs the
|
|
232
|
+
retention sweep (digest-then-hide — originals are marked `digested` and hidden
|
|
233
|
+
from recall, **never deleted**).
|
|
234
|
+
|
|
235
|
+
`summarize`:
|
|
236
|
+
|
|
237
|
+
| Key | Default | Description |
|
|
238
|
+
|---|---|---|
|
|
239
|
+
| `summarize.enabled` | `true` | Allow digest creation. |
|
|
240
|
+
| `summarize.minAgeDays` | `30` | Min memory age to be digest-eligible. |
|
|
241
|
+
| `summarize.minGroupSize` | `3` | Smallest group earning a digest. |
|
|
242
|
+
| `summarize.targetChars` | `500` | Digest length. |
|
|
243
|
+
| `summarize.replace` | `false` | Mark originals `digested` after absorbing. |
|
|
244
|
+
|
|
245
|
+
Env: `OPENCODE_MEMORY_PRO_SUMMARIZE_ENABLED`, `..._SUMMARIZE_MIN_AGE_DAYS`,
|
|
246
|
+
`..._SUMMARIZE_MIN_GROUP_SIZE`, `..._SUMMARIZE_TARGET_CHARS`,
|
|
247
|
+
`..._SUMMARIZE_REPLACE`.
|
|
248
|
+
|
|
249
|
+
`retention`:
|
|
250
|
+
|
|
251
|
+
| Key | Default | Description |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| `retention.effectivenessEventsDays` | `90` | TTL for effectiveness events (0 disables; negative → 90). |
|
|
254
|
+
| `retention.memory.enabled` | `true` | Enable the memory-level digest-then-hide sweep. |
|
|
255
|
+
| `retention.memory.unusedDays` | `60` | Unused (not recalled) for this many days → candidate. |
|
|
256
|
+
| `retention.memory.minAgeDays` | `180` | Minimum memory age. |
|
|
257
|
+
| `retention.memory.minGroupSize` | `2` | Smallest per-category group that earns a digest. |
|
|
258
|
+
| `retention.memory.targetChars` | `500` | Digest length. |
|
|
259
|
+
| `retention.memory.minImportance` | `0.3` | Importance floor — protects high-value rows. |
|
|
260
|
+
| `retention.memory.protectedCategories` | `["digest"]` | Categories never expired. |
|
|
261
|
+
|
|
262
|
+
Env: `OPENCODE_MEMORY_PRO_RETENTION_EVENTS_DAYS`,
|
|
263
|
+
`..._RETENTION_MEMORY_ENABLED`, `..._RETENTION_MEMORY_UNUSED_DAYS`,
|
|
264
|
+
`..._RETENTION_MEMORY_MIN_AGE_DAYS`, `..._RETENTION_MEMORY_MIN_GROUP_SIZE`,
|
|
265
|
+
`..._RETENTION_MEMORY_TARGET_CHARS`, `..._RETENTION_MEMORY_MIN_IMPORTANCE`.
|
|
266
|
+
|
|
267
|
+
### Scoping
|
|
268
|
+
|
|
269
|
+
| Key | Default | Description |
|
|
270
|
+
|---|---|---|
|
|
271
|
+
| `scoping` | `"global"` | `"global"` collapses all scopes (single-user mode); `"project"` restores per-project scoping. |
|
|
272
|
+
| `includeGlobalScope` | `true` | Project queries also see global memories. |
|
|
273
|
+
| `globalDetectionThreshold` | `2` | Projects with ≥ N memories become "detected" scopes. |
|
|
274
|
+
| `globalDiscountFactor` | `0.7` | Score discount applied to cross-scope global hits. |
|
|
275
|
+
| `unusedDaysThreshold` | `30` | Threshold for "unused" classification in lifecycle views. |
|
|
276
|
+
|
|
277
|
+
Env: `OPENCODE_MEMORY_PRO_SCOPING`, `..._INCLUDE_GLOBAL_SCOPE`,
|
|
278
|
+
`..._GLOBAL_DETECTION_THRESHOLD`, `..._GLOBAL_DISCOUNT_FACTOR`,
|
|
279
|
+
`..._UNUSED_DAYS_THRESHOLD`.
|
|
280
|
+
|
|
281
|
+
### Logging
|
|
282
|
+
|
|
283
|
+
`logging` controls the plugin's log sink. Logs route to opencode's `/log` bus
|
|
284
|
+
(shows in the TUI); the optional `file` adds a crash-surviving append-only file
|
|
285
|
+
(timestamps, level, message, JSON extras).
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"logging": { "level": "debug", "file": "~/.opencode/memory/opencode-memory-pro.log" }
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
- `level` — `"debug"` | `"info"` (default) | `"warn"` | `"error"`.
|
|
294
|
+
`"debug"` traces index creation, consolidation, compaction, and
|
|
295
|
+
embedder/retrieval internals.
|
|
296
|
+
- `file` — log file path (`~` expanded). Omit or set `null` to keep bus-only.
|
|
297
|
+
|
|
298
|
+
Env: `OPENCODE_MEMORY_PRO_LOG_LEVEL`, `OPENCODE_MEMORY_PRO_LOG_FILE` (applied at
|
|
299
|
+
plugin initialization, before sidecar resolution).
|
|
300
|
+
|
|
301
|
+
### ANN tunables
|
|
302
|
+
|
|
303
|
+
Advanced knobs for the vector-search layer. Defaults are conservative; raise
|
|
304
|
+
`nprobes` if you see recall misses, raise `QUERY_BATCH` if consolidation is
|
|
305
|
+
slow.
|
|
306
|
+
|
|
307
|
+
- `OPENCODE_MEMORY_PRO_NPROBES` — IVF probe count for filtered vector searches
|
|
308
|
+
(recall vs. latency). Default `40`.
|
|
309
|
+
- `OPENCODE_MEMORY_PRO_QUERY_BATCH` — ANN queries per batched vector-search call
|
|
310
|
+
during consolidation. Default `16`.
|
|
311
|
+
|
|
312
|
+
## Tools
|
|
313
|
+
|
|
314
|
+
All tools are auto-registered when the plugin loads. Hybrid recall surfaces
|
|
315
|
+
`.d.ts` type declarations for the IDEs.
|
|
316
|
+
|
|
317
|
+
**Memory core**
|
|
318
|
+
|
|
319
|
+
| Tool | Description |
|
|
320
|
+
|---|---|
|
|
321
|
+
| `memory_search` | Hybrid semantic search using vector + BM25 + graph boost. |
|
|
322
|
+
| `memory_remember` | Explicitly store a memory (with optional category). |
|
|
323
|
+
| `memory_delete` | Remove or disable a memory. |
|
|
324
|
+
| `memory_clear` | Clear all memories in a scope. |
|
|
325
|
+
| `memory_why` | Explain why a specific memory was recalled. |
|
|
326
|
+
| `memory_explain_recall` | Explain the factors behind the last recall. |
|
|
327
|
+
| `memory_citation` | View or update citation info for a memory. |
|
|
328
|
+
| `memory_validate_citation` | Validate a citation and update its status. |
|
|
329
|
+
| `memory_global_list` | List global-scoped memories (with filter). |
|
|
330
|
+
| `memory_stats` | Memory provider status and index health. |
|
|
331
|
+
|
|
332
|
+
**Feedback & effectiveness**
|
|
333
|
+
|
|
334
|
+
| Tool | Description |
|
|
335
|
+
|---|---|
|
|
336
|
+
| `memory_feedback_useful` | Record whether a recalled memory was helpful. |
|
|
337
|
+
| `memory_feedback_wrong` | Record memory that should not have been stored. |
|
|
338
|
+
| `memory_feedback_missing` | Record memory that should have been stored. |
|
|
339
|
+
| `memory_effectiveness` | Effectiveness metrics for capture recall and feedback. |
|
|
340
|
+
| `memory_dashboard` | Weekly learning dashboard with trends and insights. |
|
|
341
|
+
| `memory_kpi` | Learning KPIs (retry-to-success rate, memory lift). |
|
|
342
|
+
| `memory_what_did_you_learn` | Recent learning summary by category. |
|
|
343
|
+
|
|
344
|
+
**Lifecycle**
|
|
345
|
+
|
|
346
|
+
| Tool | Description |
|
|
347
|
+
|---|---|
|
|
348
|
+
| `memory_export` | Backup all memories to JSON. |
|
|
349
|
+
| `memory_import` | Restore memories from an export (merge/replace). |
|
|
350
|
+
| `memory_summarize` | Create digests of old memories. |
|
|
351
|
+
| `memory_expire` | Retention sweep: fold unused memories into digests. |
|
|
352
|
+
| `memory_event_cleanup` | Clean up expired effectiveness events (optional archive). |
|
|
353
|
+
| `memory_consolidate` | Merge near-duplicate memories in a scope. |
|
|
354
|
+
| `memory_consolidate_all` | Global duplicate cleanup (daily cron friendly). |
|
|
355
|
+
|
|
356
|
+
**Scoping**
|
|
357
|
+
|
|
358
|
+
| Tool | Description |
|
|
359
|
+
|---|---|
|
|
360
|
+
| `memory_scope_promote` | Promote a project memory to global scope. |
|
|
361
|
+
| `memory_scope_demote` | Demote a memory from global to project scope. |
|
|
362
|
+
|
|
363
|
+
**Episodic learning**
|
|
364
|
+
|
|
365
|
+
| Tool | Description |
|
|
366
|
+
|---|---|
|
|
367
|
+
| `task_episode_create` | Create a task episode record. |
|
|
368
|
+
| `task_episode_query` | Query task episodes by scope and state. |
|
|
369
|
+
| `similar_task_recall` | Find similar past tasks via semantic search. |
|
|
370
|
+
| `retry_budget_suggest` | Retry budget suggestion from historical data. |
|
|
371
|
+
| `recovery_strategy_suggest` | Recovery strategy suggestions after failures. |
|
|
372
|
+
|
|
373
|
+
**Tooling extras**
|
|
374
|
+
|
|
375
|
+
| Tool | Description |
|
|
376
|
+
|---|---|
|
|
377
|
+
| `memory_port_plan` | Plan non-conflicting host ports for compose services. |
|
|
378
|
+
|
|
379
|
+
Failed sessions additionally record a classified `failureType`
|
|
380
|
+
(`syntax`/`runtime`/`logic`/`resource`/`unknown`) and the raw `errorMessage` on
|
|
381
|
+
their task episode, so `similar_task_recall` / `retry_budget_suggest` /
|
|
382
|
+
`recovery_strategy_suggest` learn from real failures.
|
|
383
|
+
|
|
384
|
+
## Data locations
|
|
385
|
+
|
|
386
|
+
- Memories + events: `~/.opencode/memory/lancedb` (LanceDB) — override with
|
|
387
|
+
`dbPath` / `OPENCODE_MEMORY_PRO_DB_PATH`.
|
|
388
|
+
- Entity graph: `~/.opencode/memory/graph.db` (sqlite) — override with
|
|
389
|
+
`graph.dbPath`.
|
|
390
|
+
- Log file (optional): `~/.opencode/memory/opencode-memory-pro.log`.
|
|
391
|
+
|
|
392
|
+
## Development
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
npm install
|
|
396
|
+
npm test # node --test (unit suite)
|
|
397
|
+
npm run verify # test + pack dry-run
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Migrating from `lancedb-opencode-pro`
|
|
401
|
+
|
|
402
|
+
Clean-break rename: sidecar is `opencode-memory-pro.json`, env prefix is
|
|
403
|
+
`OPENCODE_MEMORY_PRO_*`. Data is **not** affected — the default storage paths
|
|
404
|
+
are unchanged (`~/.opencode/memory/lancedb` + `~/.opencode/memory/graph.db`),
|
|
405
|
+
so your memories and graph carry over untouched.
|
|
406
|
+
|
|
407
|
+
## License
|
|
408
|
+
|
|
409
|
+
MIT — fork of `lancedb-opencode-pro` (MIT, tryweb).
|
package/dist/config.d.ts
ADDED