dsh-memoir 0.5.2 → 0.5.4

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.en.md CHANGED
@@ -9,10 +9,11 @@
9
9
  > Cache-aware local project memory for DeepSeek Harness.
10
10
 
11
11
  - **Local-only** — all data stays on your machine (`~/.dsh/dsh-memoir.json` + per-project `PROJECT_MEMORY.md`)
12
+ - **Zero regular runtime dependencies** — the npm package has no `dependencies`; its core relies only on DSH platform contracts and the Node.js standard library
12
13
  - **Zero external memory service** — no vector database, no embedding API, no cloud memory service
13
14
  - **Bounded hot-memory injection** — token-budgeted Hot Memory is injected into the system prompt (default 900/1200)
14
15
  - **Ranked local recall** — inverted index + BM25 local ranked retrieval; `memoir_read` fetches long-tail history on demand
15
- - **Web GUI** — a sidebar "Memory" panel with project/global browsing, relevance-ranked search, Hot Memory Inspector, and Retrieval Diagnostics
16
+ - **Web GUI** — a bilingual sidebar panel with complete lifecycle editing, project/global browsing, BM25 search, Hot Memory, diagnostics, and live settings
16
17
 
17
18
  ## Quick Start
18
19
 
@@ -81,10 +82,16 @@ need long-tail history? memoir_read (local relevance-ranked recall)
81
82
 
82
83
  **Session Snapshot freezing semantics**: one session's injected text is built once and frozen (stable prompt prefix, maximizing prompt-prefix cache hits); the current session does not re-consume memory it just wrote, and a new session rebuilds and sees the latest memory. Since v0.4.2, when there is no unique session identity (session.id / agent.id), freezing is skipped — a cache miss beats wrongly reusing another session's snapshot.
83
84
 
84
- ## v0.5.2 configurable auto-distill and rc2 compatibility
85
+ ## v0.5.4 Complete GUI, bilingual settings, and Web UI integration
85
86
 
86
87
  - The development and peer-dependency baseline is `@deepseek-ai/dsh-* 0.1.1-rc.2`.
87
- - Auto-distill now supports per-agent worked-turn intervals, time cooldowns, and tool-call thresholds; defaults `1 / 0 / 1` preserve prior behavior.
88
+ - Add/edit forms now cover `importance`, `pinned`, `tags`, and `supersedes`; cards expose importance, tags, and replacement relationships, with a new section filter.
89
+ - Memory Settings now appears both inside the Memory panel and under Settings → Web UI Plugins. It covers agent injection, auto-distill, Hot Memory, recall, session snapshots, and the BM25 query cache.
90
+ - Every saved setting applies live and persists in `~/.dsh/dsh-memoir.settings.json`; version-1 settings remain readable and upgrade to version 2 only on the next save.
91
+ - The GUI follows DSH's `<html lang>` and switches between Chinese and English without a reload, including the sidebar entry, panel, and Settings card.
92
+ - The panel and sidebar emit `data-dsh-plugin="memoir"` / `data-dsh-part` semantic attributes for the dsh-web-ui v0.3 skin contract. Sidebar mounting is idempotent and self-heals after a complete shell rebuild.
93
+ - Center-panel coordination now responds to any sibling through the generic `dsh-panel-activate` protocol instead of recognizing only SSH and Task Board.
94
+ - Auto-distill retains per-agent worked-turn intervals, time cooldowns, and tool-call thresholds; defaults `1 / 0 / 1` preserve prior behavior.
88
95
  - Store format v3 migrates v2 entries without changing their `id`, content, or timestamp. The first mutation materializes `importance`, `pinned`, `status`, `supersedes`, and `tags`; startup reads do not rewrite old files.
89
96
  - Retrieval defaults to `active`. Archived and superseded history is retained and can be inspected from the Web panel. Explicit `supersedes` marks its targets as superseded; history is never deleted automatically.
90
97
  - Agents can use `memoir_update` to edit an entry's section, title, content, and lifecycle in place; the Web panel also supports editing, pinning, marking superseded, archiving, and restoring.
@@ -117,14 +124,27 @@ Curated-query Top-5 hit rate: 100% (quality gate ≥ 90%, see `test/recall-quali
117
124
 
118
125
  ## GUI
119
126
 
120
- The v0.4 Project / Global / Search / Add / Delete / Diagnostics architecture is kept; since v0.4.2:
127
+ The Project / Global / Search / Add / Delete / Diagnostics architecture now forms a complete management surface:
121
128
 
122
129
  - **Search unified on RetrievalEngine**: a non-empty query calls `GET /api/dsh-memoir/search` — the same BM25 ranking as the agent's `memoir_read` — results ordered by relevance with scores shown
123
130
  - **Hot Memory Inspector**: expand to see the Hot Memory that will actually be injected for the current workspace (Actions / Lessons / Recent state) — i.e. "what exactly the next session inherits"
124
131
  - **Retrieval Diagnostics**: Retrieval Index (docs/terms/epoch), Query Cache (hits/misses/evictions/hit rate/size/capacity), Last Query (latency/returned), Session Snapshot (hash/createdAt/storeRevision)
132
+ - **Complete lifecycle forms (v0.5.4)**: add and edit section, title, content, importance, pinning, tags, and explicit replacement relationships; filter by status and section
133
+ - **Complete live settings (v0.5.4)**: adjust agent injection, auto-distill, Hot Memory target/hard limits, recall defaults/maxima, session snapshots, and query cache immediately
134
+ - **Settings integration (v0.5.4)**: the same bilingual card mounts in the Memory panel and Settings → Web UI Plugins, and redraws immediately when the page language changes
125
135
 
126
136
  ## Screenshots
127
137
 
138
+ **v0.5.4 memory management**: importance, tags, replacement relationships, status/section filters, and lifecycle actions in one panel.
139
+
140
+ ![v0.5.4 memory management](https://raw.githubusercontent.com/Qinling-Melon-Farmers/dsh-memoir/v0.5.4/picture/v0.5.4-memory-management-zh.png)
141
+
142
+ **v0.5.4 complete live settings**: the English Settings → Web UI Plugins card, switched live from the same Chinese-capable GUI.
143
+
144
+ ![v0.5.4 complete live settings](https://raw.githubusercontent.com/Qinling-Melon-Farmers/dsh-memoir/v0.5.4/picture/v0.5.4-settings-en.png)
145
+
146
+ The following screenshots retain the feature history of earlier releases:
147
+
128
148
  **1. Plugin active & overall UI**: the sidebar gains a "Memory" entry (alongside SSH / Task Board, mutually exclusive panels); clicking opens the memory panel in the center column.
129
149
 
130
150
  ![Plugin active & overall UI](picture/插件生效和UI效果1.png)
@@ -149,6 +169,7 @@ The v0.4 Project / Global / Search / Add / Delete / Diagnostics architecture is
149
169
 
150
170
  ```text
151
171
  ~/.dsh/dsh-memoir.json ← structured JSON (single source of truth / SSOT)
172
+ ~/.dsh/dsh-memoir.settings.json ← complete runtime overrides saved by either GUI settings surface
152
173
  <workspace>/PROJECT_MEMORY.md ← human-readable projection regenerated from the JSON (git-friendly)
153
174
 
154
175
  No cloud memory DB · No embedding API · No vector DB
@@ -181,6 +202,8 @@ Add a `config` block on the plugin row in `cordis.patch.yml` (all optional; defa
181
202
 
182
203
  The three auto-distill frequency conditions are combined with AND and isolated per agent. Idle, aborted, subagent, and prior-`memoir_record` turns do not advance the interval. A worked turn below `autoDistillMinTools` advances the interval but cannot trigger by itself. Cooldown changes only after a successful steer.
183
204
 
205
+ Fields in `cordis.patch.yml` remain startup defaults. Since v0.5.4, the Memory panel or Settings → Web UI Plugins can edit every runtime field except the master `enabled` switch. Saving atomically writes `~/.dsh/dsh-memoir.settings.json`; subsequent requests and turns read the new values immediately, and shrinking snapshot/query-cache capacities evicts the oldest entries at once. Already frozen session snapshots are not rewritten when budgets change, preserving prompt-prefix cache stability. Restore Startup Config removes the Web override and returns to the profile values resolved when the plugin mounted.
206
+
184
207
  ## Design Trade-offs
185
208
 
186
209
  - **Bounded vs full injection**: v0.3 injected the full history into the prompt and it kept growing; v0.4+ injects only budgeted Hot Memory, with long-tail history recalled on demand. Token benchmarks below.
@@ -189,7 +212,7 @@ The three auto-distill frequency conditions are combined with AND and isolated p
189
212
  - **Multi-process safety**: store record/remove runs inside a cross-process critical section on `~/.dsh/dsh-memoir.lock` (exclusive O_EXCL creation with timeout); the section force-reloads from disk before mutating, so two interleaved DSH processes lose no updates (v0.4.2).
190
213
  - **Windows paths**: canonical keys are fully lowercased (`C:\A` / `c:\a\` / `C:/A` share one bucket) while display paths keep the original casing (v0.4.2).
191
214
  - **GUI and Agent share one engine**: panel search and `memoir_read` use the same RetrievalEngine instead of separate filter logic (v0.4.2).
192
- - **Auto-distill cadence**: the default still reminds after every worked turn; research-heavy sessions can combine interval, cooldown, and activity thresholds to reduce interruptions (v0.5.2).
215
+ - **Auto-distill cadence**: the default still reminds after every worked turn; research-heavy sessions can combine interval, cooldown, and activity thresholds and tune them immediately from either GUI settings surface (v0.5.4).
193
216
 
194
217
  ## Use Cases
195
218
 
@@ -220,7 +243,7 @@ Each plugin has its own focus — pick per need; no "which is stronger" narrativ
220
243
  pnpm install # install devDeps (typescript, esbuild, @deepseek-ai/* type packages)
221
244
  pnpm run build # tsc builds the host + esbuild builds the client bundle
222
245
  pnpm run typecheck # full type check (src + test)
223
- pnpm test # 147 tests: store (incl. multi-process lock) / snapshot / selector / retrieval / tools / routes / auto-distill / integration / client pure logic / bundle protocol & purity / release notes
246
+ pnpm test # 160 tests: store (incl. multi-process lock) / settings / snapshot / selector / retrieval / tools / routes / auto-distill / GUI mounting & bilingual behavior / integration / bundle protocol & purity / release notes
224
247
  npm run bench # benchmark (100/1k/10k/100k entries); results written to bench/report.md
225
248
  ```
226
249
 
@@ -237,7 +260,7 @@ v0.4.2 benchmark summary (node v22.23.2, budget 900/1200 tokens; full report in
237
260
 
238
261
  ## Implementation
239
262
 
240
- - **Full-stack TypeScript**: `src/host/*.ts` (store / tools / retrieval / selector / snapshot / routes / autodistill / index — tsc emits `lib/*.js`) + `src/client/*.ts(x)` (esbuild emits the `lib/client.js` closure-factory bundle).
263
+ - **Full-stack TypeScript**: `src/host/*.ts` (store / settings / tools / retrieval / selector / snapshot / routes / autodistill / index — tsc emits `lib/*.js`) + `src/client/*.ts(x)` (esbuild emits the `lib/client.js` closure-factory bundle).
241
264
  - **Two-sided plugin**: the host half registers the agent tools, `/api/dsh-memoir` routes, the `agent/turn-stopping` auto-distill listener, and the per-project system-prompt injection section; the client half renders the panel. Runtime deps are official NPM SDK packages only.
242
265
  - Mounted via the `dsh.bundle.patch` manifest (`insert` row in `cordis.patch.yml`); no DSH source changes.
243
266
  - Auto-distill safety boundaries: top-level sessions only (subagents / nested delegations skipped), turns with tool activity that haven't recorded yet, aborted turns skipped, at most one steer per turn.
@@ -254,7 +277,7 @@ Bug reports must include screenshot / log evidence, a smoke test, code reference
254
277
 
255
278
  ## Release
256
279
 
257
- Current stable release: **v0.5.2** (2026-08-22) · [GitHub Release](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases/tag/v0.5.2) · [npm](https://www.npmjs.com/package/dsh-memoir/v/0.5.2). Full history is in [CHANGELOG.md](./CHANGELOG.md).
280
+ Current stable release: **v0.5.4** (2026-08-23) · [GitHub Release](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases/tag/v0.5.4) · [npm](https://www.npmjs.com/package/dsh-memoir/v/0.5.4). Full history is in [CHANGELOG.md](./CHANGELOG.md).
258
281
 
259
282
  Every version keeps Chinese and English release notes in sync. GitHub Releases show Chinese by default and place the English notes in a collapsible `English` section.
260
283
 
package/README.md CHANGED
@@ -9,10 +9,11 @@
9
9
  > Cache-aware local project memory for DeepSeek Harness.
10
10
 
11
11
  - **Local-only**:全部数据留在本机(`~/.dsh/dsh-memoir.json` + 项目内 `PROJECT_MEMORY.md`)
12
+ - **零普通运行时依赖**:npm 包没有 `dependencies`,核心逻辑只依赖 DSH 平台契约与 Node.js 标准库
12
13
  - **Zero external memory service**:无向量数据库、无 embedding API、无云端记忆服务
13
14
  - **Bounded hot-memory injection**:token 预算内的 Hot Memory 自动注入 system prompt(默认 900/1200)
14
15
  - **Ranked local recall**:倒排索引 + BM25 本地排序召回,`memoir_read` 按需检索长尾历史
15
- - **Web GUI**:侧边栏「记忆」面板——项目/全局浏览、相关排序搜索、Hot Memory Inspector、Retrieval Diagnostics
16
+ - **Web GUI**:中英双语侧边栏面板——完整生命周期编辑、项目/全局浏览、BM25 搜索、Hot Memory、诊断和实时设置
16
17
 
17
18
  ## Quick Start
18
19
 
@@ -81,10 +82,16 @@ memoir_record 沉淀工作 / 教训 / 下一步
81
82
 
82
83
  **Session Snapshot 冻结语义**:同一 session 的注入文本只构建一次并冻结(prompt 前缀稳定,最大化 prompt-prefix cache 命中);当前 session 不重新消费自己刚写的记忆,新 session 重建并看到最新记忆。v0.4.2 起,没有唯一会话身份(session.id / agent.id)时**不做冻结**——宁可 cache miss,不可跨 session 错复用旧快照。
83
84
 
84
- ## v0.5.2 可调自动收尾与 rc2 兼容性
85
+ ## v0.5.4 完整 GUI、双语设置与 Web UI 适配
85
86
 
86
87
  - 当前开发基线为 `@deepseek-ai/dsh-* 0.1.1-rc.2`;peer dependency 与开发依赖已统一到 rc2。
87
- - 自动收尾支持按 agent 配置 worked-turn 间隔、时间冷却和工具调用阈值;默认值 `1 / 0 / 1` 与旧版行为一致。
88
+ - 新增/编辑表单现已完整覆盖 `importance`、`pinned`、`tags` 与 `supersedes`;列表显示重要度、标签和替代关系,并新增 section 筛选。
89
+ - 「记忆设置」同时出现在记忆面板和 Settings → Web UI 插件,覆盖 agent 注入、自动蒸馏、Hot Memory、召回、会话快照与 BM25 查询缓存。
90
+ - 保存后的所有设置实时生效并持久化到 `~/.dsh/dsh-memoir.settings.json`;v1 设置文件兼容读取,首次保存再升级到 v2。
91
+ - GUI 根据 DSH 的 `<html lang>` 在中文/英文之间即时切换,无需刷新;侧栏入口、面板和 Settings 卡保持同一语言。
92
+ - 面板与侧栏输出 `data-dsh-plugin="memoir"` / `data-dsh-part` 语义属性,支持 dsh-web-ui v0.3 皮肤契约;侧栏挂载具备幂等和整棵 shell 重建自愈。
93
+ - 中心面板通过通用 `dsh-panel-activate` 协议响应任意兄弟面板,不再只识别 SSH / Task Board。
94
+ - 自动蒸馏继续支持按 agent 配置 worked-turn 间隔、时间冷却和工具调用阈值;默认值 `1 / 0 / 1` 与旧版行为一致。
88
95
  - 存储格式从 v2 迁移到 v3:旧条目保持原有 `id`、内容和时间,首次变更时补齐 `importance`、`pinned`、`status`、`supersedes` 与 `tags`;启动读取不会重写旧文件。
89
96
  - 默认只召回 `active` 条目;归档和被替代条目保留在历史中,可在 Web 面板切换状态查看。显式 `supersedes` 会把目标条目标记为 `superseded`,不会自动删除历史。
90
97
  - Agent 可用 `memoir_update` 原地编辑条目的分类、标题、正文和生命周期;Web 面板也支持编辑、置顶、标记过时、归档与恢复。
@@ -117,14 +124,27 @@ curated 查询 Top-5 命中率 100%(质量门禁 ≥90%,见 `test/recall-qua
117
124
 
118
125
  ## GUI
119
126
 
120
- 保留 v0.4 的 Project / Global / Search / Add / Delete / Diagnostics 架构,v0.4.2 起:
127
+ Project / Global / Search / Add / Delete / Diagnostics 架构已经扩展为完整管理面:
121
128
 
122
129
  - **搜索统一走 RetrievalEngine**:query 非空时面板调用 `GET /api/dsh-memoir/search`,与 agent 的 `memoir_read` 共用同一套 BM25 排序,结果按相关性排列并显示分数
123
130
  - **Hot Memory Inspector**:展开查看当前工作区实际会被注入的 Hot Memory(Actions / Lessons / Recent state),即「下一会话到底自动继承什么」
124
131
  - **Retrieval Diagnostics**:Retrieval Index(docs/terms/epoch)、Query Cache(hits/misses/evictions/hit rate/size/capacity)、Last Query(latency/returned)、Session Snapshot(hash/createdAt/storeRevision)
132
+ - **完整生命周期表单(v0.5.4)**:新建与编辑均支持分类、标题、正文、重要度、置顶、标签和显式替代关系;支持状态与分类双重筛选
133
+ - **完整实时设置(v0.5.4)**:agent 注入、auto-distill、Hot Memory 目标/硬上限、读取默认/最大条数、会话快照和查询缓存均可即时调整
134
+ - **Settings 集成(v0.5.4)**:同一双语设置卡同时挂载到记忆面板和 Settings → Web UI 插件;页面切换语言时即时重绘
125
135
 
126
136
  ## 界面预览
127
137
 
138
+ **v0.5.4 记忆管理**:重要度、标签、替代关系、状态/分类筛选与完整生命周期操作集中在同一面板。
139
+
140
+ ![v0.5.4 记忆管理](https://raw.githubusercontent.com/Qinling-Melon-Farmers/dsh-memoir/v0.5.4/picture/v0.5.4-memory-management-zh.png)
141
+
142
+ **v0.5.4 完整实时设置**:Settings → Web UI 插件中的中文设置卡;README English 展示同一卡片的英文实时切换效果。
143
+
144
+ ![v0.5.4 完整实时设置](https://raw.githubusercontent.com/Qinling-Melon-Farmers/dsh-memoir/v0.5.4/picture/v0.5.4-settings-zh.png)
145
+
146
+ 以下图片保留早期版本的功能演进记录:
147
+
128
148
  **1. 插件生效与整体 UI**:侧边栏出现「记忆」入口(与 SSH / 任务看板同列、互斥展开),点击后在中心列打开记忆面板。
129
149
 
130
150
  ![插件生效与整体 UI](picture/插件生效和UI效果1.png)
@@ -149,6 +169,7 @@ curated 查询 Top-5 命中率 100%(质量门禁 ≥90%,见 `test/recall-qua
149
169
 
150
170
  ```text
151
171
  ~/.dsh/dsh-memoir.json ← 结构化 JSON(唯一事实源 / SSOT)
172
+ ~/.dsh/dsh-memoir.settings.json ← 两个 GUI 设置面保存的完整运行时覆盖
152
173
  <工作区>/PROJECT_MEMORY.md ← 由 JSON 重新生成的人类可读投影(git 友好)
153
174
 
154
175
  No cloud memory DB · No embedding API · No vector DB
@@ -181,6 +202,8 @@ JSON 是 source of truth,Markdown 是 generated projection:面板、工具
181
202
 
182
203
  三个 auto-distill 频率条件按 AND 关系判定并按 agent 隔离。idle、aborted、subagent、已调用 `memoir_record` 的 turn 不推进间隔计数;低于 `autoDistillMinTools` 的 worked turn 会推进间隔,但自身不能触发提醒。冷却只在 steer 成功后更新。
183
204
 
205
+ `cordis.patch.yml` 中的字段是启动默认值。v0.5.4 起,可从记忆面板或 Settings → Web UI 插件修改除总开关 `enabled` 外的全部运行时字段:保存会原子写入 `~/.dsh/dsh-memoir.settings.json`,后续请求或 turn 立即读取;缩小快照/查询缓存容量会立即淘汰最旧项。已冻结的 session snapshot 不会因预算变化而重写,以继续保证 prompt-prefix cache 稳定。「恢复启动配置」会删除 Web 覆盖并回到本次挂载时解析出的 profile 值。
206
+
184
207
  ## Design Trade-offs
185
208
 
186
209
  - **有界注入 vs 全量注入**:v0.3 把完整历史注入 prompt,越用越膨胀;v0.4+ 只注入预算内的 Hot Memory,长尾历史按需召回。token 基准见下方 Benchmark。
@@ -189,7 +212,7 @@ JSON 是 source of truth,Markdown 是 generated projection:面板、工具
189
212
  - **多进程安全**:store 的 record/remove 走 `~/.dsh/dsh-memoir.lock` 跨进程临界区(O_EXCL 独占创建 + 超时),临界区内强制从磁盘重读再改,两个 DSH 进程交错写入不丢更新(v0.4.2)。
190
213
  - **Windows 路径**:canonical key 全小写(`C:\A` / `c:\a\` / `C:/A` 一个桶),display path 保留原始大小写(v0.4.2)。
191
214
  - **GUI 与 Agent 同源**:面板搜索与 `memoir_read` 共用 RetrievalEngine,不再各写一套过滤逻辑(v0.4.2)。
192
- - **自动收尾节奏**:默认仍逐 worked turn 提醒;研究型会话可组合轮次间隔、冷却与活动阈值降低打扰(v0.5.2)。
215
+ - **自动收尾节奏**:默认仍逐 worked turn 提醒;研究型会话可组合轮次间隔、冷却与活动阈值降低打扰,并从两个 GUI 设置面即时调节(v0.5.4)。
193
216
 
194
217
  ## Use Cases
195
218
 
@@ -220,7 +243,7 @@ JSON 是 source of truth,Markdown 是 generated projection:面板、工具
220
243
  pnpm install # 安装 devDeps(typescript、esbuild、@deepseek-ai/* 类型包)
221
244
  pnpm run build # tsc 构建 host + esbuild 构建 client bundle
222
245
  pnpm run typecheck # 全量类型检查(src + test)
223
- pnpm test # 147 项测试:store(含多进程锁) / snapshot / selector / retrieval / tools / routes / 自动收尾 / 集成 / client 纯逻辑 / bundle 协议与纯净性 / 发布说明
246
+ pnpm test # 160 项测试:store(含多进程锁) / settings / snapshot / selector / retrieval / tools / routes / 自动收尾 / GUI 挂载与双语 / 集成 / bundle 协议与纯净性 / 发布说明
224
247
  npm run bench # benchmark(100/1k/10k/100k 条目),结果写入 bench/report.md
225
248
  ```
226
249
 
@@ -237,7 +260,7 @@ v0.4.2 benchmark 摘要(node v22.23.2,budget 900/1200 tokens;完整报告
237
260
 
238
261
  ## 实现说明
239
262
 
240
- - **TypeScript 全栈**:`src/host/*.ts`(store / tools / retrieval / selector / snapshot / routes / autodistill / index,tsc 构建出 `lib/*.js`)+ `src/client/*.ts(x)`(esbuild 打出 `lib/client.js` 闭包工厂 bundle)。
263
+ - **TypeScript 全栈**:`src/host/*.ts`(store / settings / tools / retrieval / selector / snapshot / routes / autodistill / index,tsc 构建出 `lib/*.js`)+ `src/client/*.ts(x)`(esbuild 打出 `lib/client.js` 闭包工厂 bundle)。
241
264
  - **双面插件**:host 半注册 agent 工具、`/api/dsh-memoir` 路由、`agent/turn-stopping` 自动收尾监听与按项目求值的 system prompt 注入段;client 半提供面板。运行时仅依赖官方 NPM SDK。
242
265
  - 通过 `dsh.bundle.patch` manifest(`cordis.patch.yml` 的 `insert` 行)挂载,不改 DSH 源码。
243
266
  - 自动收尾安全边界:仅顶级会话(跳过 subagent / 嵌套委托)、仅「有工具调用且未记录过」的回合、已中止回合不打扰、每回合至多一次。
@@ -255,7 +278,7 @@ PR 请先提 Issue 讨论。
255
278
 
256
279
  ## Release
257
280
 
258
- 当前稳定版:**v0.5.2**(2026-08-22) · [GitHub Release](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases/tag/v0.5.2) · [npm](https://www.npmjs.com/package/dsh-memoir/v/0.5.2)。完整历史见 [CHANGELOG.md](./CHANGELOG.md)。
281
+ 当前稳定版:**v0.5.4**(2026-08-23) · [GitHub Release](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases/tag/v0.5.4) · [npm](https://www.npmjs.com/package/dsh-memoir/v/0.5.4)。完整历史见 [CHANGELOG.md](./CHANGELOG.md)。
259
282
 
260
283
  每个版本的更新日志均同步维护中英文;GitHub Release 默认展开中文,英文说明收纳在可折叠的 `English` 区域。
261
284
 
package/cordis.patch.yml CHANGED
@@ -19,6 +19,15 @@
19
19
  # autoDistillEvery: 1 # remind at most once per N worked turns
20
20
  # autoDistillCooldownMin: 0 # minimum minutes between successful reminders
21
21
  # autoDistillMinTools: 1 # minimum tool calls on the triggering turn
22
+ # All fields except enabled are startup defaults. v0.5.4+ can persist complete
23
+ # live overrides from the Memory panel or Settings -> Web UI Plugins:
24
+ # hotMemoryTokens: 900
25
+ # hotMemoryMaxTokens: 1200
26
+ # readDefaultLimit: 8
27
+ # readMaxLimit: 30
28
+ # sessionSnapshotMax: 128
29
+ # queryCacheSize: 128
30
+ # Overrides live in ~/.dsh/dsh-memoir.settings.json and can be reset.
22
31
  - insert:
23
32
  - id: memoir
24
33
  name: dsh-memoir
@@ -77,5 +77,11 @@ export declare function installAutoDistill(wire: AutoDistillWire, options: {
77
77
  every?: number;
78
78
  cooldownMin?: number;
79
79
  minTools?: number;
80
+ /** Optional live policy source used by the Web settings panel. */
81
+ policy?: () => {
82
+ every?: number;
83
+ cooldownMin?: number;
84
+ minTools?: number;
85
+ };
80
86
  now?: () => number;
81
87
  }): () => void;
@@ -90,11 +90,6 @@ export function installAutoDistill(wire, options) {
90
90
  const gate = new AutoDistillGate();
91
91
  const integerAtLeast = (value, fallback, minimum) => typeof value === 'number' && Number.isFinite(value) ? Math.max(minimum, Math.floor(value)) : fallback;
92
92
  const numberAtLeast = (value, fallback, minimum) => typeof value === 'number' && Number.isFinite(value) ? Math.max(minimum, value) : fallback;
93
- const policy = {
94
- every: integerAtLeast(options.every, 1, 1),
95
- cooldownMs: numberAtLeast(options.cooldownMin, 0, 0) * 60_000,
96
- minTools: integerAtLeast(options.minTools, 1, 1),
97
- };
98
93
  return wire.on('agent/turn-stopping', (payload) => {
99
94
  if (!options.enabled())
100
95
  return;
@@ -106,6 +101,12 @@ export function installAutoDistill(wire, options) {
106
101
  const { worked, recorded, toolCalls } = turnActivity(agent.session.events, turn);
107
102
  if (!worked || recorded)
108
103
  return;
104
+ const live = options.policy?.();
105
+ const policy = {
106
+ every: integerAtLeast(live?.every ?? options.every, 1, 1),
107
+ cooldownMs: numberAtLeast(live?.cooldownMin ?? options.cooldownMin, 0, 0) * 60_000,
108
+ minTools: integerAtLeast(live?.minTools ?? options.minTools, 1, 1),
109
+ };
109
110
  const now = options.now?.() ?? Date.now();
110
111
  if (!gate.consume(agent.id, turn, toolCalls, policy, now))
111
112
  return;