dsh-command-queue:agent 忙碌時斜槓命令排隊,空閒後自動執行

前言

在 DeepSeek Harness(DSH)裏,普通用戶消息和斜槓命令走的是兩條不同的通道:前者在 agent 忙碌時會進入 inbox 排隊,回合結束再消費;後者通過 ctx.commands.execute() 直接調 handler,忙碌時沒有排隊語義。典型例子是 /compact:其 handler 會調用 compactNow() → agent.runMaintenance(),當 agent 非 idle 時會同步拋出 ManualCompactionError('busy'),你只會立刻看到「Compaction is unavailable because this process has an active compaction, or the agent is not idle.」——既不能排隊,也沒有重試。DSH 側曾明確排除「把命令本身進隊列」的方案,官方沒有對應開關。

下面介紹社區插件 dsh-command-queue(維護者 kuyueliuhun-ctrl):在 host 側包裝 ctx.commands.execute(),讓列入白名單的斜槓命令(默認只有 /compact)在 agent 忙時進入命令隊列,等狀態回到 idle 後再執行;並在瀏覽器裏用接近原生消息隊列的樣式展示這份隊列。插件分類爲工作流,不改 DSH 源碼,卸載可還原 execute 行爲。

這是什麼

dsh-command-queue 是 DSH 的 host + client 雙面插件:host 負責排隊與延遲執行,client(platform: "web")在 composer 上方、原生消息隊列下方渲染「命令隊列」面板。攔截點在 ctx.commands.execute();命令仍由原註冊表解析,仍由 CommandRuntime 寫 command/run 與 command/done 生命週期,只是執行時機被推遲到空閒窗口。

原生 agent inbox 隊列條目只能是 UserMessage,且會在下一個 step 邊界被取走——那時 agent 往往仍在 running,compactNow 仍會 busy。因此本插件另建一份隊列,只復刻樣式與掛載位置(槽位 conversation.input.dock,id:"command-queue" / order:30),與原生 id:"queue" 上下並排。

核心功能

忙碌時排隊,空閒後執行

agent 正在跑回合時發送默認白名單內的命令(默認 /compact):

  1. 命令進入隊列,輸入框不凍結,可繼續打字、繼續排普通消息;
  2. composer 上方出現命令隊列 UI:單條直接顯示一行命令;多條摺疊爲「已排隊命令 · N」可展開,每行帶移除按鈕;
  3. 回合結束、agent idle 後命令真正執行,transcript 裏出現正常命令卡片(「執行中…」→「已完成 · Compacted N history items」等),隊列中對應行消失。

隊列爲空時 client 面板不渲染(返回 null),不佔視覺空間。

白名單與零迴歸

排隊規則是白名單:只有名字列在 deferCommands 裏的命令纔可能排隊,默認僅 compact。以下任一情況立即執行,不進隊列:

  1. 不是合法命令語法(例如不以 / 開頭、名稱含大寫、只有 /);
  2. 命令名不在 deferCommands 裏(默認即絕大多數命令);
  3. 在強制立即名單裏(內置 stop / cancel / abort / interrupt / halt,與用戶配置的 immediateCommands / alwaysImmediateCommands 取並集);
  4. 在註冊表裏解析不到(ctx.commands.find 返回 undefined);
  5. agent 當前已是 idle。

排隊邏輯自身拋錯時會回落爲原行爲,不吞命令。卸載時會喚醒等待者,讓在隊命令儘快執行完。

瀏覽器面板與 /cmdqueue

面板約每 1.5s 輪詢 host 快照;行右側按鈕可移除尚未執行的排隊命令(被移除的命令不會執行)。面板數據走 /api 已鑑權路由(Host/Origin 圍欄 + 簽名 cookie),不用裸 webServer 路由。

不想開面板時,可用只讀斜槓命令查看同一份隊列:

/cmdqueue
→ 1 command(s) queued for this agent, waiting for it to become idle: /compact
→ No queued commands for this agent.

按 agent 隔離

隊列按 agent 隔離,嚴格 FIFO 串行;一個 agent 空閒不會放行另一個 agent 的在隊命令。

安裝與啓用

本包是手寫 ESM / 瀏覽器 bundle,無編譯步驟;lib/index.js 與 lib/client.js 即源碼。客戶端插件在頁面加載時裝配——安裝或注入後需要刷新頁面纔會出現面板。

Node 引擎要求:>=22.19.0(見 package.json)。peer 依賴 @deepseek-ai/cordis(>=4.0.0-rc <5)。

方式 A:從 GitHub 裝配進 profile(推薦,重啓後仍在)

進入所用 profile 目錄(示例爲 web profile):

cd "$DSH_HOME/profiles/<profile>"          # 例如 ~/.dsh/profiles/web
npm install github:kuyueliuhun-ctrl/dsh-command-queue

把包名加入該 profile 的 package.json 裏 dsh.profile.bundles 數組:

{ "dsh": { "profile": { "bundles": ["dsh-command-queue"] } } }

包自帶 cordis.patch.yml,bundle 層會把 command-queue 插進 loader,無需手寫 patch 條目。

方式 B:本地目錄(開發)

npm install "file:/path/to/dsh-command-queue"

若使用 dsh-super-injector:

dev_install_package { "dir": "/path/to/dsh-command-queue", "profile": "web" }

方式 C:運行時注入(免重啓,臨時驗證)

dev_inject_plugin   { "dir": "/path/to/dsh-command-queue" }
dev_plugin_status   {}

卸載

dev_uninject_plugin { "match": "dsh-command-queue" }

非注入器環境:從 dsh.profile.bundles 移除包名,再刪除 node_modules 裏對應包。

配置

無獨立 schema,容錯讀取,全部可選。寫在 profile 的 cordis.patch.yml 裏 command-queue 條目下的 config:

- id: command-queue
  name: 'dsh-command-queue'
  config:
    deferCommands:                   # 主開關:只有列在這裏的命令才排隊(默認 ['compact'])
      - compact                      # 帶不帶前導 / 都可以
    verbose: true                    # 打開排隊/執行日誌(默認 false)
    pollIntervalMs: 250              # host 側等空閒的輪詢兜底間隔,50–5000(默認 250)
    exposeState: true                # 註冊給瀏覽器面板的已鑑權路由(默認 true;false = 純 host)
    immediateCommands:               # 強制立即:與內置名單取並集(v0.2.2 起不再整體替換)
      - export
    alwaysImmediateCommands:         # 與 immediateCommands 語義等價,同樣取並集
      - my-control-command
  • deferCommands: [] 表示沒有任何命令排隊,等同於關閉排隊功能。
  • 某命令同時出現在 deferCommands 與強制立即名單時,強制立即優先。
  • 默認只排 /compact 的原因:/permission、/plan、/goal 等會改會話狀態,推遲到回合結束可能徹底失效;早期版本「除立即白名單外一律排隊」曾帶來這類迴歸,當前默認策略已收窄。

典型用法與故障排查

典型流程:在 agent 仍 busy 時輸入 /compact → 在命令隊列面板或 /cmdqueue 確認已排隊 → 等當前回合結束 → 在 transcript 查看 compact 結果,隊列行消失。

現象 處理要點
刷新後仍看不到面板 用 dev_plugin_status 確認 client ✓;若爲 client ✗,可能是 pkgMeta 負緩存,重啓 host
排隊期間 transcript 無提示 設計如此:command/run 在 handler 調用前才寫入,提示在隊列面板
命令一直不執行 在等 idle;若 inbox 裏消息不斷,空閒窗口會被佔用——用 /cmdqueue 或面板確認
/permission 等忙時不生效 若仍在舊規則版本,升級到默認只排 compact 的版本;檢查是否誤把狀態類命令寫進 deferCommands

開發側可運行:

npm test      # node --test tests/*.test.mjs
npm run check # node --check lib/index.js && node --check lib/client.js
npm run build # 語法校驗 + 全套測試

適用場景與注意

適合:經常在 agent 長回合進行中需要 /compact、又不想反覆撞 busy 報錯的用戶;希望在 UI 裏看見「還有哪些命令在等 idle」的團隊。

注意:

  • 插件以當前 DSH host 進程權限運行,安裝前請閱讀 源碼與 LICENSE(MIT),自行評估信任邊界。
  • 社區目錄 SkillHub 插件頁 與 GitHub 倉庫由維護者發佈,與 DeepSeek / 幻方無官方從屬關係;DSH 生態強調「一切皆插件」,本文事實以倉庫 README 與 package.json 爲準(當前 package 版本 0.2.2)。

結尾

dsh-command-queue 補上了 DSH 斜槓命令通道在 busy 時缺少排隊語義的那一段:默認只推遲 /compact,其餘命令保持立即執行;卸載可還原。更多實現細節見倉庫 docs/INTERNALS.md。

  • 目錄頁:https://www.skillhub.cn/plugins/kuyueliuhun-ctrl/dsh-command-queue
  • GitHub:https://github.com/kuyueliuhun-ctrl/dsh-command-queue
羽毛球分组比赛记分
小程序二维码

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

小夜