dsh-plugin-im-remote-control:用飛書機器人遠程驅動 DSH 會話

前言

DSH 的日常交互主要在桌面端完成。人離開工位時,想用手機或 IM 給正在跑的 Harness 會話發一條指令、看模型結論,或處理一次 ask 檔審批,往往需要額外搭回調、內網穿透或自建橋接。dsh-plugin-im-remote-control(維護者 raven3005672)把飛書(Lark)機器人和 DSH 宿主綁在一起:消息經 sessionController.prompt 進入會話,回合結束把 assistant 文本回帖;審批和 ask_user_question 可在飛書裏用卡片或斜槓命令處理。當前交付的是 direct 模式——插件進程內持有飛書 WebSocket 長連接,不需要公網 IP。包版本 0.2.0,許可證 MIT,在 DSH 插件目錄中歸類爲客戶端。

下面按定位、能力、安裝配置、典型用法和注意事項說明。

這是什麼

插件全稱 dsh-plugin-im-remote-control,一句話定位:用飛書機器人遠程控制一個 DSH 會話。飛書側私聊或羣聊 @ 機器人發消息,等價於在桌面輸入框投遞 user turn;插件監聽會話事件,在聊天裏回帖、發回執,並把審批與提問轉發到飛書。中控會話還可通過 HTTP dispatch 把任務投到其他會話,由插件負責把執行結果綁回對應聊天。

設計細節(狀態機、競速、卡片協議等)見倉庫 docs/DESIGN.md。微信接入與 gateway 冷啓動模式代碼保留但未啓用。

核心功能

資料中已覈實的能力如下。

能力 說明
飛書長連接 插件內 WebSocket,無需公網回調地址
私聊 / 羣聊 私聊直接處理;羣聊須 @ 機器人
消息進會話 走 sessionController.prompt,不繞過 session log
回合回帖 回合結束髮送最後一步 assistant 文本;dispatch 任務首行帶 【會話名】
表情回執 收到消息貼 Get;會話忙時貼 OneSecond(可由 ack 關閉)
分發接口 Bearer token + chat allowlist,POST /im-remote-control/dispatch
審批轉發 ask 檔審批以卡片發到飛書,按鈕或 /approve、/deny,與桌面彈窗競速
卡片提問 ask_user_question 以卡片展示選項;多選或自定義用 /answer
圖片輸入 下載飛書圖片作爲 image part(PNG/JPEG/GIF/WebP,單張 ≤10 MB,單條最多 4 張)
引用回覆路由 引用機器人某條結果回覆時,消息回到產生該結果的會話
設置頁 DSH「設置 → 遠程控制」可編輯憑據、allowlist、渠道等(改動需重啓生效)
/whoami 返回發送者 open_id,用於配置 allowlist

尚未交付:非圖片文件、語音/音頻、微信、gateway 冷啓動、超限重試、多實例等。

工作方式概覽:

飛書(私聊 / 羣聊 @)
  │  WebSocket 長連接(插件持有)
  ▼
dsh-plugin-im-remote-control(Host)
  ├─ sessionController.prompt  → 目標會話 user 消息
  ├─ ctx.on('session/event')   → 回合結束回帖
  ├─ ctx.on('approval/request') → 卡片審批
  ├─ ctx.on('user-questions/request') → 卡片提問
  ├─ card.action.trigger       → 按鈕點擊
  └─ ctx.webServer             → /dispatch、/check、/status

消息按 session 隊列(mode: 'queue' 對應宿主 agent.followup())串行處理;只有經插件投遞的回合會回帖,桌面手動發起的回合不受影響。

安裝與啓用

安裝命令

從 npm 安裝(將 <profile> 換成你的 profile 名):

dsh plugin --profile <profile> add dsh-plugin-im-remote-control

或從本地構建目錄安裝(lib/ 不入庫,需先構建):

cd /path/to/dsh-plugin-im-remote-control && npm install && npm run build
dsh plugin --profile <profile> add /path/to/dsh-plugin-im-remote-control

運行環境要求(來自 package.json):Node ^22.19.0 || >=24.0.0,DSH >=0.2.0 <0.3.0;與 DSH 0.2.1-rc.2 標註爲 compatible。

profile 配置

包的 dsh.bundle.patch 已 insert 插件行。你在 profile 的 cordis.patch.yml 裏只需加一條同 id 的覆蓋行(不要再次 insert 同 id,否則會掛兩份長連接且設置頁找不到配置):

- id: dsh-plugin-im-remote-control
  name: dsh-plugin-im-remote-control
  config:
    feishu:
      appId: cli_xxxxxxxxxxxxxxxx
      appSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    controllerSessionId: session-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    channels: [feishu]
    allowedChats:
      - oc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    allowedUsers:
      - name: 我自己
        openId: ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ack: true
    reply: true

覆蓋行的 config 是整體替換,不是深合併,需要的鍵要一次寫全。

配置改完後重啓 DSH:Host 半邊與飛書連接僅在啓動時加載;設置頁的修改同樣要重啓後才應用到連接。

可選兜底文件 $DSH_HOME/im-remote-control.json(默認 ~/.dsh/im-remote-control.json)可補充憑據與 allowlist;行內顯式配置優先,allowlist 數組取並集。

飛書應用準備

  1. 在飛書開放平臺創建企業自建應用,開啓「機器人」。
  2. 權限:im:message、im:message.group_msg、im:message:send_as_bot。
  3. 事件訂閱選長連接,訂閱 im.message.receive_v1(無需公網地址)。
  4. 在回調配置頁把 card.action.trigger 也設爲長連接(卡片按鈕交互);缺這一步點按鈕會報 200340。
  5. 發佈並把機器人加入目標羣或私聊使用。
  6. 在飛書裏對機器人發 /whoami,把返回的 open_id 填入 allowedUsers 或 allowedOpenIds。

訪問控制(fail-closed)

allowedChats、allowedUsers、allowedOpenIds 至少配一項,否則插件只註冊設置頁探測、不連飛書(日誌 no access control configured),也不會處理 dispatch。數組寫錯會直接報錯,不能當成「空 = 不限制」。

主要配置項:

字段 說明
feishu.appId / feishu.appSecret 自建應用憑據;設置頁 Secret 只顯示掩碼,不留存明文回顯
controllerSessionId 中控會話 ID(兼容舊字段 sessionId)
channels 默認未設置即飛書;[] 表示不連飛書
ack / reply 默認 true,控制表情回執與回合回帖
enabled false 時不啓動插件

典型用法

日常對話

私聊機器人直接發文字;羣聊須 @ 機器人。文本與圖片(在模型支持 image 輸入時)進入 controllerSessionId 指定的中控會話,或由引用回覆路由到產生某條機器人結果的執行會話。

斜槓命令

命令 作用
/whoami 返回發送者 open_id
/approve <id> 批准審批(allowed-once)
/deny <id> 拒絕審批
/answer <id> <文本> 回答提問;多選用逗號分隔選項

羣聊發命令也要 @ 機器人。

審批卡片約 120 秒內有效,超時自動拒絕;提問卡片約 5 分鐘內有效,超時只撤回卡片,桌面仍可作答。飛書與桌面競速:誰先決定誰生效。

引用回覆

對機器人發出的回合結果做「引用回覆」,下一條消息進入該結果所屬會話,適合 dispatch 出去的任務在飛書裏做追問;不引用時消息仍進中控。

中控分發

中控會話可通過 POST /im-remote-control/dispatch 把任務投給任意會話。鑑權爲 Authorization: Bearer <token>,且 chatId 須在 allowedChats 中。token 每次掛載隨機生成,寫入 $DSH_HOME/im-remote-control.token(權限 0600)。倉庫提供 scripts/dispatch.mjs 可讀該 token 調用。

設置頁通過 POST /im-remote-control/check(頭 x-imrc-check: 1)做只讀探測,GET /im-remote-control/status 查看哪些字段已配置(不含 Secret 明文)。

適用場景與注意

適合誰:需要在飛書裏收發 DSH 回合、遠程點審批或答 ask_user_question 的開發者;希望用長連接、不暴露公網回調的小型自建部署。

權限與安全:allowlist 中的飛書賬號等價於能在 DSH 進程權限下驅動 agent(含 shell、讀寫文件)。插件以當前 DSH 進程的系統用戶權限運行;安裝前應自行審閱 源碼 與 MIT 許可證。官方建議從飛書驅動的會話使用 workspace-write + ask,避免 danger-full-access + never 讓遠程消息無剎車執行。

飛書賬號即執行權,宜開啓二次驗證並保持 allowlist 儘量小。/im-remote-control/* 路由由插件掛在 Host web server 上,不走 GUI 的 cookie 認證:dispatch 靠 Bearer token;若 Host 綁定非迴環地址,這些路由會一併暴露(/status 最壞僅泄露布爾狀態與 Secret 末四位掩碼)。

已知限制:非圖片文件不轉發;回帖僅最後一步 assistant 文本,超過約 3500 字符會截斷;一個飛書應用只應有一條長連接、一個實例對應一箇中控 sessionId;審批僅對 ask 檔有意義(never 檔不產生審批請求)。

DSH 生態強調「一切皆插件」;SkillHub 目錄 爲社區站點,與 DeepSeek / 幻方無官方從屬關係。

結尾

dsh-plugin-im-remote-control 把飛書長連接、會話 prompt、回合回帖、審批與提問卡片和 dispatch 串成一條可落地的遠程控制鏈路,direct 模式無需公網回調。查閱安裝細節與更新說明見 GitHub 倉庫,在 SkillHub 插件頁 可瀏覽分類與簡介。

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

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

小夜