前言¶
在 DeepSeek Harness(DSH)里改宿主插件、cordis.patch.yml 或依赖包后,往往必须重启进程新代码才会被加载。Cordis 按 URL 缓存已 import 的模块,lib/*.js 这类改动尤其绕不开一次重启。问题是:手动杀进程再拉起会掐断正在进行的对话,用户还要重新交代上下文。
常见做法是关窗口、刷新页面或自己写脚本拉进程,但会话恢复和续接消息通常要另做一套。下面介绍社区插件 dsh-host-restart(维护者 liuyun847,npm 包名 dsh-host-restart,当前 v0.8.0,MIT 许可证):在宿主侧注册模型工具 restart_dsh 与人工指令 /restart,把「杀当前实例 → 拉起新进程 → 恢复发起会话并注入固定续接句」合成一步。
这是什么¶
dsh-host-restart 是 DSH 宿主插件(分类:工作流),通过 cordis.patch.yml 向宿主注册工具与命令。它不做业务逻辑扩展,只解决「重启后接着聊」:重启前可选调用同 profile 下 dsh-host-sl 提供的 slHandoff.saveAll 刷新 SL 工作表;重启后由 sessionController.resolveAgent 挂回发起会话,并注入固定文案 dsh已重启,继续(v0.5.0 起工具无参数、文案不可配)。
实现上依赖 Windows 上的 PowerShell 驱动脚本 dsh-restart.ps1(WMI 脱离 dsh 进程树启动),README 中的时序与排障均以 Windows + web 或 Electron 桌面宿主 为准。社区目录 SkillHub 标注该插件可安装;SkillHub 为社区站点,与 DeepSeek / 幻方无官方从属关系。DSH 生态本身是「一切皆插件」,安装前建议在 GitHub 阅读源码与许可证,并理解插件以 当前 dsh 进程权限 执行重启与写盘操作。
核心功能¶
两条入口,同一套流程¶
v0.7.0 起除模型工具外,用户还可在输入框直接敲 /restart。两条入口共用执行体 performRestart(会话校验 → 活动检测 → 交接保存 → 写标记 → 起驱动脚本),差别仅在于失败/成功文案前缀。/restart 走官方 commands 服务注册;若服务缺席,只记日志,不影响 restart_dsh 工具。
模型侧调用形式为无参工具:
restart_dsh()
工具返回会要求模型 立刻结束本轮输出;整轮重启在 README 实测中约 11 秒(看门狗不在、自行拉起)到 26 秒(看门狗换手),模型侧描述里亦提到约 20–40 秒 量级,需预留等待。
重启前:告知,不拦截¶
v0.4.0 起,检测到其它会话仍有「在飞」活动(本会话本轮在跑、名下子代理在跑、名下后台作业未结算)时 不再拒绝重启,只在日志与工具返回里点名会话 id、原因及交接是否存盘,然后照常执行。代价是:被打断会话里进行中的那一步工具调用无法救回。
重启前:可选 SL 交接(v0.8.0 契约)¶
若已装载 dsh-host-sl,首次调用重启入口时会探测 slHandoff 服务,并调用:
saveAll({ all: true, noteSessionId, session })
服务侧最多刷新约 5 秒,本插件最多等待 7 秒;v0.8.0 会等待提交结果并在返回文案中报告实际会话 ID 与刷新完整度。job-only 会话不入表、不承诺由 SL 恢复;服务缺席、失败或超时 不阻断重启。
重启后:恢复会话与注入¶
插件在新进程 apply 后读 $DSH_HOME/storages/dsh-restart/pending.json,延迟默认 4 秒(bootDelayMs),再恢复 sessionId 对应会话。
若 dsh-host-sl 的待续标记里已有本会话未处理条目,本插件 让位,由对方的【sl 交接续跑】注入(正文开头含「dsh 已重启」);约 10 秒 后兜底复查,若对方未接手且会话仍非 running,再补注入同一句固定文案。无交接记录时直接 followup("dsh已重启,继续")。
web 宿主与 Electron 桌面端(v0.6.0)¶
| 维度 | web 宿主 | Electron 桌面端 |
|---|---|---|
| 杀进程 | 命中本实例的 node + dsh\lib\bin.js |
同一安装路径下 整棵 DeepSeek Harness.exe 进程树 |
| 拉起 | 看门狗换手或脚本自行 node bin.js |
旧进程退干净后冷启动同一 exe |
| 会话续跑 | 与桌面端相同(标记 + resolveAgent + 注入) | 同上 |
桌面端只杀 同一 exe 安装路径 下的实例,避免误伤其它安装。
硬边界(调用会被拒绝或需知悉)¶
- 仅主会话:
session.header.origin === 'subagent'或拿不到会话 id 时拒绝,不写标记、不重启。 - 只杀本实例:驱动脚本身份解析失败(退出码 4)时一个进程都不杀。
- 在飞子代理与后台作业会被硬杀,结果丢失;job-only 会话不会自动恢复。
- 模型工具描述要求:仅当用户明确要求重启时使用。
安装与启用¶
README 未给出单独的 dsh plugin add … 一行命令;安装可走社区目录页(当前展示 v0.8.0、来源 GitHub):
- 目录页:https://www.skillhub.cn/plugins/liuyun847/dsh-host-restart
- 源码与说明:https://github.com/liuyun847/dsh-host-restart
安装完成后,在 DSH Web 侧栏「插件」页 →「已安装」区 打开 dsh-host-restart 卡片总开关(写入 dsh.profile.bundles)。卡片内还有行级开关,可在 profile 的 cordis.patch.yml 里对 restart-dsh 写 disabled: true 覆写。
注意:修改 lib/*.js 后必须再经历一次 dsh 重启才加载新模块;因此 v0.7.0 的 /restart 也要等「下一次重启之后」才可用。包内 cordis.patch.yml 的 config 段可选,例如 bootDelayMs、staleMs、restartScript 等;非法值会 fail loud、不注册工具。
卸载示例(README 回滚流程,<profile> 换成你的 profile 名,如 desktop):
node <工作区>\dsh\dsh-plugin-manager\dshpm.mjs remove dsh-host-restart --profile <profile>
若 pnpm remove 报供应链策略错误,可在 profile 目录执行:
pnpm remove dsh-host-restart --config.minimum-release-age=0
典型用法¶
1. 改完插件代码后让模型重启¶
在对话中明确说明需要重启 DSH 以加载新代码,由模型调用 restart_dsh()。调用成功后模型应停止本轮输出;约十余秒到半分钟内,同一会话应收到续跑消息(固定句或 SL 交接句),无需手动刷新或重述上下文。
2. 用户直接重启¶
在输入框发送:
/restart
行为与工具一致,但不向模型发送「请立刻结束本轮回复」类提示。
3. 与 dsh-host-sl 协同¶
若 profile 中同时启用 dsh-host-sl,重启前会自动尝试 saveAll;重启后若存在未处理的 SL 交接条目,续跑由 SL 插件主导,避免同一轮出现两条冲突的 user 消息。仅装 restart、不装 SL 时,仍走固定 dsh已重启,继续 注入。
4. 本地开发与验证¶
维护者在 README §7 中给出的流程包括:在 profile 的 plugins\dsh-host-restart 下改源码、跑测试、核对硬链接/哈希、再发起一次重启。测试套件在仓库内为:
node --test "test/*.test.mjs"
(README 记录 v0.7.0 时为 131/131 用例全绿。)
适用场景与注意¶
适合谁
- 频繁改 DSH 宿主插件、
cordis.patch.yml或本包自身代码,又不想每次手动杀进程、丢会话的开发者。 - 已在 Windows 上使用 DSH web 或官方 Electron 桌面端,并愿意让模型或
/restart代劳重启的用户。
使用前请确认
- 插件会 终止当前 DSH 实例(桌面端为整应用树),权限与当前用户一致;安装前请阅读 GitHub 仓库 源码与 MIT 许可证。
- 重启窗口内不要依赖未落盘的子代理或后台 job 结果。
- 驱动脚本与日志默认落在工具目录(如
dsh-restart.log、pending.json);web 自起路径会写dsh-last-url.txt(带 token 的 URL,清 cookie 时可取用)。
结尾¶
dsh-host-restart 把 DSH 开发里高频的「重启换代码」和「会话续跑」绑成一步:restart_dsh 与 /restart 共用同一流程,可选衔接 dsh-host-sl 的工作表与交接注入,并区分 web 与桌面两种杀进程/拉起语义。需要安装说明与版本信息可看 SkillHub 目录页;机制细节、配置项与排障以 GitHub README 为准。