前言¶
在 DeepSeek Harness(DSH)裏,長時間運行的工作流往往需要中途重啓宿主進程。常見的做法是人在對話裏打字說「繼續」,或者退出命令行,再重新啓動 Harness。這會打斷會話、丟失子代理和待處理的指令,需要重新整理上下文。
dsh-restart-handoff 插件通過一個專用工具 restart_dsh,把「重啓宿主」變成一次計劃內的操作:模型發出重啓請求,宿主寫入交接記錄,然後被另一個進程拉起,繼續之前的會話和子代理,並執行待處理的指令。
是什麼¶
這是 sadkga 維護的一個 DSH 插件,分類爲「工作流」。它讓模型通過 restart_dsh 工具以兩步方式重啓宿主,並把會話、子代理和指令交給新進程繼續。插件以 Node 24 運行,需要宿主由一個 Restart=always 的 systemd 單元監管。
核心功能¶
計劃內重啓:兩步調用¶
- 警告調用。 模型調用
restart_dsh,工具返回一份警告,包括原因、將重放的指令、將恢復的會話,以及一個確認令牌。這一步不執行任何重啓。 - 確認調用。 模型帶着令牌再次調用
restart_dsh,令牌匹配時,工具寫入交接記錄到$DSH_HOME/restart/handoff.json,記錄當前正在跑的會話、原因、待重放的指令(continuePrompt)和可繼續的子代理。工具等待當前輪次變空閒後,向宿主進程發送SIGTERM,由Restart=always的單元拉起新進程。 - 重放。 新進程讀取交接記錄,執行恢復:
- 恢復重啓發生時正在跑的每一個會話,並注入「請繼續」指令;
- 自上而下地喚起可繼續的子代理,保證子會話只在它自己的父會話活着時才被投遞;
- 把continuePrompt交給發起重啓的那個會話;
- 對齊 Agent Team 名冊並喚起其中的隊友。
非計劃重啓:自動恢復¶
非計劃退出(崩潰、被殺、斷電)不會留下交接記錄。插件會在下次啓動時掃描持久化的會話,把「最後一輪被打斷」的那些帶回來,以及「收件箱裏還排着沒開始過的提示」的那些。
恢復判據基於最後一個 turn/end 的 reason,以及是否還有工作在等它:
最後一個 turn/end 的 reason |
恢復? |
|---|---|
interrupted |
是 |
aborted + disposed |
是 |
aborted + user |
否 |
completed |
否 |
error |
否 |
此外,與 reason 無關地,收件箱裏還排着一個從未開始的提示的會話也會被恢復。
圍欄:防止模型直接執行重啓¶
插件把重啓暴露爲一個工具,並看守會執行命令的工具。命令行風格的「重啓 Harness」操作會被拒絕,並給出指向 restart_dsh 的提示。圍欄按 shell 分隔符切分文本,剝掉包裝層(sudo、env、nohup 等),看每一段的「首個動詞」是否衝着宿主,從而攔截對宿主進程的 kill 信號。
保真:會話回來時還是它自己¶
恢復的會話保留自己的 provider、模型、思考強度和 agent preset,全部從會話日誌讀取,而不是使用部署默認值。
恢復性能¶
掃描在每次啓動時都會跑。通過文件 mtime 預篩、只讀日誌尾部、以及向忙碌的 Agent 投遞時不空等,掃描時間可從全量讀的約 97 秒降到約 13 秒,其中日誌讀取僅約 14 毫秒。
安裝與啓用¶
用 Harness 插件 CLI 裝進某個 profile:
dsh plugin --profile web add dsh-restart-handoff
從 GitHub 裝(不需要 npm 賬號):
dsh plugin --profile web add github:sadkga/dsh-restart-handoff
鎖定某個標籤:
dsh plugin --profile web add github:sadkga/dsh-restart-handoff#v0.2.1
安裝後重啓宿主,插件的客戶端元數據與加載器會被緩存。
插件需要 Node 24(engines.node)。
配置¶
在 cordis.patch.yml 中可以覆蓋默認配置:
- insert:
- id: restart-handoff
name: 'dsh-restart-handoff'
config:
serviceUnit: 'dsh.service'
autoResume: true
resumeSubagents: true
idleTimeoutMs: 30000
常用配置項包括:
serviceUnit:監管該進程的 systemd user 單元(默認dsh.service)。handoffDir:交接記錄寫入的位置(默認$DSH_HOME/restart)。autoResume:下次啓動時重放交接記錄(默認true)。resumeSubagents:恢復後喚起可繼續的子代理(默認true)。resumeRunningSessions:同時恢復其它正在跑或排着活的會話(默認true)。pendingTtlMs:確認令牌的過期時間(默認300000毫秒)。handoffTtlMs:交接記錄的陳舊時間(默認1800000毫秒)。recoverInterruptedSessions:恢復非計劃退出留下的會話(默認true)。recoverMaxAgeMs:被打斷的會話最大年齡(默認7200000毫秒)。recoverMaxSessions:一次啓動最多恢復的會話數(默認50)。dryRun:只寫交接記錄,不發信號(默認false)。
適用場景與注意¶
- 適合需要長時間運行、中途可能重啓宿主的 DSH 工作流場景。
- 插件以當前 dsh 進程權限運行,安裝前應檢查源碼與許可證。
- 圍欄是引導而非隔離,理論上仍能被混淆繞過,真正的兜底是恢復機制。
- 宿主必須由一個
Restart=always的 systemd 單元監管,插件會向宿主發SIGTERM。
小結¶
dsh-restart-handoff 把重啓宿主變成一次可計劃的操作:模型通過 restart_dsh 工具兩步確認,宿主寫入交接記錄,新進程恢復會話、子代理和指令。即便宿主被殺,工作也會通過非計劃恢復機制回來。
目錄頁:https://www.skillhub.cn/plugins/sadkga/dsh-restart-handoff
GitHub:https://github.com/sadkga/dsh-restart-handoff