前言¶
在構建基於 DeepSeek Harness (DSH) 的智能體時,接入外部渠道(如 QQ、Telegram 或郵件)通常需要編寫大量協議適配代碼,且難以統一管理。dsh-message-hub 作爲一箇中轉插件,提供了一個傳輸無關的通信中心。它通過統一的“渠道註冊表”將入站和出站邏輯解耦:宿主插件負責具體的協議實現(如連接 QQ),而 Hub 負責路由、綁定狀態和與 Agent 的交互。
本插件由 FuLuTang 維護,採用 MIT 許可證。
核心功能¶
該插件主要解決多渠道消息的統一接入與路由問題,核心能力包括:
- 渠道註冊表:提供入站 和出站 的註冊接口,支持 Web API 集成。
- 固定 Agent 工具:提供
message_hub_list_channels、send、bind、status等固定工具,方便 Agent 查詢和管理渠道。 - 喚醒模式:支持
steer(插話)和followup(排隊)兩種模式,控制外部消息如何進入 Agent 上下文。 - 文件適配器:內置
file-spool適配器,支持通過共享目錄或 Docker Volume 進行跨進程通信。
安裝與啓用¶
安裝前請確保環境滿足 Node.js 版本要求(>=22)。
- 使用官方插件安裝器添加插件到 Web profile:
dsh plugin --profile web add github:FuLuTang/dsh-message-hub
- 安裝完成後重啓 DSH Web 服務,並強制刷新瀏覽器頁面(以加載新的 client bundle)。
配置¶
在 DSH 的 YAML 配置中聲明插件實例。channels 僅用於聲明元數據和初始開關,實際的運行時實現由受信任的插件代碼註冊。
- id: dsh-message-hub
config:
storagePath: '' # 默認爲 $DSH_HOME/message-hub/state.json
maxLedgerEntries: 2000
wakeupMode: steer # 全局默認喚醒方式:steer=插話 / followup=排隊
channels: [] # 聲明式渠道元數據
spools: [] # file-spool 配置
outlets: [] # file-spool 出站路由
渠道註冊表¶
在 DSH 運行時,通過 Agent 的 ctx 訪問 messageHub 進行註冊。
註冊入站與出站¶
// 註冊入站:接收消息
await ctx.messageHub.registerIngress({
id: 'telegram-in',
name: 'Telegram 入站',
description: '接收 Telegram 更新',
template: '來自 {{sender}}:{{text}}',
wakeup: true,
setEnabled: async (enabled) => { /* 啓停傳輸實現 */ }
});
// 註冊出站:發送消息
await ctx.messageHub.registerEgress({
id: 'telegram-out',
name: 'Telegram 出站',
description: '發送一條 Telegram 消息',
schema: { type: 'object', required: ['chatId', 'text'] },
setEnabled: async (enabled) => { /* 啓停傳輸實現 */ },
async invoke(args, { deliveryId, sessionId }) {
return { success: true, message: 'sent' }
}
});
狀態與開關¶
每個渠道維護兩種狀態:
* desiredEnabled:用戶通過 Web API 或配置要求的開關。
* light:實現報告的運行狀態燈(black、yellow、green)。
Agent 工具¶
插件爲 Agent 提供了一組固定的工具,用於查詢和管理渠道:
| 工具名 | 參數 | 用途 |
|---|---|---|
message_hub_list_channels |
無 | 列出渠道 ID、方向、開關、狀態燈和詳情。 |
message_hub_describe_channels |
channelIds?: string[] |
查詢指定渠道(默認查詢所有 egress)的說明和參數 Schema。 |
message_hub_send |
channelId, arguments |
校驗參數後調用 egress 發送消息。 |
message_hub_bind / unbind |
channelId, sessionId |
綁定或解除當前對話與舊式 adapter 的關係。 |
message_hub_status |
無 | 查看完整快照(含渠道、綁定、投遞記錄)。 |
message_hub_read_input |
無 | 讀取 file-spool input/ 目錄下的 UTF-8 文件(最大 64 KiB)。 |
入站綁定與喚醒模式¶
綁定流程¶
通過 bindIngress(channelId, sessionId, options) 將入站消息綁定到特定的 DSH session。
綁定配置支持:
* template:覆蓋默認消息模板。
* wakeup:是否在注入消息後喚醒 Agent(默認開啓)。
* wakeupMode:覆蓋全局設置。steer 模式下消息作爲 next-step 輸入插話;followup 模式下消息排隊進入下一個獨立輪次。
* cwd:替代會話工作目錄。
投遞語義¶
當 emitIngress(channelId, event) 觸發時,Hub 會執行以下步驟:
1. 檢查開關和綁定狀態。
2. 解析目標 session。若 session 不可用且綁定包含 cwd,Hub 會創建替代會話;否則保留失敗結果。
3. 向 Agent 注入兩條消息:不可信的外部上下文說明和渲染後的 <external-message> 內容。
4. 根據 wakeupMode 喚醒 Agent(舊版運行時若不支持 steer() 會自動降級爲 followup)。
Web API 與客戶端¶
啓用 Web runtime 時,插件在本地註冊前綴 /message-hub/api,僅接受受信任的 localhost 請求。
POST /message-hub/api/snapshot:獲取渠道快照(含defaultWakeupMode)。POST /message-hub/api/toggle:修改渠道的desiredEnabled。POST /message-hub/api/bind:綁定 ingress 或 file-spool 到 session。
Web 客戶端會自動在設置界面展示“消息渠道”卡片,每 5 秒刷新一次狀態,顯示渠道方向、輪詢燈(綠=輪詢中,黃=失敗,黑=停止)及綁定信息。
File-spool 適配器¶
對於需要共享目錄或跨語言腳本通信的場景,可以使用內置的 file-spool 適配器。它不是 channel registry 的一部分,而是作爲獨立的輸入/輸出通道。
配置示例¶
spools:
- id: volume-main
label: 共享目錄
root: /mnt/message-device
enabled: true
ackMode: delete # delete | keep
pollMs: 1000
maxBytes: 262144
payloadFile: input/message.json
payloadFormat: json
outlets:
- id: panel-notify
spoolId: volume-main
endpointId: panel
enabled: true
目錄佈局¶
- root/:根目錄。
- input/message.json:入站觸發文件。
- output/:出站投遞目錄。
- .tmp/:臨時文件。
- ack/:外部程序寫回的確認文件。
- .message-hub/processed/:已處理的觸發文件。
- status.json:可選的 endpoint 狀態快照。
行爲說明¶
- 入站:輪詢
root下的觸發文件(非特殊目錄)。成功排入綁定 session 後,根據ackMode移動或保留文件。 - 出站:寫入
output/<deliveryId>.json。外部程序應在output/ack/<deliveryId>.ack.json中確認發送結果。 - 輪詢燈:面板上的燈僅反映當前進程的輪詢狀態,不改變配置文件。
注意事項¶
- 單實例限制:同一個
storagePath下只能運行一個 Hub 實例。 - 協議實現:Hub 本身不實現 QQ、Telegram 等協議,僅註冊它們。具體的連接邏輯由宿主插件負責。
- 包格式:必須使用
dsh plugin安裝命令,確保包被正確加入 profile 的 bundle 列表,單純npm install不會生效。 - Node 版本:最低要求 Node.js 22。
總結¶
dsh-message-hub 爲 DeepSeek Harness 提供了標準化的通信接口。開發者可以通過註冊 Ingress 和 Egress 將任意協議接入 Agent 生態,利用固定的 Agent 工具或 Web API 進行管理。配合 file-spool 適配器,它可以輕鬆實現與外部腳本或系統的文件交換。