dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DeepSeek Harness plugin: delete a session or a single turn through one confirmation flow and one set of failure codes
DeepSeek Harness(DSH)插件:把三件会改变实例现状的破坏性操作——删除会话、删除一轮对话、重启或关闭进程——收进一个插件,用同一套确认与失败语义管理。
$DSH_HOME/attachments,可能被别的会话引用)system/message 墓碑)会让会话重启后打不开,已不再使用。restart_harness(必须说明原因)让需要重启才生效的改动(例如宿主插件代码)落地,重启后这个会话自动继续;用户也可以在设置页点按钮重启。见下方「热重启」一节。插件列表里四行、可以逐个开关(core + 会话 / 轮次 / 热重启三个组件):关掉哪一行,那一个组件 就真的下线——路由消失、界面入口随之消失。见下方「组件开关」。
本插件只使用 DSH 的公开 API:不依赖内核的私有结构,也不照抄任何第三方插件的实现。这一点是刻意的——依赖私有结构的写法换一个 harness 版本就会静默失效(详见 AGENTS.md 第 4 节)。
| 删除会话 | 删除一轮 | |
|---|---|---|
| 磁盘日志 | 永久删除 | 保留(日志是 append-only,不改写、不截断) |
| 模型上下文 | 会话整个消失 | 那一轮不再进入上下文 |
| 附件 | 随会话目录一起删 | 不会清理(见下方「已知限制」) |
| 可恢复 | ❌ 不可恢复 | ❌ 但内容仍在日志里 |
⚠️ 删除一轮不是安全删除。 它通过在日志末尾追加一笔压缩事务、把那一轮从模型可见面上替换掉来实现。被删内容仍然完整留在会话日志与附件存储里,只是不再进入模型上下文。任何「删了就没人能看到」的理解都是错的。
本插件在插件列表里是四行(一行 core + 三个组件行),每一行都可以单独关掉。关掉之后那个组件 在本进程里根本不存在:路由消失、界面上的入口也跟着消失——不是「按钮还在、点了报错」。
| 行 | 负责什么 |
|---|---|
dsh-agent-control(core) | 客户端 bundle 的交付、启动时清理孤儿归档标记,以及「按行构建各功能」的接线。它本身不含删除或重启能力 |
dsh-agent-control/session(会话) | 会话列表、删除会话(含只剩记账的「幽灵会话」清理),以及客户端判断这个组件在不在的只读探针 |
dsh-agent-control/turn(轮次) | 某个会话里已删轮次的列表、删除一轮,以及只读探针 |
dsh-agent-control/restart(热重启) | 重启状态 / 重启 / 关闭实例三条路由、模型工具 restart_harness、重启后的「续作投递」 |
怎么关:插件列表里本插件那一组「包含的组件」右侧的开关。关掉是一次 profile 写入 (宿主把那一行标成 disabled),重启实例后生效——host 端的接线只在进程启动时装配。
开关分两级:第一行是总闸(插件本体)。关掉它,另外三个组件拿不到本体提供的服务, 会停在未运行状态,一个接口都不会注册——界面也会跟着消失(客户端界面也由本体交付)。 本体开着时,三个组件可以各自独立开关。
关掉之后的实际影响:
GET /api/agent-control/sessions 这类探针可以直接用来确认。GET /api/agent-control/session/status、
.../turn/status、.../restart/status,都是只读、不带参数、不改变状态的接口),探不到就不注册
对应的槽位——会话行菜单里的删除项、回复旁的垃圾桶、已删轮次的隐藏标记、设置页那一节、重启/关闭横幅与确认框。
判据是「先探测、后注册」(已经注册的槽位无法在运行中卸载),探测失败或超时的方向是少显示
(模型侧本来也有 host 闸门,少显示只是界面滞后)。agent-control 的老配置),core 会把
三个组件全装上,行为与从前完全一致。restart_harness 工具、设置页那一节、界面上的重启按钮与
关闭实例按钮属于同一个组件,要留着它们就别关这一行。模型可以在需要的时候重启宿主进程(例如它刚改了本插件的 host 端代码,而 host 模块不会热加载),重启在本轮结束后执行,这个会话随后自动继续——模型会收到一条「DSH 已热重启」的通知,里面带着它自己写下的原因与续作说明。
restart_harness({ reason, resume_note? }) 与设置页的「重启 DSH」按钮走的是同一条路径(requestRestart)。approval 设成 auto 免审批(仍受限频与阻塞项约束)。POST /api/agent-control/restart 走的是插件自建路由(没有 harness 鉴权),所以它额外做了 Origin/自定义头校验,避免被网页 CSRF。但如果你的 webServer 绑在 0.0.0.0 上,等于把「重启我的实例」暴露给整个网络——不要这么部署。设置页同一页里还有一个「关闭 DSH」按钮:干净地停掉整个实例(ctx.appExit(0),与直接关窗口等价)。
202(已接受这次关闭请求),然后进程退出;界面显示「DSH 正在关闭…」,随后是「实例已关闭,可以关掉这个页面」。要再用它,得从启动器或终端重新启动。0.2.1-alpha.2-v1.2.0 起)。DSH 仍然没有把会话从内存 store 摘除的公开接口,但实测(0.2.1-alpha.2)活会话的磁盘目录删得掉、也不会被写回来,于是插件改成:先停掉 agent,再照常删目录、工作区记账与投影缓存;如果删的正是界面上正在看的那个会话,界面会切到同一工作区里的另一个会话。
wasLive: true 如实标注。$DSH_HOME/attachments。requestRejection,不可用时靠同源 Origin / 自定义头兜底)并要求 content-type: application/json,别的网页不能跨站触发;但能访问到这个端口的非浏览器调用者带上自定义头仍可能调用。默认只监听回环地址;如果你的 webServer 配置成 0.0.0.0,请自行评估。# 装最新发布版:不写 ref 时取仓库默认分支,本仓库的默认分支始终指向最新发布版本
dsh plugin --profile <profile 名> add github:ventisyn/dsh-agent-control
# 需要钉到某个版本时,把 <完整版本号> 换成版本分支名(也是 Release 标题)
dsh plugin --profile <profile 名> add github:ventisyn/dsh-agent-control#<完整版本号>
# 本地开发(改完重启即生效)
dsh plugin --profile <profile 名> add link:<本地 clone 路径>
⚠️ 如果 profile 里已经装了别的删除类插件,请先移除,否则界面上会出现两套删除按钮——同一批槽位只能有一个主人:
dsh plugin --profile <profile 名> remove <占用了同名槽位的插件>
安装或改动 host 端代码后需要重启 dsh web:已加载的 host 模块不会因为文件改动而重新导入(新增的路由会一直返回 401)。
装好之后:
# 会话列表(同时也是「路由是否注册成功」的探针)
curl http://127.0.0.1:<端口>/api/agent-control/sessions
# 热重启的状态(也是辅助进程判断「新进程起来了没有」的探针)
curl http://127.0.0.1:<端口>/api/agent-control/restart/status
浏览器控制台里:
window.__dshAgentControl.usingNativePrimitives() // 用的是原生原语还是自带兜底
window.__dshAgentControl.id // 注册 id
window.__dshAgentControl.features() // 这次挂载探测到的组件开关:{ session, turn, restart }
// true / false / null(null = 还没探到,按不可用处理)
接口一览:
GET /api/agent-control/session/status { ok: true, enabled: true } ←「会话」组件的只读探针(界面靠它决定注册不注册入口)
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 }
GET /api/agent-control/turn/status 「轮次」组件的只读探针(同上)
GET /api/agent-control/restart/status 热重启的状态(也是新进程的就绪探针,同时是「重启」组件的只读探针)
POST /api/agent-control/restart { reason?, force? } → 202 { ok, restartId }
POST /api/agent-control/shutdown { }(可空体)→ 202 { ok } ← 停掉整个实例,只从界面触发
组件被关掉时,属于它的那几条路由根本不存在(请求落到 404 或宿主的鉴权 fallback),
所以「这个组件在不在」用上面那几条 /status 探针一拉就知道。
失败一律返回 { ok: false, error: { code, message } }。错误码含义:
| 码 | 含义 |
|---|---|
REQUEST_DENIED | 删除请求没通过可信校验(Origin / 自定义头 / 浏览器鉴权),403;宿主鉴权给 401 时照抄 401 |
TARGET_NOT_FOUND | 目标已经不存在 |
TURN_NOT_CLOSED | 那一轮还没结束 |
TURN_COMPACTED | 那一轮已被压缩或不再连续,无法单独删除 |
AGENT_BUSY | 会话的任务没有停下来,已放弃删除 |
DELETE_FAILED | 宿主拒绝了这次删除(消息里带原始原因) |
RESTART_BLOCKED | 别的会话或后台任务在忙(消息里列出是哪些) |
RESTART_IN_PROGRESS | 已经有一次重启在进行中 |
RESTART_RATE_LIMITED | 太频繁(10 分钟 3 次 / 同会话 60 秒冷却) |
RESTART_UNSUPPORTED | 这个部署做不到(取不到启动规格、没有 appExit、辅助脚本缺失…)——不会假装成功 |
RESTART_DENIED | 审批被拒,或这次请求没通过可信校验(Origin / 自定义头) |
RESTART_FORBIDDEN | 子代理发起重启:只有主会话可以重启宿主 |
SHUTDOWN_DENIED | 关闭请求没通过可信校验(Origin / 自定义头 / 浏览器鉴权) |
SHUTDOWN_UNSUPPORTED | 这个部署没有 appExit,插件无法请求退出(请从启动器或终端停止) |
SHUTDOWN_FAILED | 请求宿主退出时抛错(消息里带原始原因)——不会假装已经关掉 |
npm test # 语法检查 + 314 项离线测试,不需要 DSH 进程,也不碰真实 profile
设计与取舍、与 DSH 版本的耦合点、改完的自检清单都在 AGENTS.md; 路由与事件细则在 docs/CONTRACT.md,已经踩过的坑在 docs/PITFALLS.md。
docs/VERIFY-*.md 里,请按那里的结论判断它的成熟度,不要只看本页的概览。docs/ 下:CONTRACT.md(路由与事件)、PITFALLS.md、RELEASING.md。MIT