dsh-auto-memory 0.1.0 → 0.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/README.md +148 -82
- package/README.zh.md +123 -74
- package/lib/index.d.ts +7 -1
- package/lib/index.js +619 -30
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -1,130 +1,196 @@
|
|
|
1
1
|
# dsh-auto-memory
|
|
2
2
|
|
|
3
|
+
[](https://github.com/AskTheWay/dsh-auto-memory/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-auto-memory)
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-auto-memory)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](package.json)
|
|
8
|
+
|
|
3
9
|
[English](README.md) | [中文](README.zh.md)
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
> ### Your dsh agent forgets everything you tell it. Every. Single. Session.
|
|
12
|
+
> **Fix it with one command.** Claude Code-style persistent memory for
|
|
13
|
+
> [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — native,
|
|
14
|
+
> zero servers, zero embeddings, zero setup.
|
|
6
15
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
```sh
|
|
17
|
+
dsh plugin --profile demo add dsh-auto-memory
|
|
18
|
+
```
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
Say *"Remember: I'm a Python backend engineer preparing for interviews"* today —
|
|
21
|
+
open a brand-new session tomorrow, ask *"what do you know about me?"*, and it
|
|
22
|
+
**remembers**.
|
|
12
23
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## What's new in 0.3.0 (P2)
|
|
27
|
+
|
|
28
|
+
- **Pinned memories** (`pinned: true` on memory_write): pinned entries lead
|
|
29
|
+
the index, survive budget truncation, and are exempt from staleness
|
|
30
|
+
eviction — a trust anchor the user controls.
|
|
31
|
+
- **Eval-driven fix**: the injection budget now covers the *whole* section
|
|
32
|
+
(index + guidance); it used to overshoot by ~800 bytes. Caught by the new
|
|
33
|
+
deterministic evaluation layer on its first run.
|
|
34
|
+
- **Deterministic eval layer** ([evals/](evals/README.md)) in CI: injection
|
|
35
|
+
budget curves, eviction zero-misfire, link-expansion bounds, and a
|
|
36
|
+
signal-to-noise characterization — which pinned-priority truncation then
|
|
37
|
+
improved from **38% → ≥80% probe retention** under half-budget pressure.
|
|
38
|
+
Same budget, better memories.
|
|
39
|
+
|
|
40
|
+
## What's new in 0.2.0 (P1)
|
|
41
|
+
|
|
42
|
+
- **Auto-consolidation** (`autoSummarize: true`): when a root session ends, a
|
|
43
|
+
background LLM pass extracts durable new facts from the session and files
|
|
44
|
+
them as memories — deduplicated, capped, fully silent on failure. Claude
|
|
45
|
+
Code doesn't do this automatically.
|
|
46
|
+
- **Forgetting & eviction**: every memory carries lifecycle metadata
|
|
47
|
+
(created/updated/reads); `memory_read` counts references; `staleAfterDays`
|
|
48
|
+
soft-hides zero-reference stale memories from the injected index (files
|
|
49
|
+
kept); `memory_prune` lists (dry-run) or deletes aged memories.
|
|
50
|
+
- **Recall expansion**: `memory_read` resolves `[[name]]` cross-links one
|
|
51
|
+
level and attaches linked summaries.
|
|
52
|
+
- `memory_delete_all` — guarded by `tools/pre-execute` **human approval**:
|
|
53
|
+
the model cannot self-confirm irreversible bulk deletes.
|
|
54
|
+
- Hardened by a second adversarial review (11 agents): single-lock `clear`
|
|
55
|
+
(no concurrent-write escape), conditional index rebuild on `touch`
|
|
56
|
+
(no O(N) amplification), session-start stale refresh, subagent capture
|
|
57
|
+
cleanup, abortable consolidation.
|
|
58
|
+
|
|
59
|
+
Tools: `memory_write` / `memory_read` / `memory_list` / `memory_delete` /
|
|
60
|
+
`memory_prune` / `memory_delete_all`.
|
|
61
|
+
|
|
62
|
+
## Claude Code has this. dsh didn't. Now it does.
|
|
63
|
+
|
|
64
|
+
DeepSeek Harness is the hottest open agent harness on GitHub right now —
|
|
65
|
+
models, tools, sandboxes, everything is a plugin. But it ships with **no memory
|
|
66
|
+
subsystem at all**. The official answer is three *default-off* MCP configs to
|
|
67
|
+
third-party servers, which the official docs themselves qualify: not
|
|
68
|
+
auto-injected, no forgetting policy, substring-only search. Your agent has
|
|
69
|
+
amnesia by design.
|
|
18
70
|
|
|
19
71
|
`dsh-auto-memory` closes that gap natively:
|
|
20
72
|
|
|
21
|
-
|
|
|
73
|
+
| | MCP bridge approach | **dsh-auto-memory** |
|
|
22
74
|
|---|---|---|
|
|
23
|
-
|
|
|
24
|
-
| Typed memories
|
|
25
|
-
| Workspace
|
|
26
|
-
| Crash
|
|
27
|
-
|
|
|
28
|
-
| Auto-consolidation on session end (P1) | ✗ | planned |
|
|
75
|
+
| Memories injected into **every** system prompt, automatically | ✗ | ✓ (zero tokens when empty) |
|
|
76
|
+
| Typed memories: user / feedback / project / reference | ✗ | ✓ |
|
|
77
|
+
| Workspace + user scope layers — no cross-project leakage | ✗ | ✓ |
|
|
78
|
+
| Crash & concurrency safety (cross-process locks, orphan recovery) | — | ✓ |
|
|
79
|
+
| External services / databases / embeddings required | ✓✓✓ | **none — just plain Markdown files** |
|
|
29
80
|
|
|
30
|
-
|
|
81
|
+
Memories are ordinary files under `$DSH_HOME/memory/` — hand-editable,
|
|
82
|
+
grep-able, git-friendly, yours.
|
|
31
83
|
|
|
32
|
-
|
|
84
|
+
## One minute to feel it
|
|
33
85
|
|
|
34
86
|
```sh
|
|
35
|
-
|
|
36
|
-
dsh plugin --profile demo add /absolute/path/to/dsh-auto-memory
|
|
37
|
-
dsh --profile demo # restart the profile to activate
|
|
87
|
+
node scripts/demo.mjs # no API key, no browser: watch write → index → inject → recall → forget
|
|
38
88
|
```
|
|
39
89
|
|
|
40
|
-
|
|
90
|
+
Or for real, in a chat: tell your agent things worth remembering. The model
|
|
91
|
+
calls `memory_write` / `memory_read` / `memory_list` / `memory_delete`,
|
|
92
|
+
following Claude Code's write discipline: **dedupe-and-update over piling up**,
|
|
93
|
+
absolute dates only, `[[name]]` cross-links, `feedback` memories carry
|
|
94
|
+
**Why:** / **How to apply:** lines.
|
|
41
95
|
|
|
42
|
-
|
|
96
|
+
## What the model actually sees
|
|
43
97
|
|
|
44
|
-
|
|
98
|
+
Every request, one system-prompt section (order 4000) carries the index —
|
|
99
|
+
re-evaluated per step, byte-budgeted, and **gone entirely when the store is
|
|
100
|
+
empty**:
|
|
45
101
|
|
|
46
|
-
|
|
102
|
+
```
|
|
103
|
+
# Persistent memory index
|
|
104
|
+
## Project memories
|
|
105
|
+
- [压测过 PostgreSQL](id-generator-benchmark.md) — psycopg2 连接池有踩坑经验 (2026-09)
|
|
106
|
+
- [用户是 Python 后端工程师](user-prefers-python.md) — 正在准备面试; 偏好中文交流
|
|
107
|
+
```
|
|
47
108
|
|
|
48
|
-
|
|
109
|
+
Chinese titles, YAML frontmatter, one file per memory — exactly the Claude
|
|
110
|
+
Code `MEMORY.md` model, rebuilt natively on dsh's prompt-assembly pipeline.
|
|
49
111
|
|
|
50
|
-
|
|
51
|
-
index is already there — ask *"what do you know about me?"* and it recalls.
|
|
112
|
+
## Hardened before first release
|
|
52
113
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
cross-link with `[[name]]`.
|
|
114
|
+
This plugin survived a **12-agent adversarial code review** (680k tokens of
|
|
115
|
+
source-level scrutiny) before v0.1.0. Five production-grade traps were caught
|
|
116
|
+
and fixed — with regression tests — including two that would have been
|
|
117
|
+
field incidents:
|
|
58
118
|
|
|
59
|
-
|
|
119
|
+
- **The NTFS silent destroyer**: a memory named `memory` collides with
|
|
120
|
+
`MEMORY.md` on case-insensitive filesystems — the write *succeeds* while
|
|
121
|
+
destroying the record. Blocked by a reserved-name guard.
|
|
122
|
+
- **The poisoned-prompt bomb**: three literal `{{{ }}}` braces in any memory
|
|
123
|
+
could crash *every* model request in the workspace — with no way for the
|
|
124
|
+
model to self-recover. Neutralized by a converging sanitizer.
|
|
60
125
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
│ └── one-file-per-memory.md # frontmatter + body
|
|
66
|
-
└── _user/ # user layer (shared across all workspaces)
|
|
67
|
-
```
|
|
126
|
+
Plus: orphaned-lock self-healing (Ctrl+C can't brick your memory store),
|
|
127
|
+
symlink-read protection, malformed-file tolerance, stable index ordering to
|
|
128
|
+
protect KV-prefix caches, and a strict no-custom-session-events policy (they
|
|
129
|
+
make dsh sessions refuse to resume).
|
|
68
130
|
|
|
69
|
-
|
|
131
|
+
## Measured, not just claimed
|
|
70
132
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
name: user-prefers-python
|
|
74
|
-
title: Backend engineer, prefers Python
|
|
75
|
-
description: Preparing for interviews; prefers Chinese
|
|
76
|
-
type: user
|
|
77
|
-
---
|
|
133
|
+
A deterministic evaluation layer ([evals/](evals/README.md)) runs in CI —
|
|
134
|
+
no LLM, fully reproducible:
|
|
78
135
|
|
|
79
|
-
|
|
80
|
-
|
|
136
|
+
- **Injection budget holds at any scale**: 20/50/100/200 memories → the
|
|
137
|
+
injected section stays ≤ 4 KB (4065/4048/4018/3940 bytes measured), with
|
|
138
|
+
truncation markers; empty store injects **0 bytes**.
|
|
139
|
+
- **Eviction never misfires**: four-class mixed scenario — only
|
|
140
|
+
stale-zero-read memories get hidden; zero files lost; one read revives.
|
|
141
|
+
- **Known limitation, pinned as baseline**: budget truncation is currently
|
|
142
|
+
positional (index order), not relevance-ranked — probe retention under
|
|
143
|
+
half-budget pressure drops to ~38%→10% as N grows. **Pinning fixes it for
|
|
144
|
+
what matters**: pinned probes retain **≥80%** at the same budget (0.3.0);
|
|
145
|
+
full relevance ranking remains on the roadmap.
|
|
146
|
+
|
|
147
|
+
This evaluation layer already caught a real bug: the byte budget used to
|
|
148
|
+
exclude the policy text, overshooting by ~800 bytes (fixed, regression-tested).
|
|
81
149
|
|
|
82
|
-
|
|
150
|
+
**78 tests (incl. a deterministic eval layer). 0 runtime deps beyond `yaml`. 15 kB installed.**
|
|
83
151
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
sessions fail to resume); everything flows through standard `tool/call` /
|
|
94
|
-
`tool/result`.
|
|
152
|
+
## Install
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
dsh plugin --profile demo add dsh-auto-memory # from npm (prebuilt)
|
|
156
|
+
dsh --profile demo # restart the profile
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
From source: `npm install && npm run build && dsh plugin --profile demo add /abs/path`.
|
|
160
|
+
Requires `@deepseek-ai/dsh >= 0.1.5-rc.2` (Node `^22.19 || >=24`).
|
|
95
161
|
|
|
96
162
|
## Configuration
|
|
97
163
|
|
|
98
|
-
Override
|
|
99
|
-
restate every key):
|
|
164
|
+
Override in your profile's `cordis.patch.yml` (config replaces wholesale):
|
|
100
165
|
|
|
101
166
|
```yaml
|
|
102
167
|
- id: auto-memory
|
|
103
168
|
config:
|
|
104
|
-
maxBytes: 4096 # injection budget
|
|
169
|
+
maxBytes: 4096 # injection budget
|
|
105
170
|
memoryDir: D:/memories # default: $DSH_HOME/memory
|
|
106
171
|
enableUserScope: true # false: user layer off on every path
|
|
107
|
-
autoSummarize: false # P1 placeholder
|
|
108
172
|
```
|
|
109
173
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
- [docs/design.md](docs/design.md) — design decisions and trade-offs
|
|
113
|
-
- [docs/api-reports.md](docs/api-reports.md) — dsh source-level API research
|
|
114
|
-
backing every implementation choice (including the traps this plugin avoids)
|
|
174
|
+
## How it works (60 seconds)
|
|
115
175
|
|
|
116
|
-
|
|
176
|
+
- **Write**: tool `execute` → name normalized to `[a-z0-9-]` (reserved names
|
|
177
|
+
rejected) → cross-process file lock (official `dsh-atomic-write`) → atomic
|
|
178
|
+
write → full index rebuild inside the lock.
|
|
179
|
+
- **Inject**: one dynamic section re-evaluated on every step assembly; reads
|
|
180
|
+
the index synchronously, enforces the byte budget, neutralizes `{{`.
|
|
181
|
+
Tool writes take effect on the **very next request** — no restart, ever.
|
|
182
|
+
- **Audit**: no custom session events (third-party types make dsh refuse to
|
|
183
|
+
resume); everything flows through standard `tool/call` / `tool/result`.
|
|
117
184
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
185
|
+
Deep dives: [design decisions](docs/design.md) ·
|
|
186
|
+
[dsh source-level research](docs/api-reports.md) ·
|
|
187
|
+
[postmortem: shipping a PR to awesome-dsh-plugin](docs/postmortem-pr-5696.md)
|
|
121
188
|
|
|
122
|
-
##
|
|
189
|
+
## Roadmap
|
|
123
190
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```
|
|
191
|
+
- [x] P0 — typed store, four tools, prompt injection, scoped layers, crash safety
|
|
192
|
+
- [x] P1 — auto-consolidation on session end, forgetting & eviction, recall expansion, human-gated bulk delete
|
|
193
|
+
- [ ] P2 — Web UI memory cards, token-cost / recall-quality benchmarks
|
|
128
194
|
|
|
129
195
|
## License
|
|
130
196
|
|
package/README.zh.md
CHANGED
|
@@ -1,121 +1,170 @@
|
|
|
1
1
|
# dsh-auto-memory
|
|
2
2
|
|
|
3
|
+
[](https://github.com/AskTheWay/dsh-auto-memory/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-auto-memory)
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-auto-memory)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](package.json)
|
|
8
|
+
|
|
3
9
|
[English](README.md) | [中文](README.zh.md)
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
> ### 你的 dsh 智能体把你说过的每件事都忘掉。每一次。每一个会话。
|
|
12
|
+
> **一条命令修复。** 把 Claude Code 式持久记忆带给
|
|
13
|
+
> [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)——原生实现,
|
|
14
|
+
> 零服务器、零 embedding、零配置。
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
dsh plugin --profile demo add dsh-auto-memory
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
今天对它说 *"记住:我是准备面试的 Python 后端工程师"*——
|
|
21
|
+
明天开一个全新会话,问 *"你对我有什么了解?"*,它**记得**。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 0.3.0 新增(P2)
|
|
26
|
+
|
|
27
|
+
- **置顶记忆**(memory_write 传 `pinned: true`):置顶条目排在索引最前、
|
|
28
|
+
在预算截断中优先保留、豁免软淘汰——用户可控的信任锚点。
|
|
29
|
+
- **评测驱动修复**:注入预算语义改为覆盖整段(索引+指导文本);旧实现会
|
|
30
|
+
超支 ~800 字节——由新评测层首跑即抓出。
|
|
31
|
+
- **确定性评测层**([evals/](evals/README.md))进 CI:注入预算曲线、淘汰
|
|
32
|
+
零误杀、链接展开边界、信噪比 characterization——pinned 优先截断把
|
|
33
|
+
半量预算下的探针保留率从 **38% 提升到 ≥80%**。同样的预算,更对的记忆。
|
|
6
34
|
|
|
7
|
-
|
|
8
|
-
`MEMORY.md` 索引、四个模型工具——轻量、纯文件、无外部服务、无 embedding 依赖。
|
|
35
|
+
## 0.2.0 新增(P1)
|
|
9
36
|
|
|
10
|
-
|
|
37
|
+
- **自动固化**(`autoSummarize: true`):根会话结束时,后台 LLM 从会话中提取
|
|
38
|
+
值得长期保留的新事实并写入记忆——查重、限量、失败静默。Claude Code 没有全自动。
|
|
39
|
+
- **遗忘与淘汰**:每条记忆携带生命周期元数据(created/updated/reads);
|
|
40
|
+
`memory_read` 累计引用;`staleAfterDays` 把零引用超龄记忆从注入索引软隐藏
|
|
41
|
+
(文件保留);`memory_prune` 列出(dry-run)或删除高龄记忆。
|
|
42
|
+
- **召回展开**:`memory_read` 解析一层 `[[name]]` 交叉链接并附摘要。
|
|
43
|
+
- `memory_delete_all`——由 `tools/pre-execute` **人工审批**把关:
|
|
44
|
+
模型无法自证通过不可逆批量删除。
|
|
45
|
+
- 经第二轮对抗审查(11 个智能体)加固:clear 单锁窗口(并发写不逃逸)、
|
|
46
|
+
touch 条件重建(消除 O(N) 放大)、会话启动刷新软淘汰、子代理缓冲清理、
|
|
47
|
+
固化可中止。
|
|
11
48
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
(模型必须主动调工具)、无自动摘要、无冲突消解、无遗忘策略。
|
|
49
|
+
工具:`memory_write` / `memory_read` / `memory_list` / `memory_delete` /
|
|
50
|
+
`memory_prune` / `memory_delete_all`。
|
|
15
51
|
|
|
16
|
-
|
|
52
|
+
## Claude Code 有的东西,dsh 一直没有。现在有了。
|
|
17
53
|
|
|
18
|
-
|
|
54
|
+
DeepSeek Harness 是当下 GitHub 最火的开源智能体框架——模型、工具、沙箱,万物皆插件。
|
|
55
|
+
但它**根本没有记忆子系统**。官方的答案是三份*默认关闭*的 MCP 外挂配置,而且官方文档
|
|
56
|
+
自己承认局限:不自动注入、无遗忘策略、只做子串搜索。你的智能体是**设计层面的失忆症**。
|
|
57
|
+
|
|
58
|
+
`dsh-auto-memory` 用原生实现补上这个缺口:
|
|
59
|
+
|
|
60
|
+
| | MCP 外挂方案 | **dsh-auto-memory** |
|
|
19
61
|
|---|---|---|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
| 会话结束自动固化(P1) | ✗ | 计划中 |
|
|
62
|
+
| 记忆自动注入**每一次**系统提示词 | ✗ | ✓(无记忆时零 token 占用) |
|
|
63
|
+
| 类型化记忆:user / feedback / project / reference | ✗ | ✓ |
|
|
64
|
+
| 工作区 + 用户双层作用域——跨项目不串扰 | ✗ | ✓ |
|
|
65
|
+
| 崩溃与并发安全(跨进程锁、孤儿锁自愈) | — | ✓ |
|
|
66
|
+
| 需要外部服务 / 数据库 / embedding | ✓✓✓ | **全都不用——纯 Markdown 文件** |
|
|
26
67
|
|
|
27
|
-
|
|
68
|
+
记忆是 `$DSH_HOME/memory/` 下的普通文件——可手改、可 grep、对 git 友好,完全属于你。
|
|
28
69
|
|
|
29
|
-
|
|
70
|
+
## 一分钟感受它
|
|
30
71
|
|
|
31
72
|
```sh
|
|
32
|
-
|
|
33
|
-
dsh plugin --profile demo add /绝对路径/dsh-auto-memory
|
|
34
|
-
dsh --profile demo # 重启 profile 生效
|
|
73
|
+
node scripts/demo.mjs # 不要 API key、不开浏览器:看 写入 → 索引 → 注入 → 召回 → 遗忘
|
|
35
74
|
```
|
|
36
75
|
|
|
37
|
-
|
|
76
|
+
或者在真实对话里:告诉智能体值得记住的事。模型调用
|
|
77
|
+
`memory_write` / `memory_read` / `memory_list` / `memory_delete`,
|
|
78
|
+
遵循 Claude Code 的写入纪律:**查重更新而非堆积**、只用绝对日期、
|
|
79
|
+
`[[name]]` 交叉链接、`feedback` 记忆附 **Why:** / **How to apply:** 行。
|
|
38
80
|
|
|
39
|
-
|
|
81
|
+
## 模型实际看到什么
|
|
40
82
|
|
|
41
|
-
|
|
83
|
+
每个请求,一个系统提示词段(order 4000)携带索引——每步重新求值、字节预算控制、
|
|
84
|
+
存储为空时**整段消失**:
|
|
42
85
|
|
|
43
|
-
|
|
86
|
+
```
|
|
87
|
+
# Persistent memory index
|
|
88
|
+
## Project memories
|
|
89
|
+
- [压测过 PostgreSQL](id-generator-benchmark.md) — psycopg2 连接池有踩坑经验 (2026-09)
|
|
90
|
+
- [用户是 Python 后端工程师](user-prefers-python.md) — 正在准备面试; 偏好中文交流
|
|
91
|
+
```
|
|
44
92
|
|
|
45
|
-
|
|
93
|
+
中文标题、YAML frontmatter、一条记忆一个文件——完整的 Claude Code `MEMORY.md`
|
|
94
|
+
模型,在 dsh 的提示词组装管线上原生重建。
|
|
46
95
|
|
|
47
|
-
|
|
48
|
-
问 *"你对我有什么了解?"* 它就能召回。
|
|
96
|
+
## 首发之前就被锤炼过
|
|
49
97
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
98
|
+
这个插件在 v0.1.0 发布前经受了一次 **12 个智能体的对抗性代码审查**
|
|
99
|
+
(68 万 token 的源码级拷问)。五个生产级陷阱被抓出并修复——全部带回归测试——
|
|
100
|
+
其中两个若上线就是事故:
|
|
53
101
|
|
|
54
|
-
|
|
102
|
+
- **NTFS 静默毁数据**:名为 `memory` 的记忆会在大小写不敏感文件系统上撞上
|
|
103
|
+
`MEMORY.md`——写入*报告成功*,实际销毁记录。保留字守卫拦截。
|
|
104
|
+
- **毒提示炸弹**:任何记忆里三个字面 `{{{ }}}` 花括号,就能炸掉工作区的
|
|
105
|
+
*每一个*模型请求——且模型无法自救。收敛式消毒器中和。
|
|
55
106
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
│ ├── MEMORY.md # 索引(唯一被注入的部分)
|
|
60
|
-
│ └── 每条记忆一个.md # frontmatter + 正文
|
|
61
|
-
└── _user/ # 用户层(所有工作区共享)
|
|
62
|
-
```
|
|
107
|
+
还有:孤儿锁自愈(Ctrl+C 砸不坏你的记忆库)、symlink 读取防护、坏文件容错、
|
|
108
|
+
稳定的索引排序(保住 KV 前缀缓存)、严格不写自定义会话事件(那会让 dsh 会话
|
|
109
|
+
拒绝 resume)。
|
|
63
110
|
|
|
64
|
-
|
|
111
|
+
## 用数字说话,不止口头宣称
|
|
65
112
|
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
name: user-prefers-python
|
|
69
|
-
title: 后端工程师,偏好 Python
|
|
70
|
-
description: 正在准备面试;偏好中文交流
|
|
71
|
-
type: user
|
|
72
|
-
---
|
|
113
|
+
确定性评测层([evals/](evals/README.md))随 CI 运行——无 LLM、结果完全可复现:
|
|
73
114
|
|
|
74
|
-
|
|
75
|
-
|
|
115
|
+
- **注入预算任意规模下成立**:20/50/100/200 条记忆,注入段恒 ≤ 4 KB
|
|
116
|
+
(实测 4065/4048/4018/3940 字节)且带截断标记;空库注入 **0 字节**。
|
|
117
|
+
- **淘汰零误杀**:四类混合场景——只有"超龄零引用"被隐藏,文件零丢失,
|
|
118
|
+
读一次即复活。
|
|
119
|
+
- **已知局限(有意钉板)**:预算截断目前按索引行序(位置式)而非相关性排序——
|
|
120
|
+
半量预算压力下探针保留率随规模降至 ~38%→10%。**置顶可解关键项**:同预算下
|
|
121
|
+
pinned 探针保留 **≥80%**(0.3.0);完整相关性排序仍在路线图。
|
|
76
122
|
|
|
77
|
-
|
|
123
|
+
评测层已抓到过真实 bug:字节预算曾遗漏指导文本、整段超支 ~800 字节
|
|
124
|
+
(已修复并带回归)。
|
|
78
125
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
126
|
+
**78 项测试(含确定性评测层)。运行时依赖仅 `yaml`。安装体积 15 kB。**
|
|
127
|
+
|
|
128
|
+
## 安装
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
dsh plugin --profile demo add dsh-auto-memory # npm 直装(预构建)
|
|
132
|
+
dsh --profile demo # 重启 profile 生效
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
源码安装:`npm install && npm run build && dsh plugin --profile demo add /绝对路径`。
|
|
136
|
+
要求 `@deepseek-ai/dsh >= 0.1.5-rc.2`(Node `^22.19 || >=24`)。
|
|
87
137
|
|
|
88
138
|
## 配置
|
|
89
139
|
|
|
90
|
-
在 profile 的 `cordis.patch.yml` 覆盖(config
|
|
140
|
+
在 profile 的 `cordis.patch.yml` 覆盖(config 整表替换):
|
|
91
141
|
|
|
92
142
|
```yaml
|
|
93
143
|
- id: auto-memory
|
|
94
144
|
config:
|
|
95
|
-
maxBytes: 4096 # 注入预算
|
|
145
|
+
maxBytes: 4096 # 注入预算
|
|
96
146
|
memoryDir: D:/memories # 默认: $DSH_HOME/memory
|
|
97
147
|
enableUserScope: true # false: 用户层在所有路径禁用
|
|
98
|
-
autoSummarize: false # P1 占位
|
|
99
148
|
```
|
|
100
149
|
|
|
101
|
-
##
|
|
150
|
+
## 工作原理(60 秒)
|
|
102
151
|
|
|
103
|
-
- [
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
152
|
+
- **写入**:工具 `execute` → name 归一化为 `[a-z0-9-]`(保留字拒绝)→
|
|
153
|
+
跨进程文件锁(官方 `dsh-atomic-write`)→ 原子写 → 锁内全量重建索引。
|
|
154
|
+
- **注入**:单个动态段,每步组装重新求值;同步读索引、执行字节预算、中和 `{{`。
|
|
155
|
+
工具写入在**下一个请求**即生效——永远不需要重启。
|
|
156
|
+
- **审计**:不写自定义会话事件(第三方事件类型会让 dsh 拒绝 resume);
|
|
157
|
+
一切走标准 `tool/call` / `tool/result`。
|
|
108
158
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
-
|
|
159
|
+
深度内容:[设计决策](docs/design.md) ·
|
|
160
|
+
[dsh 源码级调研](docs/api-reports.md) ·
|
|
161
|
+
[复盘:向 awesome-dsh-plugin 提 PR](docs/postmortem-pr-5696.md)
|
|
112
162
|
|
|
113
|
-
##
|
|
163
|
+
## 路线图
|
|
114
164
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
```
|
|
165
|
+
- [x] P0——类型化存储、四工具、提示词注入、分层作用域、崩溃安全
|
|
166
|
+
- [x] P1——会话结束自动固化、遗忘与淘汰、召回展开、人工审批的批量删除
|
|
167
|
+
- [ ] P2——Web UI 记忆卡片、token 成本/召回质量评测
|
|
119
168
|
|
|
120
169
|
## 许可
|
|
121
170
|
|
package/lib/index.d.ts
CHANGED
|
@@ -11,8 +11,14 @@ interface Config {
|
|
|
11
11
|
memoryDir?: string;
|
|
12
12
|
/** 是否启用用户级作用域(_user 目录注入所有会话)。 */
|
|
13
13
|
enableUserScope: boolean;
|
|
14
|
-
/** P1
|
|
14
|
+
/** P1:会话结束自动总结固化(需要可用模型路由;失败静默不影响会话)。 */
|
|
15
15
|
autoSummarize: boolean;
|
|
16
|
+
/** 单次固化最多写入的新记忆数。 */
|
|
17
|
+
autoSummarizeMaxMemories: number;
|
|
18
|
+
/** 固化模型调用的输出 token 上限。 */
|
|
19
|
+
autoSummarizeMaxTokens: number;
|
|
20
|
+
/** P1:软淘汰阈值(天)——超过且从未被读取的记忆在索引重建时从注入索引隐藏(文件保留)。0 禁用。 */
|
|
21
|
+
staleAfterDays: number;
|
|
16
22
|
}
|
|
17
23
|
declare const Config: z<Config>;
|
|
18
24
|
declare function apply(ctx: Context, config: Config): void;
|