ventisyn/dsh-agent-control ↗★ 1

dsh-agent-control

DeepSeek Harness 插件:把「删除一个会话」与「从模型上下文中删除一轮对话」这两件破坏性操作收进一个插件,用同一套确认与失败语义管理。 适合需要删除闲置会话或移除单轮模型上下文的用户;单轮删除仍保留日志与附件。

パッケージ
dsh-agent-control
互換性
未検証
バージョン
0.2.0-rc.2-v1.0.0
ライセンス
MIT
最終更新
2026/10/04

インストール

$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,可能被别的会话引用)
  • 删除一轮对话:从模型可见的上下文里移除一轮已结束的对话(问题、回复与该轮的工具记录),会话本身、之后的轮次与日志都保留
    • 做法与 DSH 自己的手动压缩同形:一笔独立压缩事务把那一轮的可见区间换成一句「这里原有一轮对话,已被用户删除」的提示,模型从此看不到原内容。只能在会话空闲时删(有一轮正在进行或正在压缩时会拒绝)。
    • ⚠️ v1.0.0 的旧写法(空的 system/message 墓碑)会让会话重启后打不开,已不再使用。

本插件只使用 DSH 的公开 API:不依赖内核的私有结构,也不照抄任何第三方插件的实现。这一点是刻意的——依赖私有结构的写法换一个 harness 版本就会静默失效(详见 AGENTS.md 第 4 节)。

两者的区别(最要紧的一条)

删除会话删除一轮
磁盘日志永久删除保留(日志是 append-only,不改写、不截断)
模型上下文会话整个消失那一轮不再进入上下文
附件随会话目录一起删不会清理(见下方「已知限制」)
可恢复❌ 不可恢复❌ 但内容仍在日志里

⚠️ 删除一轮不是安全删除。 它通过在日志末尾追加一笔压缩事务、把那一轮从模型可见面上替换掉来实现。被删内容仍然完整留在会话日志与附件存储里,只是不再进入模型上下文。任何「删了就没人能看到」的理解都是错的。

界面

  • 会话行「…」菜单 → 「删除会话…」(侧栏)
  • 每条已结束的回复旁 → 垃圾桶按钮(会话运行中时禁用)
  • 两者都会弹出同一个确认框,必须勾选确认才能点「删除」
  • 删掉的那一轮会在界面上被隐藏,让界面与模型看到的保持一致

已知限制

  • 不能删除仍处于活动状态的会话。DSH 没有公开的「把会话从内存 store 摘除」的 API(能摘除的 disposer 只交给会话的创建者),所以对一个活着的会话强删磁盘,只会留下「目录没了但会话还在列表里」的半删除状态。插件选择拒绝,而不是制造一个说不清的状态。
    • ⚠️ 切换到别的会话并不会让它下线:Web 端打开过的会话会一直驻留在内存里,直到 dsh web 退出。所以要删一个本次启动后打开过的会话,只能重启 dsh 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