dsh-memory-fast 0.1.16 → 0.1.17
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 +69 -154
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,151 +1,74 @@
|
|
|
1
1
|
# dsh-memory-fast
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/dsh-memory-fast)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-memory-fast)
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-memory-fast)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> AGENTS.md-based long-term memory plugin for DeepSeek Harness (DSH) — hot/cold layered memory across sessions and workspaces, with a built-in `memory_search` retrieval tool. Zero storage layer.
|
|
8
|
+
>
|
|
9
|
+
> 为 DeepSeek Harness (DSH) 提供基于 `AGENTS.md` 加载链的跨会话长期记忆:全局 + 工作区两级热层、冷层归档、休眠机制,并内置 `memory_search` 检索工具。零存储层、零第三方依赖。
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
- 🛠 **写入零自定义工具**——agent 直接用系统 `read` / `write` / `edit` 工具维护记忆文件,不破坏 touch 热更新监听。
|
|
9
|
-
- 🔍 **`memory_search` 检索(0.1.16+)**——插件注册一个只读检索工具,对全局与各工作区记忆文件(热层+冷层)做关键字/正则搜索,休眠态同样可用。
|
|
10
|
-
- 🔄 **热更新**——`dsh-agent-instructions` 的 touch 监听器会捕获原生 `edit` 调用,当前会话立即收到 `Updated instructions`。
|
|
11
|
-
- 📦 **零存储层**——没有 JSON / SQLite / JSONL,没有解析 bug,没有并发写入问题。
|
|
12
|
-
- 🗂 **两级记忆**——全局 + 工作区;会话进入对应工作区时自动加载工作区层。
|
|
13
|
-
- ⚖️ **静态/动态分工**——插件只负责静态机制(加载链、模板、写入分流);所有操作规则放进 `~/.dsh/AGENTS.md`,改了立即热更新,不用重启。
|
|
14
|
-
- 🪪 **可回溯的变更日志**——工作区变更日志条目携带会话短ID,任何改动都能回溯到产生它的 `session.jsonl.zstd` 会话日志。
|
|
11
|
+
## 特性
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
- 🧠 **跨会话记忆**——复用 DSH 原生 `dsh-agent-instructions` 加载链,记忆在会话间自动持久化
|
|
14
|
+
- 🔍 **`memory_search` 检索**——插件注册的只读工具,对全局与各工作区记忆文件(热层+冷层)做关键字/正则搜索,休眠态同样可用
|
|
15
|
+
- 🛠 **写入零自定义工具**——agent 直接用系统 `read` / `write` / `edit` 维护记忆文件,保留原生热更新与审批 UX
|
|
16
|
+
- 🔄 **热更新**——touch 监听器捕获原生 `edit` 调用,当前会话立即收到更新
|
|
17
|
+
- 📦 **零存储层**——没有 JSON / SQLite / JSONL,没有解析 bug,没有并发写入问题
|
|
18
|
+
- 🗂 **两级记忆 + 冷层归档**——全局 + 工作区热层,`AGENT-MEMORY.md` 冷层存长流程与历史
|
|
19
|
+
- 😴 **自管休眠**——初始化完成后自动休眠省上下文,一句话唤醒
|
|
20
|
+
- 🪪 **可回溯的变更日志**——条目携带会话短ID,可回溯到 `session.jsonl.zstd`
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
## 快速开始
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
[会话 N] 模型调用 edit → 把记忆写入 AGENTS.md
|
|
22
|
-
[会话 N+1] (任意工作区,任意时刻)启动预步骤加载 AGENTS.md → 记忆进入上下文
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### 插件 vs AGENTS.md——各放什么
|
|
24
|
+
### 前置条件
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
- [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) 已配好 profile(如 `web`)
|
|
27
|
+
- Node.js ≥ 22
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|---|---|---|---|
|
|
31
|
-
| **机制性**(不能热替换) | "AGENTS.md 存在"、加载链、模板骨架、写入分流、跨工作区检索流程 | 插件提示词 | 模型一旦遗忘,整套记忆系统就崩;全新工作区还没有 AGENTS.md 可读这些规则 |
|
|
32
|
-
| **经验性**(应该可热替换) | 索引同步规则、索引行格式、描述写作标准、维护规则、收尾检查、变更日志短ID | `~/.dsh/AGENTS.md`(`## 注意事项`) | 这些是使用中沉淀的经验;编辑后通过 touch 监听器立即热更新,无需重启 |
|
|
29
|
+
### 安装(npm)
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
```sh
|
|
32
|
+
dsh plugin --profile web add dsh-memory-fast -w
|
|
33
|
+
```
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
若 dsh web 由 systemd 管理,重启生效:
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
```sh
|
|
38
|
+
systemctl restart dsh-web
|
|
39
|
+
```
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
- `pnpm`
|
|
41
|
+
重启后开一个新会话:插件自动注入记忆体系说明,模型按模板创建 `~/.dsh/AGENTS.md`(全局)与工作区根 `AGENTS.md`。初始化完成后模型自动把 `~/.dsh/.dsh-memory-state` 写为 `sleep`(休眠省上下文);对模型说「初始化记忆插件」即可唤醒。`memory_search` 工具在休眠态同样可用。
|
|
42
42
|
|
|
43
|
-
###
|
|
43
|
+
### 从源码安装
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
46
|
# 1. 把插件放到 ~/.dsh/plugins/ 下
|
|
47
|
-
cp -r dsh-memory ~/.dsh/plugins/dsh-memory
|
|
47
|
+
cp -r dsh-memory-fast ~/.dsh/plugins/dsh-memory-fast
|
|
48
48
|
|
|
49
|
-
# 2. 在 profile 的 package.json
|
|
50
|
-
# dependencies: "dsh-memory": "file:../../plugins/dsh-memory"
|
|
51
|
-
# dsh.profile.bundles: [
|
|
49
|
+
# 2. 在 profile 的 package.json 里注册:
|
|
50
|
+
# dependencies: "dsh-memory-fast": "file:../../plugins/dsh-memory-fast"
|
|
51
|
+
# dsh.profile.bundles: [..., "dsh-memory-fast"]
|
|
52
52
|
|
|
53
53
|
# 3. 安装并重启
|
|
54
54
|
cd ~/.dsh/profiles/<your-profile> && pnpm install
|
|
55
55
|
dsh --profile <your-profile>
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```sh
|
|
61
|
-
systemctl restart dsh-web
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
该服务配置了 `Restart=always`、`RestartSec=3`,以及会先杀掉占用 3080 端口进程的 `ExecStartPre`。重启会断开当前 Web GUI 会话——刷新页面即可重连新会话并加载新提示词。
|
|
58
|
+
> ⚠️ `file:` 依赖在 pnpm 安装时是**拷贝不是链接**——修改插件源码后必须把文件同步进 `node_modules` 里的实际加载位置(或用 `dsh plugin add` 重装),再重启 dsh,否则跑的还是旧副本。
|
|
65
59
|
|
|
66
60
|
## 记忆布局
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
| 层 | 文件 | 加载时机 | 章节 |
|
|
62
|
+
| 层 | 文件 | 加载时机 | 内容 |
|
|
71
63
|
|---|---|---|---|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
- **注意事项**(跨工作区操作规则)永远进全局——见上表。工作区不复制这些规则。
|
|
77
|
-
- **待办**永远进全局——汇总所有工作区,每条标注来源,便于在任何会话推进。
|
|
78
|
-
- **工作区索引**只在全局——每个工作区一行,含 ≤50 字描述 + 关键词 + 路径 + 规模,让模型按需 `read` 其他工作区的记忆。
|
|
79
|
-
|
|
80
|
-
### 工作区索引行格式
|
|
81
|
-
|
|
82
|
-
> **该规则存放位置:** `~/.dsh/AGENTS.md` → `## 注意事项` → `**工作区索引行格式**`。此处仅作参考,要改请去那里改。
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
- (YYYY-MM-DD) [workspace] 工作区标识 | 特征+用途描述(≤50字) | 关键词1、关键词2 | 路径: /绝对路径/AGENTS.md | 规模: N条
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**描述写作标准**
|
|
89
|
-
|
|
90
|
-
1. ≤50 字,结构固定:`[技术栈/形态] + [做什么] + [给谁/解决什么]`
|
|
91
|
-
2. 英文专有名词配中文解释,如 `GLM(智谱大模型)`、`Go(谷歌编程语言)`、`admin(管理后台)`
|
|
92
|
-
3. 避免空泛词("系统"、"服务"、"工具"),写具体形态("HTTP 转发服务"而非"一个服务")
|
|
93
|
-
4. 缩写一律补全含义
|
|
94
|
-
|
|
95
|
-
**示例**
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
- (2026-09-02) [workspace] glm-free-api | Go(谷歌编程语言) HTTP 转发服务,把智谱免费 GLM(智谱大模型) 接口包装成 OpenAI 兼容格式供下游客户端调用 | 鉴权、流式解析、admin(管理后台)、部署 | 路径: /opt/glm-free-api/server/AGENTS.md | 规模: 11条
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### 索引同步(强制)
|
|
64
|
+
| 全局热层 | `~/.dsh/AGENTS.md` | 每个会话 | 用户偏好 / 注意事项 / 工作区索引 / 待办 / 变更日志 |
|
|
65
|
+
| 工作区热层 | `<工作区根>/AGENTS.md` | 进入该工作区时 | 工作区注意事项 / 近期变更日志 |
|
|
66
|
+
| 全局冷层 | `~/.dsh/AGENT-MEMORY.md` | 按需 read | 长流程与踩坑档案、变更日志归档 |
|
|
67
|
+
| 工作区冷层 | `<工作区根>/AGENT-MEMORY.md` | 按需 read | 同上,工作区级 |
|
|
102
68
|
|
|
103
|
-
|
|
69
|
+
热层长条目在原位置留一行指针指向冷层锚点;防膨胀阈值(全局 30KB / 工作区 32KB,硬红线 55KB)内建于模板。
|
|
104
70
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
### 工作区变更日志短ID
|
|
108
|
-
|
|
109
|
-
**工作区**的 `## 工作区变更日志` 每条末尾追加 ` #<短ID>`,用于回溯:
|
|
110
|
-
|
|
111
|
-
- 短ID = `$DSH_SESSION_ID` 去掉 `session-` 前缀后 UUID 的前 8 位。
|
|
112
|
-
- 示例:`- (2026-09-03) ... #8acbdac5`。
|
|
113
|
-
- **只加工作区变更日志**,全局变更日志不加。
|
|
114
|
-
- 历史条目无法回溯的不补。
|
|
115
|
-
|
|
116
|
-
## 会话日志与环境变量
|
|
117
|
-
|
|
118
|
-
DSH 通过环境变量向每次 `bash` 工具调用暴露当前会话信息:
|
|
119
|
-
|
|
120
|
-
| 变量 | 含义 |
|
|
121
|
-
|---|---|
|
|
122
|
-
| `DSH_HOME` | DSH 根目录,通常 `/root/.dsh` |
|
|
123
|
-
| `DSH_SESSION_ID` | 当前会话 ID,如 `session-8acbdac5-d05c-4ce8-afbf-9243787338f5` |
|
|
124
|
-
| `DSH_SESSION_JSONL` | 完整聊天日志路径(zstd 压缩的 JSONL) |
|
|
125
|
-
| `DSH_WEB_URL` | Web GUI 地址,如 `http://127.0.0.1:3080` |
|
|
126
|
-
| `DSH_SHELL` | 在 harness shell 下为 `1` |
|
|
127
|
-
|
|
128
|
-
### 会话日志结构
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
/root/.dsh/sessions/ ← 根目录
|
|
132
|
-
└── --root-~8BB0~5FC6~63D2~4EF6--/ ← 编码后的工作区路径(此处为 /root/记忆插件)
|
|
133
|
-
└── session-8acbdac5-d05c-4ce8-afbf-9243787338f5/ ← 每个会话一个文件夹
|
|
134
|
-
└── session.jsonl.zstd ← 完整聊天日志,zstd 压缩的 JSONL
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
文件夹名编码规则:把工作区路径中每段非字母数字字符替换为 `~<十六进制码点>~`,所以 `记忆插件` 变成 `~8BB0~5FC6~63D2~4EF6`,结尾 `--` 标记路径结束。
|
|
138
|
-
|
|
139
|
-
查看会话日志:
|
|
140
|
-
|
|
141
|
-
```sh
|
|
142
|
-
# 解压为普通 JSONL,然后用 read 工具或 jq 查看
|
|
143
|
-
zstd -d /root/.dsh/sessions/--root-~8BB0~5FC6~63D2~4EF6--/session-8acbdac5-.../session.jsonl.zstd -o session.jsonl
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
工作区变更日志的短ID 正好是会话文件夹名 UUID 的前缀,所以从变更日志条目回到产生它的会话日志只需一步。
|
|
147
|
-
|
|
148
|
-
## memory_search 检索工具(0.1.16+)
|
|
71
|
+
## memory_search 检索工具
|
|
149
72
|
|
|
150
73
|
0.1.16 起插件通过 `inject: ["tools"]` 注册一个**只读**工具 `memory_search`,把"跨工作区检索"从纯提示词约定升级为机制兜底:
|
|
151
74
|
|
|
@@ -155,56 +78,48 @@ zstd -d /root/.dsh/sessions/--root-~8BB0~5FC6~63D2~4EF6--/session-8acbdac5-.../s
|
|
|
155
78
|
| `scope`(可选) | `all`(默认)= 全局 + 工作区索引登记的全部工作区;`global` = 仅 `~/.dsh` 两个全局文件;`workspaces` = 仅索引工作区文件 |
|
|
156
79
|
| `limit`(可选) | 单文件最多列出的匹配行数,默认 20(硬上限 100;`total_matches` 始终统计全量命中) |
|
|
157
80
|
|
|
158
|
-
-
|
|
159
|
-
- **返回**:`{query, files_searched, total_matches, matches:[{file, line, section, text}]}`,`section`
|
|
160
|
-
- **休眠态可用**:工具注册与 active/sleep
|
|
161
|
-
- **零新增依赖**:纯 Node 内置 `fs
|
|
81
|
+
- **搜索范围**:全局热/冷层 + 全局「工作区索引」行里登记的各工作区热/冷层;索引未登记的路径不猜测、不搜索
|
|
82
|
+
- **返回**:`{query, files_searched, total_matches, matches:[{file, line, section, text}]}`,`section` 为匹配行所属最近二级标题;拿到指针后用 `read` 跟进上下文
|
|
83
|
+
- **休眠态可用**:工具注册与 active/sleep 状态无关
|
|
84
|
+
- **零新增依赖**:纯 Node 内置 `fs` / `path`
|
|
162
85
|
|
|
163
|
-
##
|
|
86
|
+
## 工作原理
|
|
164
87
|
|
|
165
|
-
|
|
88
|
+
DSH 内置的 `dsh-agent-instructions` 插件在每个会话开始时把 `~/.dsh/AGENTS.md` 与工作区根的 `AGENTS.md` 注入对话上下文。本插件寄生在这条加载链上:
|
|
166
89
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
90
|
+
```
|
|
91
|
+
[会话 N] 模型调用 edit → 把记忆写入 AGENTS.md
|
|
92
|
+
[会话 N+1] (任意工作区,任意时刻)启动预步骤加载 AGENTS.md → 记忆进入上下文
|
|
93
|
+
```
|
|
170
94
|
|
|
171
|
-
|
|
95
|
+
**静态/动态分工**:插件提示词只放"缺失即崩"的机制性内容(加载链、模板骨架、写入分流);经验性规则(索引格式、维护规则、收尾检查)放进 `~/.dsh/AGENTS.md` 的「注意事项」——编辑后通过 touch 监听立即热更新,无需重启。
|
|
172
96
|
|
|
173
|
-
|
|
97
|
+
### 为什么写入不用自定义工具?
|
|
174
98
|
|
|
175
|
-
|
|
176
|
-
node --check index.js
|
|
177
|
-
# Syntax check passed
|
|
178
|
-
```
|
|
99
|
+
早期版本注册过 `memory_save` / `memory_list` / `memory_delete` 一整套读写工具,有三个问题:
|
|
179
100
|
|
|
180
|
-
|
|
101
|
+
1. **破坏热更新**——自定义工具不触发 touch 监听器,编辑无法传播到当前会话
|
|
102
|
+
2. **自建存储的 bug**——JSON 解析、原子写入、并发写入全要自己处理
|
|
103
|
+
3. **非原生 UX**——绕过了系统工具的审批/展示卡片
|
|
104
|
+
|
|
105
|
+
写入直接用系统工具完全规避这三个问题;只读的 `memory_search` 不触碰写入链路,故 0.1.16 起补回。
|
|
106
|
+
|
|
107
|
+
## 验证
|
|
181
108
|
|
|
182
109
|
```sh
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
# - id: dsh-memory
|
|
186
|
-
# name: dsh-memory
|
|
110
|
+
node --check index.js
|
|
111
|
+
dsh --profile <your-profile> --dump-config | grep dsh-memory-fast
|
|
187
112
|
```
|
|
188
113
|
|
|
189
|
-
|
|
114
|
+
插件成功加载后会在自身目录写 `.loaded` 标记(内容为 ISO 时间戳),其 mtime 晚于 dsh 进程启动时间即证明 `apply()` 已执行、工具已注册。
|
|
190
115
|
|
|
191
116
|
## 局限
|
|
192
117
|
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
- **插件提示词不可热替换**——改 `index.js`
|
|
198
|
-
|
|
199
|
-
## 文件结构
|
|
200
|
-
|
|
201
|
-
```
|
|
202
|
-
dsh-memory/
|
|
203
|
-
├── index.js # 插件入口——注入系统提示词 + 注册 memory_search 检索工具
|
|
204
|
-
├── package.json # 插件清单,声明 dsh.bundle.patch
|
|
205
|
-
├── cordis.patch.yml # patch 层,把插件注册到 profile
|
|
206
|
-
└── README.md # 本文件
|
|
207
|
-
```
|
|
118
|
+
- **两级一致性尽力而为**——全局索引与工作区文件是两次独立编辑,中断会留下过时索引(强制索引同步规则 + 收尾检查缓解)
|
|
119
|
+
- **跨层无自动去重**——同一内容写在两层会被注入两次
|
|
120
|
+
- **无文件锁**——多会话并发编辑同一 AGENTS.md 可能竞态(个人单用户风险低)
|
|
121
|
+
- **软约束**——保存时机、章节归属依赖模型遵守提示词,没有硬性保证
|
|
122
|
+
- **插件提示词不可热替换**——改 `index.js` 须重启 dsh
|
|
208
123
|
|
|
209
124
|
## License
|
|
210
125
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-memory-fast",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "DeepSeek Harness 记忆插件:AGENTS.md 三级冷热长期记忆 + memory_search 检索工具(全局+工作区、热/冷层、休眠态可用)。零存储层。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,5 +29,6 @@
|
|
|
29
29
|
"@deepseek-ai/dsh-tools": {
|
|
30
30
|
"optional": true
|
|
31
31
|
}
|
|
32
|
-
}
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT"
|
|
33
34
|
}
|