🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话与轮次删除 ventisyn/dsh-agent-control

DeepSeek Harness
ventisyn15 天前有提交已提供中文文档扫描:含敏感能力

DSH 整合插件,包含功能:删除会话,删除单独一轮对话,重启及关闭实例

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ventisyn/dsh-agent-control
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · chat
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-agent-control(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 09:38:10

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 24 处,展示前 23 条)
  • 发起网络请求
    client.js:862
    return await fetch(url, { method: 'GET', cache: 'no-store', signal: controller.signal })
  • 发起网络请求
    client.js:898
    const response = await fetch(url, options)
  • 读取本地文件
    src/session-delete.mjs:49
    if (names.length === 0 || !existsSync(sessionsRoot)) return []
  • 读取本地文件
    src/session-delete.mjs:53
    slugs = readdirSync(sessionsRoot, { withFileTypes: true })
  • 删除本地文件递归
    src/session-delete.mjs:81
    rmSync(dir, { recursive: true, force: true })
  • 读取本地文件
    src/session-delete.mjs:439
    file = readdirSync(dir).find((name) => /^session\..*\.jsonl\.zstd$/.test(name))
  • 读取本地文件
    src/session-delete.mjs:606
    if (!existsSync(sessionsRoot)) return []
  • 读取本地文件
    src/session-delete.mjs:609
    slugs = readdirSync(sessionsRoot, { withFileTypes: true })
  • 读取本地文件
    src/session-delete.mjs:620
    entries = readdirSync(slugDir, { withFileTypes: true })
  • 读取本地文件
    src/restart.mjs:436
    text = readFileSync(file, 'utf8')
  • 写入本地文件
    src/restart.mjs:475
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/restart.mjs:485
    renameSync(temp, file)
  • 删除本地文件
    src/restart.mjs:495
    rmSync(temp, { force: true })
  • 读取本地文件
    src/restart.mjs:512
    const existed = existsSync(file)
  • 删除本地文件
    src/restart.mjs:514
    rmSync(file, { force: true })
  • 读取本地文件
    src/restart-tool.mjs:284
    const parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 读取本地文件
    src/restart-tool.mjs:365
    if (deps.helperPath === '' || !existsSync(deps.helperPath)) {
  • 发起网络请求
    src/restart-tool.mjs:536
    outcome = await approval.request({
  • 读取本地文件
    src/restart-tool.mjs:1204
    stat = statSync(file)
  • 写入本地文件
    src/restart-helper.mjs:116
    appendFileSync(helperLog, `[${new Date().toISOString()}] ${line}\n`, 'utf8')
  • 读取本地文件
    src/restart-helper.mjs:534
    const raw = JSON.parse(readFileSync(specPath, 'utf8'))
  • 删除本地文件
    src/restart-helper.mjs:683
    unlinkSync(specPath)
  • 删除本地文件
    src/restart-helper.mjs:692
    unlinkSync(path.join(dir, 'pending.json'))
扫描于 2026/10/31(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 删除会话
  • 删除单轮对话
  • 重启及关闭实例

DeepSeek Harness 插件:一套确认流程、一组失败码,删除会话或单轮对话

README

由 DeepSeek 最新模型翻译生成
dsh-agent-control DeepSeek Harness(DSH)插件:把三件会改变实例现状的破坏性操作——删除会话、删除一轮对话、重启或关闭进程——收进一个插件,用同一套确认与失败语义管理。 - 删除会话:把一个会话不留残留地移除——磁盘目录(两种 id 拼写)、工作区记账(含归档/置顶)、投影缓存记录,以及它派生的子代理会话(递归,同样清目录与缓存)。fork 出来的会话是独立对话,不受影响。子代理里只要有一个还驻留在内存里,整次删除都会拒绝、什么都不动 - 插件不碰的:别的插件自己存的数据(例如审批类插件的事件记录里可能提到这个会话 id)、按内容寻址共享的附件($DSH_HOME/attachments,可能被别的会话引用) - 删除一轮对话:从模型可见的上下文里移除一轮已结束的对话(问题、回复与该轮的工具记录),会话本身、之后的轮次与日志都保留 - 做法与 DSH 自己的手动压缩同形:一笔独立压缩事务把那一轮的可见区间换成一句「这里原有一轮对话,已被用户删除」的提示,模型从此看不到原内容。只能在会话空闲时删(有一轮正在进行或正在压缩时会拒绝)。 - ⚠️ v1.0.0 的旧写法(空的 system/message 墓碑)会让会话重启后打不开,已不再使用。
展开完整文档(README 剩余 1 节)
dsh-agent-control

DeepSeek Harness(DSH)插件:把三件会改变实例现状的破坏性操作——删除会话、删除一轮对话、重启或关闭进程——收进一个插件,用同一套确认与失败语义管理。

- 删除会话:把一个会话不留残留地移除——磁盘目录(两种 id 拼写)、工作区记账(含归档/置顶)、投影缓存记录,以及它派生的子代理会话(递归,同样清目录与缓存)。fork 出来的会话是独立对话,不受影响。子代理里只要有一个还驻留在内存里,整次删除都会拒绝、什么都不动
- 插件不碰的:别的插件自己存的数据(例如审批类插件的事件记录里可能提到这个会话 id)、按内容寻址共享的附件($DSH_HOME/attachments,可能被别的会话引用)
- 删除一轮对话:从模型可见的上下文里移除一轮已结束的对话(问题、回复与该轮的工具记录),会话本身、之后的轮次与日志都保留
- 做法与 DSH 自己的手动压缩同形:一笔独立压缩事务把那一轮的可见区间换成一句「这里原有一轮对话,已被用户删除」的提示,模型从此看不到原内容。只能在会话空闲时删(有一轮正在进行或正在压缩时会拒绝)。
- ⚠️ v1.0.0 的旧写法(空的 system/message 墓碑)会让会话重启后打不开,已不再使用。
- 热重启:把「DSH 进程重启」这件事也收进同一个插件——模型可以调用 restart_harness(必须说明原因)让需要重启才生效的改动(例如宿主插件代码)落地,重启后这个会话自动继续;用户也可以在设置页点按钮重启。见下方「热重启」一节。

插件列表里四行、可以逐个开关(core + 会话 / 轮次 / 热重启三个组件):关掉哪一行,那一个组件就真的下线——路由消失、界面入口随之消失。见下方「组件开关」。

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

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

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

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

界面

- 会话行「…」菜单 → 「删除会话…」(侧栏)
- 每条已结束的回复旁 → 垃圾桶按钮(会话运行中时禁用)
- 两者都会弹出同一个确认框,必须勾选确认才能点「删除」
- 删掉的那一轮会在界面上被隐藏,让界面与模型看到的保持一致
- 设置 → Agent 控制 → 运行状态、阻塞提示、「重启 DSH」按钮与「最近一次重启」卡片,外加一个「关闭实例」按钮(见下)

组件开关

本插件在插件列表里是四行(一行 core + 三个组件行),每一行都可以单独关掉。关掉之后那个组件在本进程里根本不存在:路由消失、界面上的入口也跟着消失——不是「按钮还在、点了报错」。

| 行 | 负责什么 |
| dsh-agent-control(core) | 客户端 bundle 的交付、启动时清理孤儿归档标记,以及「按行构建各功能」的接线。它本身不含删除或重启能力 |
| dsh-agent-control/session(会话) | 会话列表、删除会话(含只剩记账的「幽灵会话」清理),以及客户端判断这个组件在不在的只读探针 |
| dsh-agent-control/turn(轮次) | 某个会话里已删轮次的列表、删除一轮,以及只读探针 |
| dsh-agent-control/restart(热重启) | 重启状态 / 重启 / 关闭实例三条路由、模型工具 restart_harness、重启后的「续作投递」 |

怎么关:插件列表里本插件那一组「包含的组件」右侧的开关。关掉是一次 profile 写入(宿主把那一行标成 disabled),重启实例后生效——host 端的接线只在进程启动时装配。

开关分两级:第一行是总闸(插件本体)。关掉它,另外三个组件拿不到本体提供的服务,会停在未运行状态,一个接口都不会注册——界面也会跟着消失(客户端界面也由本体交付)。
本体开着时,三个组件可以各自独立开关。

关掉之后的实际影响:

- 路由真的不见了:被关掉的组件那几条路由(含只读探针)在进程里根本不存在,请求会落到 404 或宿主的鉴权 fallback。GET /api/agent-control/sessions 这类探针可以直接用来确认。
- 界面入口跟着消失:客户端在挂载时先探测这几个组件(GET /api/agent-control/session/status、 .../turn/status、.../restart/status,都是只读、不带参数、不改变状态的接口),探不到就不注册对应的槽位——会话行菜单里的删除项、回复旁的垃圾桶、已删轮次的隐藏标记、设置页那一节、重启/关闭横幅与确认框。
判据是「先探测、后注册」(已经注册的槽位无法在运行中卸载),探测失败或超时的方向是少显示 (模型侧本来也有 host 闸门,少显示只是界面滞后)。
- 旧配置不受影响:如果某个组件行从来不存在(例如只有一行 agent-control 的老配置),core 会把三个组件全装上,行为与从前完全一致。
- 关掉不删数据、也不改变已知残留:插件自己不落任何数据文件;会话删除在内存 store 里那条记录(已知残留,见「已知限制」)仍然要等进程退出才消失——关掉组件既不会撤销已经发生的删除,也不会顺手清残留。
- 关掉「热重启」= 重启与关闭都下线:restart_harness 工具、设置页那一节、界面上的重启按钮与 关闭实例按钮属于同一个组件,要留着它们就别关这一行。
- 关掉一个组件不会让实例起不来(刻意的:配置写错一个词的代价不该是打不开)。

热重启与关闭实例

模型可以在需要时重启宿主进程(例如它刚改了本插件的 host 端代码,而 host 模块不会热加载)。重启在本轮结束后执行,这个会话随后自动继续——模型会收到一条「DSH 已热重启」的通知,里面带着它自己写下的原因与续作说明。

- 两个入口,同一套护栏:模型工具 restart_harness({ reason, resume_note? }) 与设置页的「重启 DSH」按钮走的是同一条路径(requestRestart)。
- 模型发起时默认要过审批:审批卡片里显示模型给的原因;被拒就什么都不做。可以在插件行配置里把 approval 设成 auto 免审批(仍受限频与阻塞项约束)。
- 有别的会话在跑、或有后台任务在跑时会拒绝,并告诉模型「等哪个会话结束」。这是刻意的:重启会中断那些任务。
- ⚠️ 已知限制:宿主的作业列表按所有者隔离,插件看不到别的会话启动的后台任务,只能统计无主作业与调用者自己的作业。
- 限频:10 分钟内最多 3 次;同一个会话在 60 秒内再次请求会被拒绝(防模型死循环)。
- 停机时间约 6–10 秒,其中大部分是新进程启动的时间;重启期间页面会短暂不可用(不需要手动刷新,DSH 客户端会自己恢复)。
- 不做配置回滚:如果新进程因为配置或插件错误起不来,插件不会替你改回任何东西——它会如实报告失败,并在设置页给出新进程日志的文件名,剩下的要你自己处理。
- ⚠️ 如果你的实例是由桌面启动器(DSHL)拉起的:实测(v1.1.0)重启本身能成功,辅助进程也不会被杀,但启动器认不出重启后的新进程——它会从启动器的列表里消失,变成一个它管不到的孤儿进程(还活着、还在服务)。
- 原因:启动器按它自己 spawn 的那个子进程 PID 认实例(就绪判定读的是子进程 stdout 里的登录横幅),进程一退出它就记「已退出」;它只在自己启动时做一次「核验并恢复监控」,判据仍是那个进程的身份,所以新 PID 不会被认领。
- 后果与处置:启动器里看不到、也停不掉它(要从任务管理器结束进程);也别对同一个 profile 再点一次「启动」,那会变成两个实例争同一个端口。要恢复管理,只能先手动结束那个进程,再从启动器启动。
- 这条本插件修不了:需要启动器提供重启接口,而本插件按设计不依赖、也不改写启动器的私有状态(那套记录是它的私有格式,靠它等于把插件绑死在一个第三方实现上)。
- ⚠️ 端口暴露的风险同样适用:POST /api/agent-control/restart 走的是插件自建路由(没有 harness 鉴权),所以它额外做了 Origin/自定义头校验,避免被网页 CSRF。但如果你的 webServer 绑在 0.0.0.0 上,等于把「重启我的实例」暴露给整个网络——不要这么部署。

关闭实例

设置页同一页里还有一个「关闭 DSH」按钮:干净地停掉整个实例(ctx.appExit(0),与直接关窗口等价)。

- 它存在的理由:实例被启动器失去跟踪之后(见上面那条),启动器里既看不到也停不掉它——这个按钮就是那种情况下唯一的收尾入口。当然,任何时候都能用它停实例。
- 只有界面能触发:插件不提供对应的模型工具。关掉实例会让所有会话与后台任务一起中断,而且不会自动重启(不像热重启会续作),所以这个决定只能由人来做。
- 必须勾选确认,弹窗里会列出当前有几个会话 / 后台任务会被中断,并写明「不会自动重启」。
- 行为:接口先回 202(已接受这次关闭请求),然后进程退出;界面显示「DSH 正在关闭…」,随后是「实例已关闭,可以关掉这个页面」。要再用它,得从启动器或终端重新启动。
- 不会写坏日志:退出前会尽力把每个会话已经记录的事件刷到盘上(每个会话最多等 500 毫秒,刷不动也照常退出)。如果关的时候正好有一轮在跑,那一轮在日志里会是「未闭合」,打开会话时由 DSH 内核按「被中断」补齐——这正是关窗口/崩溃时的同一套恢复路径,不是损坏。
- 与热重启互斥:任一流程进行中时另一个按钮是禁用的。关闭不等正在跑的任务结束(它就是要立刻停),这一点与热重启刻意不同。

已知限制

- 打开过的会话也能删(0.2.1-alpha.2-v1.2.0 起)。DSH 仍然没有把会话从内存 store 摘除的公开接口,但实测(0.2.1-alpha.2)活会话的磁盘目录删得掉、也不会被写回来,于是插件改成:先停掉 agent,再照常删目录、工作区记账与投影缓存;如果删的正是界面上正在看的那个会话,界面会切到同一工作区里的另一个会话。
- 残留只有一处、并且说清楚:内存里那条 store 记录会留到进程退出(它不再对应任何磁盘数据,也不会再被界面打开);接口响应里用 wasLive: true 如实标注。
- 删除一轮不清理附件:内核当前没有公开的附件清理接口。被删轮次里的图片/文件仍留在 $DSH_HOME/attachments。
- 已压缩的轮次可能无法单独删除:如果那一轮与其它内容共用了一个压缩后的可见节点,或它的可见节点不再连续,插件会拒绝并说明原因,而不是删掉一半。
- HTTP 接口没有 harness 鉴权:插件自建的路由不走 harness 的鉴权链路。会改变状态的 POST 路由(删除会话、删除轮次、重启、关闭)自己做了可信校验(优先用宿主的 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 <配置档名> 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 进程,也不碰真实配置档

设计与取舍、与 DSH 版本的耦合点、改完的自检清单都在 AGENTS.md;路由与事件细则在 docs/CONTRACT.md,已经踩过的坑在 docs/PITFALLS.md。

说明

- 非官方:这是第三方插件,与 DeepSeek 官方没有隶属或背书关系;文中出现的 DeepSeek、DeepSeek Harness、DSH 等名称仅用于说明它在什么环境里运行。
- 主要由 AI 编码代理编写:代码、测试与文档都是在与 AI 代理协作下产出的,提交历史里能直接看到。仓库里所有结论都尽量附上可复核的证据(日志、接口响应、诊断脚本输出),请按证据判断,不要按措辞判断。
- 本插件的实测记录(包括未验证项)都写在仓库内 docs/VERIFY-*.md 里,请按那里的结论判断它的成熟度,不要只看本页的概览。
- 细则与坑在 docs/ 下:CONTRACT.md(路由与事件)、PITFALLS.md、RELEASING.md。

许可

MIT
预览分享卡片长什么样 ↓ventisyn/dsh-agent-control
分享 · DeepSeek Harness Hub
ventisyn/dsh-agent-control

DSH 整合插件,包含功能:删除会话,删除单独一轮对话,重启及关闭实例

回到顶部