ventisyn/dsh-agent-control ↗★ 1
dsh-agent-control
DeepSeek Harness 插件:把「删除一个会话」与「从模型上下文中删除一轮对话」这两件破坏性操作收进一个插件,用同一套确认与失败语义管理。 适合需要删除闲置会话或移除单轮模型上下文的用户;单轮删除仍保留日志与附件。
インストール
$
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:ventisyn/dsh-agent-controlドキュメント
README 全文を読む ↗dsh-agent-control
DeepSeek Harness(DSH)插件:把两件破坏性、不可撤销的操作收进一个插件,用同一套确认与失败语义管理。
- 删除会话:把一个会话不留残留地移除——磁盘目录(两种 id 拼写)、工作区记账(含归档/置顶)、投影缓存记录,以及它派生的子代理会话(递归,同样清目录与缓存)。fork 出来的会话是独立对话,不受影响。子代理里只要有一个还驻留在内存里,整次删除都会拒绝、什么都不动
- 插件不碰的:别的插件自己存的数据(例如审批类插件的事件记录里可能提到这个会话 id)、按内容寻址共享的附件(
$DSH_HOME/attachments,可能被别的会话引用)
- 插件不碰的:别的插件自己存的数据(例如审批类插件的事件记录里可能提到这个会话 id)、按内容寻址共享的附件(
- 删除一轮对话:从模型可见的上下文里移除一轮已结束的对话(问题、回复与该轮的工具记录),会话本身、之后的轮次与日志都保留
- 做法与 DSH 自己的手动压缩同形:一笔独立压缩事务把那一轮的可见区间换成一句「这里原有一轮对话,已被用户删除」的提示,模型从此看不到原内容。只能在会话空闲时删(有一轮正在进行或正在压缩时会拒绝)。
- ⚠️ v1.0.0 的旧写法(空的
system/message墓碑)会让会话重启后打不开,已不再使用。
本插件只使用 DSH 的公开 API:不依赖内核的私有结构,也不照抄任何第三方插件的实现。这一点是刻意的——依赖私有结构的写法换一个 harness 版本就会静默失效(详见 AGENTS.md 第 4 节)。
两者的区别(最要紧的一条)
| 删除会话 | 删除一轮 | |
|---|---|---|
| 磁盘日志 | 永久删除 | 保留(日志是 append-only,不改写、不截断) |
| 模型上下文 | 会话整个消失 | 那一轮不再进入上下文 |
| 附件 | 随会话目录一起删 | 不会清理(见下方「已知限制」) |
| 可恢复 | ❌ 不可恢复 | ❌ 但内容仍在日志里 |
⚠️ 删除一轮不是安全删除。 它通过在日志末尾追加一笔压缩事务、把那一轮从模型可见面上替换掉来实现。被删内容仍然完整留在会话日志与附件存储里,只是不再进入模型上下文。任何「删了就没人能看到」的理解都是错的。
界面
- 会话行「…」菜单 → 「删除会话…」(侧栏)
- 每条已结束的回复旁 → 垃圾桶按钮(会话运行中时禁用)
- 两者都会弹出同一个确认框,必须勾选确认才能点「删除」
- 删掉的那一轮会在界面上被隐藏,让界面与模型看到的保持一致
已知限制
- 不能删除仍处于活动状态的会话。DSH 没有公开的「把会话从内存 store 摘除」的 API(能摘除的 disposer 只交给会话的创建者),所以对一个活着的会话强删磁盘,只会留下「目录没了但会话还在列表里」的半删除状态。插件选择拒绝,而不是制造一个说不清的状态。
- ⚠️ 切换到别的会话并不会让它下线:Web 端打开过的会话会一直驻留在内存里,直到
dsh web退出。所以要删一个本次启动后打开过的会话,只能重启dsh web,重启后不要点开它,直接从侧栏「…」菜单删除。
- ⚠️ 切换到别的会话并不会让它下线:Web 端打开过的会话会一直驻留在内存里,直到
- 删除一轮不清理附件:内核当前没有公开的附件清理接口。被删轮次里的图片/文件仍留在
$DSH_HOME/attachments。 - 已压缩的轮次可能无法单独删除:如果那一轮与其它内容共用了一个压缩后的可见节点,或它的可见节点不再连续,插件会拒绝并说明原因,而不是删掉一半。
- HTTP 接口没有鉴权:插件自建的路由不走 harness 的鉴权链路——能访问到这个端口的人就能调用删除。默认只监听回环地址;如果你的
webServer配置成0.0.0.0,请自行评估。
安装
# 从已发布的版本分支安装
dsh plugin --profile
add github:ventisyn/dsh-agent-control#0.2.0-rc.2-v1.0.0
# 本地开发(改完重启即生效)
dsh plugin --profile
add link:
⚠️ 如果 profile 里已经装了别的删除类插件,请先移除,否则界面上会出现两套删除按钮——同一批槽位只能有一个主人:
dsh plugin --profile
remove
安装或改动 host 端代码后需要重启 dsh web:已加载的 host 模块不会因为文件改动而重新导入(新增的路由会一直返回 401)。
排障
装好之后:
# 会话列表(同时也是「路由是否注册成功」的探针)
curl http://127.0.0.1:/api/agent-control/sessions
浏览器控制台里:
window.__dshAgentControl.usingNativePrimitives() // 用的是原生原语还是自带兜底
window.__dshAgentControl.id // 注册 id
接口一览:
GET /api/agent-control/sessions 会话列表
GET /api/agent-control/turns?sessionId= 某个会话里已被删除的轮次
POST /api/agent-control/session/delete { sessionId }
POST /api/agent-control/turn/delete { sessionId, assistantMessageId }
失败一律返回 { ok: false, error: { code, message } }。错误码含义:
| 码 | 含义 |
|---|---|
SESSION_LIVE | 会话本次启动后打开过、仍驻留在内存里:重启 dsh web 后不打开它直接删 |
TARGET_NOT_FOUND | 目标已经不存在 |
TURN_NOT_CLOSED | 那一轮还没结束 |
TURN_COMPACTED | 那一轮已被压缩或不再连续,无法单独删除 |
AGENT_BUSY | 会话的任务没有停下来,已放弃删除 |
DELETE_FAILED | 宿主拒绝了这次删除(消息里带原始原因) |
开发
npm test # 语法检查 + 83 项离线测试,不需要 DSH 进程,也不碰真实 profile
设计与取舍、与 DSH 版本的耦合点、改完的自检清单都在 AGENTS.md。
说明
- 非官方:这是第三方插件,与 DeepSeek 官方没有隶属或背书关系;文中出现的 DeepSeek、DeepSeek Harness、DSH 等名称仅用于说明它在什么环境里运行。
- 主要由 AI 编码代理编写:代码、测试与文档都是在与 AI 代理协作下产出的,提交历史里能直接看到。仓库里所有结论都尽量附上可复核的证据(日志、接口响应、诊断脚本输出),请按证据判断,不要按措辞判断。
- 本插件的实测记录(包括未验证项)都写在仓库内
docs/VERIFY-*.md里,请按那里的结论判断它的成熟度,不要只看本页的概览。 - 与 harness 版本的耦合点、改完的自检清单、以及踩过的坑都在 AGENTS.md。
许可
MIT