dsh-supergroup:給 DSH 裝一個可對賬的多會話派工層

前言

在 DSH 裏做多會話協作時,常見做法是在一個長會話裏手動記錄「張三幹 A、李四幹 B」,回頭看誰回覆了什麼。這種做法在會話多、上下文長時很容易出錯:把別人的輸出誤當成自己的結果,或者重啓後根本想不起某張工單投出去沒有。

下面介紹的 dsh-supergroup 就是針對這個痛點的一個插件。它不改變 DSH 的會話機制,而是加一層編排:一個主會話帶若干執行會話,按 sessionId 派工、按 rpcId 回收結果、重啓後自動對賬。維護者是 LXS652,分類爲工作流,許可證 MIT,項目版本 1.0.1。

這是什麼

一句話定位:dsh-supergroup 是 DeepSeek Harness 的一組會話編排插件,把一個主會話和若干執行會話組成一個「整體」,主會話負責拆解與派工,執行會話各幹各的,結果按投遞時生成的 rpcId 精確回到主會話。

它要解決的問題很具體:

  • 派工不靠標題、暱稱或當前選中會話,而是按確定的 sessionId 投遞,避免「派給誰」的歧義。
  • 結果回收不靠「猜下一條回覆」,而是按投遞時生成的 requestId(即 rpcId)錨定,該 id 會隨消息進入會話歷史。
  • 宿主重啓後,賬本先恢復,再對「投遞了但沒等到結算」的工單做歷史對賬,能自動證明完成的才收斂,證明不了的留給人裁決。
  • 對賬只做只讀歷史和改狀態,絕不自動重發——因爲外部副作用可能已經發生。

安裝只需要往 DSH profile 里加一個 insert 條目,無外部依賴。

核心能力

下面列出的是 README 中明確寫出的能力,按功能分述。

編排模型

一個 DSH profile 裏可以同時存在多個「整體」,每個整體有獨立的主會話(lead)、成員名單和工單賬本視圖。成員最多 8 個,lead 不能出現在成員裏。

派工通過 ms2_dispatch 完成,消息進入成員會話,賬本寫 dispatch,工單進入 delivered 狀態。回收有兩條路:一是 session/event 快路徑,收到帶同一 rpcId 的 user/message 後跟隨該回合到 turn/end;二是歷史對賬,在啓動、ms2_status、/ms2 panel 三個時機讀取會話歷史,按 rpcId 精確錨定。

重啓自愈

宿主重啓時,delivered 先轉成 uncertain(不知道結果是否已經產生)。啓動對賬繼續查歷史:

  • 找到 turn/end 且 completed,結算爲 completed,保留 reason: "restart" 作爲證據,source 標爲 history-reconcile-after-restart;
  • 找不到證據,保持 uncertain,原因寫進 observeStats;
  • uncertain 也可以由主會話用 ms2_resolve 人工 accept / fail。

需要強調的是:插件從不爲了「催結果」重投工單。

側欄面板

  • 左欄按工作區分組列出會話,「摺疊批量會話」「摺疊空白會話」兩個勾選互相獨立;
  • 點「創建一個整體」進入三步向導:選主會話 → 選執行會話(可多選,空白會話也可選)→ 填整體名;
  • 每張整體卡片顯示主會話、成員、工單數與在途數,卡片內可改名、全量替換成員、解散整體;
  • 有在途工單(delivered / uncertain)時,解散或移除對應成員會被拒絕,並返回具體 requestId。

權限隔離

成員不能調用 ms2_* 協調工具,也不能用跨會話工具,業務工具照常可用。派工、裁決、改名、改成員、解散權限只在整體 lead 手上。

安裝與啓用

當前版本有兩條安裝路徑,新裝優先走路 A:直接改 profile 的 patch 文件,不依賴 bundle 機制。

路 A:往 cordis.patch.yml 追加 insert 條目

1、把插件目錄放到一個固定位置,確認入口文件存在:<你的工作區>/dsh-supergroup/src/plugin2.mjs。

2、打開 ~/.dsh/profiles/<profile>/cordis.patch.yml,在文件末尾追加:

- insert:
    - id: dsh-supergroup
      name: file:///<你的工作區>/dsh-supergroup/src/plugin2.mjs
      config:
        registryFile: '<你的 DSH_HOME>\data\registry.json'
        groupsFile: '<你的 DSH_HOME>\data\groups.json'
        ledgerFile: '<你的 DSH_HOME>\data\tasks.jsonl'

這裏要注意三點:name 必須是絕對路徑的 file:/// 形式且指向入口文件 src/plugin2.mjs(不是目錄);Windows 路徑把反斜槓寫成 /;條目必須包在 insert: 列表裏,不能用 plugin: 字段,也不要裸寫 - id: dsh-supergroup——沒有對應已有條目時會被當成覆蓋,宿主只記一條 patch: entry ... not found 然後靜默跳過。

3、重啓 DSH。側欄應出現「超級代理部署」圖標,ms2_status 應可用。

配置上,groupsFile 省略時會跟隨 registryFile 落到同目錄的 groups.json,eventsLogFile 省略時落在賬本同目錄的 session-events.log。可選配置:startupReconcileAttempts(默認 50,夾在 1..50)、startupReconcileIntervalMs(默認 200,夾在 1..200)、bootstrapGroups(首次啓動預置整體,數組項爲 {name, lead, members})、startupReport(默認 false)、selfTest(傳入對象時運行內置自檢)。

路 B:作爲 bundle 安裝

如果 profile 已經用 bundle 機制,則三件事必須同時成立,缺一不會加載:

1、profile 的 package.json 在 dependencies 裏登記本包,例如 "dsh-supergroup": "file:<你的工作區>/dsh-supergroup";
2、同一個 package.json 的 dsh.profile.bundles 數組包含 "dsh-supergroup";
3、在 profile 目錄執行 pnpm install,讓包真正進入 node_modules。

三者齊備後,bundle 會讀取包內的 cordis.patch.yml,其中 name 使用包名 dsh-supergroup,而不是 file:// 路徑。

裝完沒反應怎麼查

1、確認改的是當前 profile 的 cordis.patch.yml,條目追加在文件末尾、位於 insert: 列表內。

2、用 dsh --dump-config 看最終配置。Desktop 的 profile 可能被 Electron 獨佔,可以複製一份再對副本 dump:

cp -al ~/.dsh/profiles/<profile> ~/.dsh/profiles/<profile>-probe

3、grep dsh-supergroup 檢查 dump 輸出;若 stderr 出現 patch: entry ... not found,說明條目沒進入 insert:,或 id 寫錯。

4、仍無圖標時,再確認入口文件存在、name 是 file:/// 文件 URL,且 DSH 已完全重啓——客戶端 bundle 不熱更。

典型用法

工具層面,主會話通過以下 ms2_* 工具完成日常編排:

工具 參數 作用
ms2_status 留空或 list 查看當前調用者可見的整體、成員、工單、恢復項與對賬統計
ms2_group {"action":"create","name":"...","lead":"session-...","members":["session-..."]} 創建整體;list 列出可見整體
ms2_members {"group":"整體名或 id","request":"list\|add <id>\|remove <id>\|lead <id>"} 查看或增刪成員
ms2_dispatch {"group":"整體名或 id","memberId":"session-...","text":"..."} 把一張工單投給成員
ms2_resolve {"requestId":"...","action":"accept\|fail"} 主會話裁決一條等待人工的工單

一個可復現的最小流程:

1、主會話裏執行 ms2_group,創建整體 {"action":"create","name":"research","lead":"session-A","members":["session-B","session-C"]};
2、把任務拆成兩張工單,分別用 ms2_dispatch 投給 session-B、session-C,每張工單各自生成 requestId;
3、結果走 session/event 快路徑迴流,或在下次 ms2_status / /ms2 panel 時由歷史對賬補結算;
4、如果某張工單成了 uncertain,在主會話裏用 ms2_resolve 按證據 accept 或 fail。

命令層面,面板側欄還支持以下命令,命令後的內容是 rawInput(不含 /ms2 前綴):

/ms2 panel
/ms2 create {"name":"...","lead":"session-...","members":["session-..."]}
/ms2 dissolve <groupId>
/ms2 group rename {"group":"g-...","name":"..."}
/ms2 group members {"group":"g-...","members":["session-..."]}

這些命令由客戶端面板通過 ctx.remote.commands.execute 投到目標會話。只有整體 lead 能解散、改名、改成員;成員名單是全量覆蓋;被移除成員若有 delivered / uncertain 工單,整次修改拒絕。

適用場景與注意

適合誰:需要在單個 DSH profile 內管理多個執行會話、希望派工有明確歸屬、要求結果可追溯、並且看重重啓後狀態不丟失的用戶。它把「誰來做、做沒做完、重啓後賬本是否對得上」這三件事交給了工程化的賬本和對賬,而不是靠人工記憶。

需要注意的邊界,README 已逐條寫明,下面挑重點:

  • 對賬時機固定:只有啓動、ms2_status、/ms2 panel 三個入口觸發,沒有後臺輪詢,不調用就不會主動結算。
  • 不做隔離:插件只做會話編排,成員共享文件系統、網絡和 cwd,不提供進程、目錄或網絡隔離,需要注意成員之間的可見範圍。
  • 沒有外部效果的 exactly-once:賬本保證工單狀態可恢復,但成員在完成前執行的副作用(發消息、改文件、調外部 API)無法由插件回滾;需要重試前請自行確認冪等性。
  • 會話必須存在:派工只按 sessionId 投遞,不探測會話是否仍有效,失效會話會在歷史對賬時表現爲找不到錨點。
  • 暫不支持主會話轉移:lead 是整體創建時確定的會話。

另外,該插件以當前 dsh 進程權限運行,安裝前應檢查源碼與許可證(MIT)是否符合你的環境要求。插件在 SkillHub 社區目錄的分類是工作流,社區目錄是獨立站點,與 DeepSeek 無官方從屬關係。

結尾

dsh-supergroup 補的是這樣一塊:多會話編排裏最難的不是「發出去」,而是「發出去之後能不能對得上賬」。它用 sessionId 解決歸屬,用 rpcId 解決回收,用落盤賬本和歷史對賬解決重啓後的自愈。如果你在 DSH 裏已經跑起了多條執行會話,可以把它作爲一層輕量的協調骨架試試。

插件目錄頁:https://www.skillhub.cn/plugins/LXS652/dsh-supergroup

源碼與文檔:https://github.com/LXS652/dsh-supergroup

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

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

小夜