dsh-restart-handoff:在對話裏重啓 DeepSeek Harness

前言

在 DeepSeek Harness(DSH)裏,長時間運行的工作流往往需要中途重啓宿主進程。常見的做法是人在對話裏打字說「繼續」,或者退出命令行,再重新啓動 Harness。這會打斷會話、丟失子代理和待處理的指令,需要重新整理上下文。

dsh-restart-handoff 插件通過一個專用工具 restart_dsh,把「重啓宿主」變成一次計劃內的操作:模型發出重啓請求,宿主寫入交接記錄,然後被另一個進程拉起,繼續之前的會話和子代理,並執行待處理的指令。

是什麼

這是 sadkga 維護的一個 DSH 插件,分類爲「工作流」。它讓模型通過 restart_dsh 工具以兩步方式重啓宿主,並把會話、子代理和指令交給新進程繼續。插件以 Node 24 運行,需要宿主由一個 Restart=always 的 systemd 單元監管。

核心功能

計劃內重啓:兩步調用

  1. 警告調用。 模型調用 restart_dsh,工具返回一份警告,包括原因、將重放的指令、將恢復的會話,以及一個確認令牌。這一步不執行任何重啓。
  2. 確認調用。 模型帶着令牌再次調用 restart_dsh,令牌匹配時,工具寫入交接記錄到 $DSH_HOME/restart/handoff.json,記錄當前正在跑的會話、原因、待重放的指令(continuePrompt)和可繼續的子代理。工具等待當前輪次變空閒後,向宿主進程發送 SIGTERM,由 Restart=always 的單元拉起新進程。
  3. 重放。 新進程讀取交接記錄,執行恢復:
    - 恢復重啓發生時正在跑的每一個會話,並注入「請繼續」指令;
    - 自上而下地喚起可繼續的子代理,保證子會話只在它自己的父會話活着時才被投遞;
    - 把 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

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜