Towzai
dsh-restart
DSH 应用内整体重启插件
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-restart
DSH 应用内整体重启插件:agent 自主 / 人工触发,忙碌会话协调,失败自动回滚,重启后自动恢复会话并继续任务。
版本:1.0.0 · License: MIT
功能
- 应用内整体重启:进程不退出,重新读取全部配置并重挂插件树
- 插件行添加/移除/修改 → 生效
- 外部插件代码改动 → 生效(自动重载磁盘最新代码)
- 配置变更 → 生效
- 配置错误 / 启动失败 → 自动回滚到上一状态并记录错误(应用不中断)
- agent 自主触发:模型工具
dsh_restart(when, reason)when: 'now':当前轮结束后立即重启when: 'wait':等其它会话空闲后再重启(超时仍重启,超时可配置)
- 人工触发:GUI 侧边栏「🔄 重启」按钮(立即 / 等任务完成)
- 重启后自动恢复:恢复发起会话并注入「继续重启前的任务」,agent 自动继续并向用户汇报
- 模型保持:恢复时使用发起会话的模型,不会串到其它模型
安装
前置条件
- DSH(DeepSeek Harness)web 或 headless profile
- DSH 版本需含 launcher 的
appRestart服务(较新版本内置;如不确定,安装后运行dsh_restart工具,返回ok: true即支持)
方式一:npm 安装(发布后)
dsh plugin --profile <profile名> add dsh-restart
方式二:GitHub 仓库
dsh plugin --profile <profile名> add git+https://github.com/<owner>/dsh-restart.git
方式三:本地路径(开发 / 本机使用)
dsh plugin --profile web add D:\path\to\dsh-restart
手动配置(任意方式安装后可选)
在 profile 的 cordis.patch.yml 中按需覆盖配置:
- id: dsh-restart
name: 'dsh-restart'
config:
waitTimeoutMs: 900000 # when=wait 最大等待 ms(默认 15 分钟)
安装完成后重启一次 DSH:侧边栏出现「🔄 重启」按钮,agent 获得 dsh_restart 工具。
使用
Agent 自主
对 agent 说:
请重启 DSH,等其它会话任务完成后执行,原因:更新插件配置
agent 会调用 dsh_restart({ when: 'wait', reason: '...' });重启完成后本会话自动恢复,agent 继续原任务并向你汇报结果。
人工
侧边栏底部「🔄 重启」→ 立即重启 / 等任务完成后重启。
配置项
| 配置 | 默认 | 说明 |
|---|---|---|
waitTimeoutMs | 900000(15 分钟) | when=wait 的最长等待时间(1000 ~ 24h) |
stateDir | <DSH home>/restart | notice 与诊断日志目录 |
架构
| 组件 | 说明 |
|---|---|
| 插件 Host | 工具注册、重启编排、忙碌协调、通知恢复、HTTP API(lib/index.js) |
| 插件 Client | GUI 侧边栏按钮(lib/client.js) |
appRestart 服务 | 由 DSH launcher 提供(profile-boot.ts),负责重读配置、重载模块、事务性重挂与回滚 |
重启流程:重读全部配置层 → 备份并重载外部插件模块 → 销毁旧树 → 挂新树 → 失败自动回滚。
HTTP API
POST /plugins/dsh-restart/api
{ "method": "restart.request", "args": { "when": "now", "reason": "..." } }
{ "method": "restart.status", "args": {} }
故障排查
| 症状 | 处理 |
|---|---|
| 重启后没有收到恢复通知 | 检查 <stateDir>/notices.jsonl 是否有 pending 记录;重启后应被消费清空 |
恢复轮报 has no provider/model | 确认 notices.jsonl 中该条 notice 带 provider/model 字段(发起时写入) |
| GUI 看不到注入消息 | 刷新页面 / 重开会话 |
| 重启后插件代码未更新 | 仅外部插件支持热更;核心包(@deepseek-ai/*)需进程级重启 |
踩坑记录
详细修复链见 docs/2026-08-16-fixes-postmortem.md(5 个根因 + 验证矩阵)。
| 坑 | 现象 | 解法 |
|---|---|---|
| 通知轮缺模型 | 恢复会话报 has no provider/model | notice 携带发起时的 provider/model,resume 显式传入 |
| notice 误删 | 重启后用户没收到注入 | notice 改用唯一 id,dropNotices 按 id 过滤而非 sessionId |
| 缓存清理失效 | 重启后插件仍运行旧代码 | 模块 URL 做 realpathSync 归一化,匹配 Node ESM loadCache 键 |
| 核心包重载崩溃 | Duplicate type name 'STARTUPINFOW' | 应用内重启跳过 @deepseek-ai/* 核心包(koffi 等非幂等) |
| 重写文件漏函数 | 重启静默失败无报错 | 重写后必须 diff 验证;restartApp 增加 trace 日志 |
边界认知:
- 应用内重启 = 外部插件 + 配置变更
- 核心包代码改动 = 进程级重启
- GUI 视图需手动刷新
开发
npm pack # 构建发布包(产物 .tgz,清单见 package.json files)
Changelog
见 CHANGELOG.md。