dsh-self-restart
Manifest validDSH 插件:会话智能体自重启宿主进程,并在重启后向原会话投递一条消息
dsh-self-restart
允许会话智能体重启承载它的 DeepSeek Harness 宿主进程,并在重启完成后于原会话内收到一条消息(默认「已重启」)。
设计说明见 docs/design.md。
能力
- 工具
restart_self:由会话智能体调用,写入重启标记,等待当前轮结束并刷盘后替换进程。 - 命令
/restart:由人直接触发,出现在输入框的命令菜单中,不经模型;命令名之后的文本即投递文本。 - 常驻提示段:把「何时该用」写进系统提示,使模型在「重启 dsh / 让改动生效」这类请求下主动选择该工具,而不仅依赖 schema 被偶然读到。
- 进程替换:分离式 helper 等待端口释放,以完全相同的命令行拉起替换进程;日志写入系统临时目录。
- 续跑投递:浏览器端在宿主恢复后,把标记中的消息作为一条用户消息送回原会话。
- 其它活动会话续跑:重启时仍
running的其它顶层会话各收到一条提示,说明宿主重启过、本轮可能被中断、请从未完成处继续(notifyActive可关闭)。
智能体如何知道有这个工具
三层,缺一都会退化成「偶然才用」:
- 目录:
ctx.tools.register让restart_self进入该 Agent 的工具目录,随每次模型请求下发名称、描述与参数。 - 提示:
ctx.systemPrompt.section注入常驻提示段,写明触发条件与「调用后不必再叮嘱重启」。 - 命令:
/restart给人用;输入框输入/即可看到。
注意:若会话使用「首轮工具收窄」的预设(例如 liangshen),新会话的第一个请求只暴露 bootstrap 工具,restart_self 会在第一次工具调用之后才出现于目录中;这属于预设行为,不是插件缺注册。
配置
插件行 config 支持下列键(缺省值见括号):
| 键 | 类型 | 说明 |
|---|---|---|
allowRestart | boolean(true) | 为 false 时工具直接失败 |
message | string(已重启) | 默认投递文本 |
maxAgeMs | 正整数(600000) | 标记有效期 |
readyDelayMs | 非负整数(1500) | 刷盘后到终止自身的等待 |
idleTimeoutMs | 正整数(15000) | 等待智能体静默的上限 |
port | 正整数或 null(null) | 覆盖端口;缺省取 Web 载体实际端口 |
markerDir | string('') | 覆盖标记目录;缺省 <DSH_HOME>/self-restart |
dryRun | boolean(false) | 只写标记,不替换进程;用于自检与演练 |
notifyActive | boolean(true) | 是否为重启时仍在工作的其它会话各留一条续跑提示 |
resumeMessage | string(见源码) | 发给那些会话的提示文本 |
安装
# 1. 目录联接:把插件检出目录接到 profile 的 @local 作用域(与既有 @local 插件同形)
New-Item -ItemType Junction `
-Path "$env:USERPROFILE\.dsh\profiles\web\node_modules\@local\dsh-self-restart" `
-Target "<CHECKOUT>"
# 2. profile 清单:dependencies 增加 "link:<CHECKOUT>",
# dsh.profile.bundles 追加 "@instpe/dsh-self-restart"
# 3. 重启一次宿主
其中 <CHECKOUT> 指本仓库的本地检出路径,例如 link:C:/src/dsh-self-restart。
不使用 cordis.patch.yml 直接插入:插件自带装载行,重复插入会产生同 id 双行。
使用
两种触发方式,效果相同:
/restart # 人:输入框直接执行,投递默认文本「已重启」
/restart 环境已就绪 # 人:命令名之后的文本即投递文本
restart_self({ message: "已重启" }) # 模型:由智能体调用
两条路径都是「先安排、后发生」:调用当即返回,此刻尚未重启。工具返回值里 restarted 恒为 false,并用 timing 说明随后的等待:
{
"ok": true,
"restarted": false,
"pid": 20532,
"sessionId": "session-…",
"deliverAfterRestart": "已重启",
"timing": { "afterTurnMs": 1500, "idleTimeoutMs": 15000, "portWaitMs": 30000 },
"note": "尚未重启。进程会在本轮回复结束、会话刷盘后被替换……",
"logPath": "…\\Temp\\dsh-self-restart-….err.log"
}
restarted: false 是刻意留的:只有它能让模型不把「已排程」说成「已重启」。本轮回复可能在替换时被截断,属正常;浏览器重连后,原会话收到 deliverAfterRestart 并产生一轮回复。
重启时仍在运行的其它顶层会话也各收到一条续跑提示(默认文案见源码 resumeMessage),由同一条投递通道送出,所以被切断的工作会自己接上。判定口径:只取根会话、只取 running、排除发起者、每会话一条、上限 20 条、临动手前取快照。
验证
node test/smoke.mjs
自检覆盖配置校验、启动命令行重建、工具/命令/提示段/路由注册、标记存储与接口契约(含写入者隔离),以及真实拉起一个替换子进程。第 4 项会把返回值键集合与 output.schema.required 逐字比对——只断言「字段存在」抓不到「schema 已改、execute 还返回旧字段」这种半途状态。
查看运行中的注册情况(宿主 Inspect):Tool.listTools 应含 restart_self;/api/commands/list 应含 restart。
改动本插件时的注意:宿主会热重载被 watch 的插件文件。若一次改动拆成多次保存,watcher 可能在中间态重载,得到一个「新 schema + 旧 execute」的混合定义,表现为调用时报
missing required property "value.…"。改完一组相关编辑后重启一次宿主再验收,或一次保存整块。
投递语义
标记带写入者 pid,GET /api/pending 只返回非当前进程写入的条目。因此在重启发生前,前端看不到这条标记,不会把消息投进仍在运行的旧 agent 的队列;只有替换进程启动后条目才可见,此时会话处于冷态,投递会正常开启一轮。若一次重启并未真的发生(例如 dryRun,或 helper 引导失败),这条消息就不投递——因为「已重启」只有在确实重启后才成立。
已知局限
- 无恢复页面:替换进程引导失败时只有日志,需手工重新执行
dsh web。 - 投递依赖浏览器在线:无界面宿主下标记会在有效期后失效。
- 多标签页并发投递为弱一致去重,极端竞态最多重复一条消息。
Comments
Loading…
Similar plugins
by Fyue7
给 DSH 会话头部加一颗重启按钮:完全退出并把新实例拉回来,全程零窗口。非官方插件。
★ 0
JavaScript
Oct 10, 2026
dsh plugin --profile web add dsh-restart-buttonDSH 桌面端(Windows)重启插件:从侧边栏按钮或默认关闭的模型工具重启宿主,重启后按会话原有预设自动唤醒;宿主繁忙时拒绝重启。
★ 0
dsh plugin --profile web add dsh-desktop-auto-restartby Erick0412-dev
DSH 重启插件:可配置的重启方式(Node 原生 / 旧 PowerShell 适配)与重启后自动继续提示。
★ 0
MIT
JavaScript
Oct 14, 2026
dsh plugin --profile web add @erick0412-dev/dsh-restartby Towzai
DSH 应用内整体重启插件
★ 0
JavaScript
Aug 16, 2026
dsh plugin --profile web add dsh-restartby omdsh-dev
DSH 一键复活:重启后给所有被打断的会话自动发送「继续」指令(/revive 命令 + revive_sessions 工具 + 浏览器一键按钮)
★ 3
BSD-3-Clause
TypeScript
Aug 19, 2026
dsh plugin --profile web add dsh-reviveby suzuran520yyz
DSH Web GUI 插件,用于对会话消息进行编辑、重试、高级重试和删除等功能的实现
★ 0
MIT
JavaScript
Sep 3, 2026
dsh plugin --profile web add dsh-more-message-actions