opencode-codex-memory 0.6.4 → 0.6.5
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/README.md +19 -50
- package/dist/src/index.js +9 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ If you want the mental model before the details, jump to
|
|
|
52
52
|
|
|
53
53
|
```json
|
|
54
54
|
{
|
|
55
|
-
"plugin": ["opencode-codex-memory@0.6.
|
|
55
|
+
"plugin": ["opencode-codex-memory@0.6.5"]
|
|
56
56
|
}
|
|
57
57
|
```
|
|
58
58
|
|
|
@@ -101,51 +101,20 @@ echo 'I prefer TypeScript strict mode and 2-space indentation.' \
|
|
|
101
101
|
|
|
102
102
|
## How it works
|
|
103
103
|
|
|
104
|
-
You don't need to know any of this to use the plugin.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
comes back as structured data — a detailed note plus a short recap of the
|
|
119
|
-
session — and lands in a local SQLite database. One session in, one record out.
|
|
120
|
-
Sessions are independent, so this part is easy to parallelize and to retry when
|
|
121
|
-
it fails.
|
|
122
|
-
|
|
123
|
-
**Phase 2 — merge all those notes into one memory.** Every few hours at most
|
|
124
|
-
(and only one run at a time across all your OpenCode windows), a second pass
|
|
125
|
-
takes the most relevant per-session notes and rewrites the actual memory files:
|
|
126
|
-
`MEMORY.md` as the full index, `memory_summary.md` as the short version, and
|
|
127
|
-
`skills/` for procedures worth repeating. This is where the interesting work
|
|
128
|
-
happens — ten similar observations collapse into one rule, contradictions get
|
|
129
|
-
resolved, and notes nothing ever used age out. Forgetting is a feature: memory
|
|
130
|
-
that only grows is memory that stops being useful.
|
|
131
|
-
|
|
132
|
-
The split exists because the two halves have opposite needs. Phase 1 is
|
|
133
|
-
per-session and can run many at once; phase 2 touches the single shared memory,
|
|
134
|
-
so it has to be serialized. Keeping them apart means one slow or failing session
|
|
135
|
-
extraction can't corrupt or block the shared store.
|
|
136
|
-
|
|
137
|
-
**The read path — actually remembering.** Every turn, the short summary is
|
|
138
|
-
appended to the system prompt (capped at ~2500 tokens, so the cost is small and
|
|
139
|
-
predictable). That's the always-on layer. When a task looks related to past
|
|
140
|
-
work, the agent goes further and searches the full memory itself with the
|
|
141
|
-
`memory_*` tools — the equivalent of "I've seen this before, let me look it up"
|
|
142
|
-
rather than carrying everything around all the time.
|
|
143
|
-
|
|
144
|
-
**The feedback loop.** When the agent uses a memory, it cites it. The citation
|
|
145
|
-
is recorded and then stripped before it reaches your screen, and those usage
|
|
146
|
-
counts feed back into phase 2's ranking. Memories that keep proving useful get
|
|
147
|
-
kept and sharpened; memories nothing has touched in a month drop out. The system
|
|
148
|
-
finds out which of its own notes were worth writing.
|
|
104
|
+
You don't need to know any of this to use the plugin. In short: two background
|
|
105
|
+
writers and one reader. Once a session has been idle long enough (default 6 h),
|
|
106
|
+
a cheap model reviews its transcript and writes a structured note (**phase 1 —
|
|
107
|
+
extraction**). Every few hours, a stronger model merges those notes into the
|
|
108
|
+
actual memory files — the index, the short summary, reusable skills — resolving
|
|
109
|
+
duplicates and dropping what went stale (**phase 2 — consolidation**). On every
|
|
110
|
+
turn, the short summary goes into the system prompt, and the agent searches
|
|
111
|
+
deeper layers itself when a task looks familiar (**read path**). When the agent
|
|
112
|
+
uses a memory it cites it; those citations feed consolidation's ranking, so
|
|
113
|
+
useful memories survive and unused ones age out.
|
|
114
|
+
|
|
115
|
+
For the full architecture — learning, remembering, forgetting, and the
|
|
116
|
+
trade-offs behind each — see
|
|
117
|
+
[How OpenCode Codex Memory works](./docs/how-ai-memory-works.md).
|
|
149
118
|
|
|
150
119
|
## Where your data lives
|
|
151
120
|
|
|
@@ -232,7 +201,7 @@ To set options, turn the plugin entry into a `[name, options]` pair:
|
|
|
232
201
|
```json
|
|
233
202
|
{
|
|
234
203
|
"plugin": [
|
|
235
|
-
["opencode-codex-memory@0.6.
|
|
204
|
+
["opencode-codex-memory@0.6.5", { "disable_on_external_context": true, "min_rollout_idle_hours": 2 }]
|
|
236
205
|
]
|
|
237
206
|
}
|
|
238
207
|
```
|
|
@@ -299,7 +268,7 @@ Off by default; no changes to Codex's own config are required.
|
|
|
299
268
|
{
|
|
300
269
|
"plugin": [
|
|
301
270
|
[
|
|
302
|
-
"opencode-codex-memory@0.6.
|
|
271
|
+
"opencode-codex-memory@0.6.5",
|
|
303
272
|
{ "codex_interop": { "import": true, "export": true } }
|
|
304
273
|
]
|
|
305
274
|
]
|
|
@@ -356,7 +325,7 @@ from the project memories Claude already keeps on your machine. **One-way only**
|
|
|
356
325
|
```json
|
|
357
326
|
{
|
|
358
327
|
"plugin": [
|
|
359
|
-
["opencode-codex-memory@0.6.
|
|
328
|
+
["opencode-codex-memory@0.6.5", { "claude_import": { "enabled": true } }]
|
|
360
329
|
]
|
|
361
330
|
}
|
|
362
331
|
```
|
|
@@ -383,7 +352,7 @@ Claude names each project with an opaque id (a folder under
|
|
|
383
352
|
{
|
|
384
353
|
"plugin": [
|
|
385
354
|
[
|
|
386
|
-
"opencode-codex-memory@0.6.
|
|
355
|
+
"opencode-codex-memory@0.6.5",
|
|
387
356
|
{
|
|
388
357
|
"claude_import": {
|
|
389
358
|
"enabled": true,
|
package/dist/src/index.js
CHANGED
|
@@ -326,6 +326,10 @@ async function classifyExternalContextTool(toolName) {
|
|
|
326
326
|
}
|
|
327
327
|
return false;
|
|
328
328
|
}
|
|
329
|
+
const TITLE_GENERATOR_MARKER = "You are a title generator. You output ONLY a thread title.";
|
|
330
|
+
function isTitleGenerationPrompt(system) {
|
|
331
|
+
return system.some((block) => block.includes(TITLE_GENERATOR_MARKER));
|
|
332
|
+
}
|
|
329
333
|
/**
|
|
330
334
|
* Registers the memorize / memorize-extract sub-agents through the config
|
|
331
335
|
* hook so installing the plugin requires no manual agent setup. Definitions
|
|
@@ -383,9 +387,13 @@ function buildHooks() {
|
|
|
383
387
|
if (!pluginOptions.use_memories)
|
|
384
388
|
return;
|
|
385
389
|
// OpenCode also invokes this hook while generating agent definitions,
|
|
386
|
-
// without a session
|
|
390
|
+
// without a session, and while naming a session (hidden `title` agent,
|
|
391
|
+
// same sessionID; hook has no agent field). Memory belongs only in
|
|
392
|
+
// real conversation prompts.
|
|
387
393
|
if (!input.sessionID || isMemorySubSession(input.sessionID))
|
|
388
394
|
return;
|
|
395
|
+
if (isTitleGenerationPrompt(output.system))
|
|
396
|
+
return;
|
|
389
397
|
ensureMemoryLayout();
|
|
390
398
|
const memoryPrompt = buildMemorySystemPrompt(pluginOptions.dedicated_tools);
|
|
391
399
|
if (memoryPrompt) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-codex-memory",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Persistent memory plugin for opencode — ports codex's two-phase memory system (extraction → consolidation → injection → citation feedback)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|