Repository navigation
Releases
Releases · BPTumbleweed/dsh-agent-memory
v0.2.1 — 修复:面板整页空白
修了什么
面板打开后只剩卡片标题、内容全空。
根因:v0.2.0 在 JS 模板字符串里直接写了正则 /^---[\s\S]*?---\n/ 用来剥会话文件的 frontmatter。
模板字符串会先吃掉转义:\s→s、\n→真换行,于是正则跨行断裂,整段内联脚本
SyntaxError,后面所有渲染都没执行。
修法
- 剥 frontmatter 移到服务端做(
stripFrontmatter()),前端不再出现正则 - 新增第 9 项自测:把面板生成的内联脚本抽出来做语法解析
(new Function(js))—— 原有的取值路径守卫只查了数据路径,查不出这类语法事故
自测 13 项 + 脱敏自检 8 项全过。
v0.2.0 — 双层记忆:全局偏好 + 对话专属记忆
本次新增
记忆分成两层,解决所有对话共用一份记忆的问题:
| 全局层 | 对话层 | |
|---|---|---|
| 文件 | preferences/global.md |
sessions/<会话id>.md |
| 注入者 | 官方 agent-instructions($DSH_HOME/AGENTS.md) |
本插件(agent/pre-step) |
| 生效范围 | 每个对话 | 仅该对话 |
| 预算 | 6 KB 告警 | 2 KB 截断(sessionInjectMax) |
python3 bin/memory-note.py "普适习惯" --section "干活" # 全局
python3 bin/memory-note.py "只对这个对话有用" --scope session --section "约定" # 对话层实现要点
- 注入位置取自 DSH 核心契约:
agent/pre-step瀑布钩子,返回{kind:"enter", messages};
采用官方写法先await next()再改结果,不吞掉别人的处理器;消息带
source:{kind:"plugin",plugin:"dsh-agent-memory",form:"session-memory"},插在最后一条用户消息之前 - 这层是内部接口,按最坏情况设计:特性探测 + 熔断 + 字节预算;失效只影响本层,
全局注入与记忆库不受影响,面板会标红说明 - 会话文件 90 天未更新自动归档到
sessions/archive/(不删除);sessions/index.json记录大小/条数/是否超预算 - 面板新增「本对话记忆」卡片;
/data/session?id=带格式校验(实测../被拒)
实测
在真实会话中验证:注入事件 seq 2891 / 10:33:20 / kind=plugin / form=session-memory / 246 字符,
计数器 injected:1。自测 12 项 + 脱敏自检 8 项全过。
兼容性
全局注入路径完全未动(仍由官方 agent-instructions 负责);新增的会话层是可降级的可选能力。
v0.1.0 — 插件 + 配套 CLI
首个版本:插件 + 配套 CLI,装完即有数据、有面板。
装
dsh plugin --profile web add github:BPTumbleweed/dsh-agent-memory
systemctl restart dsh-web-<你的实例>包含什么
插件(lib/)
- 挂
session/event实时采集人类用户消息,写入evidence/live-messages.jsonl(由 CLI 按消息 id 归并去重,不会重复计数) - 会话头部新增 「记忆」页签,内容为自包含面板:统计磁贴、能力探测、记忆库规模、注入体预算、最近错误、常用命令
- 10 个白名单只读数据接口,把统计项做成可点按钮,直接看库里究竟存了什么
- 全部路由走 DSH 浏览器信任栅栏,栅栏不可用时默认 fail-closed
配套 CLI(bin/)
memory-scan.py:增量扫描会话日志 → 证据;归并 live 文件;压缩工作集;生成digest.md与$DSH_HOME/AGENTS.mdmemory-note.py:当场记一条长期偏好(写入偏好档案 + 日志,并刷新摘要)redact.py:脱敏引擎(已知密钥值采集 + 结构模式),所有入库内容先过它,带自检
兼容性(本项目的核心设计约束)
- 零运行时依赖 —— 只用
node:fs/node:path/node:os/node:module - 不声明硬依赖 ——
inject: [];webServer/connection用ctx.inject([...], cb)可选等待,缺了就标unavailable - 回调全包 try/catch —— 异常绝不冒泡进 DSH
- 失败熔断 —— 同一能力连续失败到阈值只停该能力,原因显示在面板上
- 只写自己的目录
- 降级链 —— 插件停摆 ⇒ CLI 定时器照跑;面板坏了 ⇒ 摘要与日志照旧;插件整个坏了 ⇒ 注入与记忆库不受影响
- 不接管注入 ——
agent/pre-step/agent.inbox属内部接口、升级最易碎,偏好注入继续交给官方agent-instructions与$DSH_HOME/AGENTS.md
存储模型:工作集,不是档案
原始消息的权威副本在 DSH 自己的会话日志里,所以库里只保留"最近 N 条未沉淀材料",更早的压掉并在 evidence/archive.jsonl 记一行台账,随时可用 --rebuild 从会话日志重建。
已知边界
- 面板里的数据依赖配套 CLI 定时运行;只装插件不跑 CLI,面板会是空的
- 客户端页签使用 DSH 的客户端插槽 API(
conversation.view)。这是本方案里最容易被版本升级打断的一层,因此客户端只有十几行(注册页签 + iframe),UI 逻辑全在服务端:最坏情况是页签消失,不影响会话本体 - 在 DSH
0.1.5-rc.1上验证通过(见package.json的dsh.compatibility.dshReleases)
自检
node test/selftest.mjs # 8 项
python3 bin/redact.py # 脱敏引擎自检