此頁是目標設計,用於以一個耐久的訊息生命週期,取代分散的頻道回合、回覆分派、預覽串流,以及出站傳遞輔助工具。 簡短版本:Documentation Index
Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
- 核心基元應該是 接收 與 傳送,而不是 回覆。
- 回覆只是出站訊息上的一種關係。
- 回合是入站處理的便利機制,不是傳遞的擁有者。
- 傳送必須以脈絡為基礎:
begin、算繪、預覽或串流、最終傳送、提交、失敗。 - 接收也必須以脈絡為基礎:正規化、去重、路由、記錄、分派、平台 ack、失敗。
- 公開的 Plugin SDK 應收斂為一個小型頻道訊息介面。
問題
目前的頻道堆疊是由幾個合理的局部需求演進而來:- 簡單的入站配接器使用
runtime.channel.turn.run。 - 功能較完整的配接器使用
runtime.channel.turn.runPrepared。 - 舊版輔助工具使用
dispatchInboundReplyWithBase、recordInboundSessionAndDispatchReply、回覆承載輔助工具、回覆分塊、回覆參照,以及出站執行階段輔助工具。 - 預覽串流位於各頻道專屬的分派器中。
- 最終傳遞耐久性正在既有回覆承載路徑周圍加入。
目標
- 所有頻道訊息接收與傳送路徑共用一個核心生命週期。
- 配接器宣告具備可安全重放行為後,在新的訊息生命週期中預設使用耐久最終傳送。
- 共用的預覽、編輯、串流、最終化、重試、復原與收據語意。
- 第三方 Plugin 可學習並維護的小型 Plugin SDK 介面。
- 遷移期間相容既有
channel.turn呼叫者。 - 為新的頻道能力提供清楚的擴充點。
- 核心中沒有平台專屬分支。
- 沒有 token-delta 頻道訊息。頻道串流仍維持為訊息預覽、編輯、附加,或已完成區塊傳遞。
- 針對操作性/系統輸出的結構化 OpenClaw 來源中繼資料,避免可見的 Gateway 失敗在啟用機器人的共用房間中重新作為新提示進入。
非目標
- 第一階段不移除
runtime.channel.turn.*。 - 不強迫每個頻道採用相同的原生傳輸行為。
- 不讓核心理解 Telegram 主題、Slack 原生串流、Matrix 編修、Feishu 卡片、QQ 語音,或 Teams 活動。
- 不將所有內部遷移輔助工具發布為穩定 SDK API。
- 不讓重試重放已完成的非冪等平台操作。
參考模型
Vercel Chat 有一個良好的公開心智模型:ChatThreadChannelMessage- 配接器方法,例如
postMessage、editMessage、deleteMessage、stream、startTyping,以及歷史擷取 - 用於去重、鎖定、佇列與持久化的狀態配接器
- 在直接傳輸呼叫之前建立耐久出站傳送意圖。
- 具有開始、提交與失敗的明確傳送脈絡。
- 知道平台 ack 政策的接收脈絡。
- 可在重新啟動後保留,並驅動編輯、刪除、復原與重複抑制的收據。
- 更小的公開 SDK。內建 Plugin 可以使用內部執行階段輔助工具,但第三方 Plugin 應看到一個一致的訊息 API。
- Agent 專屬行為:工作階段、逐字稿、區塊串流、工具進度、核准、媒體指令、靜默回覆,以及群組提及歷史。
thread.post() 風格的 promise 對 OpenClaw 而言並不足夠。它們隱藏了決定傳送是否可復原的交易邊界。
核心模型
新的領域應位於內部核心命名空間之下,例如src/channels/message/*。
它有四個概念:
receive 擁有入站生命週期。
send 擁有出站生命週期。
live 擁有預覽、編輯、進度與串流狀態。
state 擁有耐久意圖儲存、收據、冪等性、復原、鎖定與去重。
訊息術語
訊息
正規化訊息與平台無關:目標
目標描述訊息所在的位置:關係
回覆是一種關係,不是 API 根:來源
來源描述誰產生了訊息,以及 OpenClaw 應如何處理該訊息的回音。它與關係分離:一則訊息可以是對使用者的回覆,同時仍是 OpenClaw 來源的操作性輸出。allowBots 啟用時,不能於共用房間中被接受為機器人撰寫的輸入。
收據
收據是一等概念:接收脈絡
接收不應是單純的輔助呼叫。核心需要一個知道去重、路由、工作階段記錄,以及平台 ack 政策的脈絡。- 傳輸 ack: 告知平台 Webhook 或 socket,OpenClaw 已接受事件信封。有些平台要求這必須發生在分派之前。
- 輪詢 offset ack: 推進游標,使同一事件不會再次被擷取。這不得推進越過無法復原的工作。
- 入站記錄 ack: 確認 OpenClaw 已持久化足夠的入站中繼資料,可對重新傳遞進行去重與路由。
- 使用者可見收據: 選用的已讀/狀態/輸入中行為;絕不是耐久性邊界。
ReceiveAckPolicy 只控制傳輸或輪詢確認。它不得重用於已讀收據或狀態反應。
在機器人授權之前,當頻道可解碼訊息來源中繼資料時,接收必須套用共用的 OpenClaw 回音政策:
allowBots 授權。
Ack 政策是明確的:
getUpdates 擷取 offset 仍由輪詢函式庫控制,因此如果我們需要超出 OpenClaw 重新啟動水位線的平台層級重新傳遞,剩下更深入的一步就是完全耐久的輪詢來源。Webhook 平台可能需要立即 HTTP ack,但仍需要入站去重與耐久出站傳送意圖,因為 Webhook 可能重新傳遞。
傳送脈絡
傳送也以脈絡為基礎:unknown_after_send 中恢復,而不是盲目重播。沒有對帳能力的通道,只有在重複可見訊息是該通道與關係可接受且已記錄的取捨時,才可選擇至少一次重播。目前的 SDK 對帳橋接要求轉接器宣告 reconcileUnknownSend,然後要求 durableFinal.reconcileUnknownSend 將未知項目分類為 sent、not_sent 或 unresolved;只有 not_sent 允許重播,而未解決項目會保持終止狀態,或只重試對帳檢查。
持久性政策必須明確:
required 表示當核心無法寫入持久化意圖時,必須失敗關閉。best_effort 可在持久化不可用時繼續落入後續流程。disabled 會保留舊的直接傳送行為。遷移期間,舊版包裝器與公開相容性輔助程式預設為 disabled;它們不得因為通道有通用輸出轉接器,就推斷為 required。
傳送情境也擁有通道本地的傳送後效果。如果持久傳遞繞過先前附加在通道直接傳送路徑上的本地行為,遷移就不安全。範例包括自我回聲抑制快取、討論串參與標記、原生編輯錨點、模型簽章轉譯,以及平台特定的重複防護。這些效果必須移入傳送轉接器、轉譯轉接器,或具名的傳送情境 hook,該通道才能啟用持久化通用最終傳遞。
傳送輔助程式必須一路將回執傳回呼叫端。持久化包裝器不能吞掉訊息 ID,或以 undefined 取代通道傳遞結果;緩衝式分派器會使用這些 ID 作為討論串錨點、後續編輯、預覽最終化,以及重複抑制。
備援傳送以批次運作,而不是以單一承載運作。靜默回覆重寫、媒體備援、卡片備援,以及分塊投影都可能產生一個以上可傳遞訊息,因此傳送情境必須傳遞完整投影批次,或明確記錄為何只有一個承載有效。
unknown_after_send,直到轉接器完成對帳。
即時情境
預覽、編輯、進度與串流行為應該是一個選擇啟用的生命週期。- Telegram 傳送加上編輯預覽,並在預覽過舊後使用新的最終訊息。
- Discord 傳送加上編輯預覽,並在媒體、錯誤或明確回覆時取消。
- Slack 原生串流,或依討論串形狀使用草稿預覽。
- Mattermost 草稿貼文最終化。
- Matrix 草稿事件最終化,或在不相符時撤回。
- Teams 原生進度串流。
- QQ Bot 串流或累積式備援。
轉接器介面
公開 SDK 目標應為單一子路徑:origin.decode 回傳 OpenClaw 來源中繼資料,核心就必須執行共用的 OpenClaw 回聲述詞。接收轉接器會提供平台事實,例如機器人作者與房間形狀;核心擁有丟棄決策與排序,因此通道不需要重新實作文字篩選器。
來源轉接器:
MessageOrigin。通道只將它轉換為原生傳輸中繼資料,或從原生傳輸中繼資料轉回。Slack 會將此對應到 chat.postMessage({ metadata }) 與傳入的 message.metadata;Matrix 可將它對應到額外事件內容;沒有原生中繼資料的通道,可在那是最佳可用近似方式時使用回執/輸出登錄檔。
能力:
公開 SDK 簡化
新的公開介面應吸收或淘汰這些概念區域:reply-runtimereply-dispatch-runtimereply-referencereply-chunkingreply-payloadinbound-reply-dispatchchannel-reply-pipelineoutbound-runtime的大多數公開用法- 臨時草稿串流生命週期輔助程式
plugin-sdk/channel-message 存在後,引導 Plugin 作者使用它。
與通道回合的關係
runtime.channel.turn.* 應在遷移期間保留。
它應成為相容性轉接器:
channel.turn.runPrepared 一開始也應保留:
channel.turn。在有已發布的 SDK 遷移路徑,以及證明舊 plugins 仍能運作或以清楚版本錯誤失敗的合約測試之前,不應移除它。
相容性護欄
遷移期間,對於現有傳遞回呼除了「傳送此承載」以外還有副作用的任何通道,通用持久傳遞都必須選擇啟用。 舊版進入點預設為非持久:channel.turn.run與dispatchAssembledChannelTurn使用通道的傳遞回呼,除非該通道明確提供已稽核的持久性政策/選項物件。channel.turn.runPrepared保持由通道擁有,直到已準備的分派器明確呼叫傳送情境。- 公開相容性輔助程式,例如
recordInboundSessionAndDispatchReply、dispatchInboundReplyWithBase,以及直接 DM 輔助程式,在呼叫端提供的deliver或reply回呼之前,絕不注入通用持久傳遞。
durable: undefined 表示「非持久」。持久路徑只有透過明確的政策/選項值才會啟用。durable: false 可作為相容性拼法保留,但實作不應要求每個尚未遷移的通道都加入它。
目前的橋接程式碼必須保持持久性決策明確:
- 持久最終遞送會回傳可辨別聯集狀態。
handled_visible和handled_no_send是終止狀態;unsupported和not_applicable可以 回退到由通道擁有的遞送;failed會傳遞傳送失敗。 - 通用持久最終遞送受轉接器能力控管,例如 靜默遞送、回覆目標保留、原生引用保留,以及 訊息傳送掛鉤。若缺少同等行為,應選擇由通道擁有的遞送, 而不是會改變使用者可見行為的通用傳送。
- 以佇列支援的持久傳送會公開遞送意圖參照。現有
pendingFinalDelivery*工作階段欄位可以在轉換期間攜帶意圖 id; 最終狀態是MessageSendIntent儲存,而不是凍結的 回覆文字加上臨時脈絡欄位。
- 通用傳送轉接器會執行與舊直接路徑相同的算繪與傳輸行為。
- 本機傳送後副作用會透過傳送脈絡保留。
- 轉接器會回傳收據或遞送結果,且包含所有平台訊息 id。
- 已準備的分派器路徑要麼呼叫新的傳送脈絡,要麼持續記錄為不在持久保證範圍內。
- 回退遞送會處理每個投影後的承載,而不只是第一個。
- 持久回退遞送會將整個投影後承載陣列記錄為一個可重播意圖或批次計畫。
- iMessage 監控器遞送會在成功傳送後,將已傳送訊息記錄在 echo 快取中。持久最終傳送仍必須填入該快取,否則 OpenClaw 可能會將自己的最終回覆重新擷取為傳入使用者訊息。
- Tlon 會附加可選的模型簽章,並在群組回覆後記錄已參與的討論串。通用持久遞送不得略過這些效果;要麼將它們移入 Tlon 算繪/傳送/完成轉接器,要麼讓 Tlon 維持在由通道擁有的路徑。
- Discord 和其他已準備的分派器已經擁有直接遞送與預覽行為。除非其已準備的分派器明確透過傳送脈絡路由最終訊息,否則它們不受組裝回合持久保證涵蓋。
- Telegram 靜默回退遞送必須遞送完整的投影後承載陣列。單一承載捷徑可能會在投影後丟棄額外的回退承載。
- LINE、Zalo、Nostr,以及其他現有組裝/輔助路徑可能 具有回覆權杖處理、媒體代理、已傳送訊息快取、載入/狀態 清理,或僅回呼目標。在這些語義由傳送轉接器表示並經測試驗證之前, 它們會維持在由通道擁有的遞送。
- 直接 DM 輔助程式可能有一個回覆回呼,且它是唯一正確的傳輸
目標。通用對外傳送不得從
OriginatingTo或To猜測並略過 該回呼。 - OpenClaw Gateway 失敗輸出必須維持讓人類可見,但標記為
bot 所撰寫的聊天室 echo 必須在
allowBots授權之前丟棄。 通道不得以可見文字前綴篩選器實作這點,除非作為 短期緊急權宜措施;持久合約是結構化來源中繼資料。
內部儲存
持久佇列應儲存訊息傳送意圖,而不是回覆承載。失敗類別
通道轉接器會將傳輸失敗分類為封閉類別:- 重試
transient和rate_limit。 - 除非存在算繪回退,否則不要重試
invalid_payload。 - 在設定變更之前,不要重試
auth或permission。 - 對於
not_found,當通道宣告安全時,讓即時完成從編輯回退到全新傳送。 - 對於
conflict,使用收據/idempotency 規則判斷訊息是否已存在。 - 在轉接器可能已完成平台 I/O 之後、收據提交之前發生的任何錯誤,除非轉接器能證明平台操作並未發生,否則都會變成
unknown_after_send。
通道對應
| 通道 | 目標遷移 |
|---|---|
| Telegram | 接收確認政策加上持久化的最終傳送。即時配接器負責傳送與編輯預覽、過期預覽的最終傳送、主題、引用回覆預覽略過、媒體備援,以及 retry-after 處理。 |
| Discord | 傳送配接器包裝現有的持久化酬載傳遞。即時配接器負責草稿編輯、進度草稿、媒體/錯誤預覽取消、回覆目標保留,以及訊息 ID 回執。稽核共用聊天室中由 bot 產生的 Gateway 失敗回音;如果 Discord 無法在一般訊息上承載來源中繼資料,請使用出站登錄表或其他原生等效機制。 |
| Slack | 傳送配接器處理一般聊天貼文。當執行緒形態支援時,即時配接器選擇原生串流,否則使用草稿預覽。回執會保留執行緒時間戳。來源配接器將 OpenClaw Gateway 失敗對應到 Slack chat.postMessage.metadata,並在 allowBots 授權之前丟棄已標記的 bot 聊天室回音。 |
| 傳送配接器負責文字/媒體傳送與持久化的最終意圖。接收配接器處理群組提及與傳送者身分。即時配接器可以暫時不存在,直到 WhatsApp 擁有可編輯的傳輸。 | |
| Matrix | 即時配接器負責草稿事件編輯、最終化、遮除、加密媒體限制,以及回覆目標不相符備援。接收配接器負責加密事件補水與去重。來源配接器應將 OpenClaw Gateway 失敗來源編碼到 Matrix 事件內容中,並在 allowBots 處理之前丟棄已設定 bot 的聊天室回音。 |
| Mattermost | 即時配接器負責單一草稿貼文、進度/工具摺疊、就地最終化,以及全新傳送備援。 |
| Microsoft Teams | 即時配接器負責原生進度與區塊串流行為。傳送配接器負責活動與附件/卡片回執。 |
| Feishu | 算繪配接器負責文字/卡片/原始算繪。即時配接器負責串流卡片與重複最終內容抑制。傳送配接器負責留言、主題工作階段、媒體,以及語音抑制。 |
| QQ Bot | 即時配接器負責 C2C 串流、累加器逾時,以及備援最終傳送。算繪配接器負責媒體標籤與文字轉語音。 |
| Signal | 簡單接收加上傳送配接器。除非 signal-cli 加入可靠的編輯支援,否則不使用即時配接器。 |
| iMessage | 簡單接收加上傳送配接器。在持久化最終內容可以略過監視器傳遞之前,iMessage 傳送必須保留監視器回音快取填入。 |
| Google Chat | 簡單接收加上傳送配接器,執行緒關聯對應到空間與執行緒 ID。稽核 allowBots=true 聊天室對已標記 OpenClaw Gateway 失敗回音的行為。 |
| LINE | 簡單接收加上傳送配接器,回覆權杖限制建模為目標/關聯能力。 |
| Nextcloud Talk | SDK 接收橋接加上傳送配接器。 |
| IRC | 簡單接收加上傳送配接器,沒有持久化編輯回執。 |
| Nostr | 加密私訊的接收加上傳送配接器;回執是事件 ID。 |
| QA 通道 | 接收、傳送、即時、重試與復原行為的合約測試配接器。 |
| Synology Chat | 簡單接收加上傳送配接器。 |
| Tlon | 在啟用通用持久化最終傳遞之前,傳送配接器必須保留模型簽章算繪與已參與執行緒追蹤。 |
| Twitch | 簡單接收加上傳送配接器,具備速率限制分類。 |
| Zalo | 簡單接收加上傳送配接器。 |
| Zalo Personal | 簡單接收加上傳送配接器。 |
遷移計畫
第 1 階段:內部訊息領域
- 新增
src/channels/message/*型別,用於訊息、目標、關聯、 來源、回執、能力、持久化意圖、接收內容脈絡、傳送 內容脈絡、即時內容脈絡,以及失敗類別。 - 將
origin?: MessageOrigin加入目前回覆傳遞使用的遷移橋接酬載型別, 然後隨著重構取代回覆酬載,將該欄位移到ChannelMessage和算繪後的 訊息型別。 - 在配接器與測試證明其形態之前,將其保持為內部使用。
- 為狀態轉換與序列化加入純單元測試。
第 2 階段:持久化傳送核心
- 將現有出站佇列從回覆酬載持久化移到持久化的 訊息傳送意圖。
- 讓持久化傳送意圖承載投影後的酬載陣列或批次計畫,而不 只是單一回覆酬載。
- 透過相容性轉換保留目前的佇列復原行為。
- 讓
deliverOutboundPayloads呼叫messages.send。 - 在配接器宣告重播安全之後,讓最終傳送持久化成為預設值,並在新的訊息生命週期中無法寫入持久化意圖時封閉失敗。現有的通道回合與 SDK 相容性路徑在此階段預設仍維持直接傳送。
- 一致地記錄回執。
- 將回執與傳遞結果回傳給原始分派器呼叫端,而不是將持久化傳送視為終止性的副作用。
- 透過持久化傳送意圖保留訊息來源,讓復原、重播與 分塊傳送保留 OpenClaw 操作來源。
第 3 階段:通道回合橋接
- 在
messages.receive和messages.send之上重新實作channel.turn.run與dispatchAssembledChannelTurn。 - 保持目前的事實型別穩定。
- 預設保留舊有行為。只有當配接器明確選擇加入具備重播安全性的持久化政策時,組裝回合通道才會變為持久化。
- 將
durable: false保留為相容性逃生口,用於最終化原生編輯且尚無法安全重播的路徑,但不要依賴false標記來保護尚未遷移的通道。 - 只有在新的訊息生命週期中,且通道對應證明通用傳送路徑保留舊通道傳遞語意之後,才預設組裝回合持久化。
第 4 階段:已準備分派器橋接
- 將
deliverDurableInboundReplyPayload替換為傳送情境橋接。 - 保留舊 helper 作為 wrapper。
- 先移植 Telegram、WhatsApp、Slack、Signal、iMessage 和 Discord,因為 它們已有 durable-final 工作或較簡單的傳送路徑。
- 在每個已準備的 dispatcher 明確選擇加入傳送情境之前,都將其視為未涵蓋。 文件與 changelog 項目必須說「已組裝的頻道回合」,或指名已遷移的頻道路徑, 而不是宣稱所有自動最終回覆。
- 保持
recordInboundSessionAndDispatchReply、direct-DM helpers,以及類似的 公開相容性 helpers 行為不變。它們日後可以公開明確的傳送情境選擇加入, 但不得在呼叫端擁有的 delivery callback 之前,自動嘗試通用 durable delivery。
階段 5:統一的即時生命週期
- 建置
messages.live,並提供兩個 proof adapters:- Telegram:用於傳送、編輯,以及過期最終傳送。
- Matrix:用於草稿完成與 redact 後援。
- 接著遷移 Discord、Slack、Mattermost、Teams、QQ Bot 和 Feishu。
- 只有在每個頻道都有同等測試後,才刪除重複的預覽完成程式碼。
階段 6:公開 SDK
- 新增
openclaw/plugin-sdk/channel-message。 - 將其記錄為偏好的頻道 Plugin API。
- 更新套件 exports、entrypoint inventory、產生的 API baselines,以及 Plugin SDK 文件。
- 在 channel-message SDK 表面納入
MessageOrigin、origin encode/decode hooks, 以及共用的shouldDropOpenClawEchopredicate。 - 保留舊 subpaths 的相容性 wrappers。
- 在隨附 Plugin 都已遷移後,於文件中將以 reply 命名的 SDK helpers 標記為 deprecated。
階段 7:所有傳送者
將所有非回覆的 outbound producers 移到messages.send:
- cron 與 heartbeat 通知
- 任務完成
- hook 結果
- approval prompts 與 approval results
- message tool 傳送
- subagent 完成公告
- 明確的 CLI 或 Control UI 傳送
- automation/broadcast 路徑
階段 8:淘汰 Turn
- 保留
channel.turn作為 wrapper,至少維持一個相容性窗口。 - 發布遷移說明。
- 針對舊 imports 執行 Plugin SDK 相容性測試。
- 只有在沒有隨附 Plugin 需要它們,且第三方合約已有穩定替代方案後, 才移除或隱藏舊的內部 helpers。
測試計畫
單元測試:- Durable send intent 序列化與復原。
- Idempotency key 重用與重複抑制。
- Receipt commit 與 replay skip。
- 當 adapter 支援 reconciliation 時,
unknown_after_send復原會在 replay 前先 reconcile。 - 失敗分類政策。
- Receive ack policy sequencing。
- reply、followup、system 和 broadcast sends 的 relation mapping。
- Gateway-failure origin factory 與
shouldDropOpenClawEchopredicate。 - origin 在 payload normalization、chunking、durable queue serialization,以及 recovery 中的保留。
channel.turn.runsimple adapter 仍會記錄並傳送。- 舊版 assembled-turn delivery 不會變成 durable,除非該頻道明確選擇加入。
channel.turn.runPreparedbridge 仍會記錄並完成。- 公開相容性 helpers 預設會呼叫呼叫端擁有的 delivery callbacks, 且不會在這些 callbacks 之前進行 generic-send。
- Durable fallback delivery 在重新啟動後會 replay 整個 projected payload array, 且不能在早期 crash 後留下後續 payloads 未記錄。
- Durable assembled-turn delivery 會將平台 message ids 回傳給 buffered dispatcher。
- 當 durable delivery 停用或不可用時,custom delivery hooks 仍會回傳平台 message ids。
- 最終回覆在 assistant completion 與平台傳送之間重新啟動後仍能保留。
- Preview draft 在允許時就地完成。
- 當 media/error/reply-target mismatch 需要一般 delivery 時,preview draft 會被取消或 redacted。
- Block streaming 和 preview streaming 不會同時 delivery 相同文字。
- 早期 streaming 的 media 不會在最終 delivery 中重複。
- Telegram topic reply 搭配 polling ack,延遲到 receive context 的 safe completed watermark。
- Telegram polling recovery 針對已接受但未 delivery updates,由持久化 safe-completed offset model 涵蓋。
- Telegram stale preview 會傳送新的 final 並清理 preview。
- Telegram silent fallback 會傳送每個 projected fallback payload。
- Telegram silent fallback durability 會原子地記錄完整 projected fallback array, 而不是在每次 loop iteration 記錄單一 single-payload durable intent。
- Discord 在 media/error/explicit reply 時取消 preview。
- Discord prepared dispatcher finals 會先透過傳送情境路由, 文件或 changelog 才能宣稱 Discord final-reply durability。
- iMessage durable final sends 會填入 monitor sent-message echo cache。
- LINE、Zalo 和 Nostr 舊版 delivery paths 在其 adapter parity tests 存在之前, 不會被 generic durable send 繞過。
- Direct-DM/Nostr callback delivery 仍是權威,除非已明確遷移到完整 message target 與 replay-safe send adapter。
- Slack 帶標籤的 OpenClaw gateway failure messages 仍維持可見 outbound,
帶標籤的 bot-room echoes 會在
allowBots前 drop,而具有相同可見文字的 未標籤 bot messages 仍遵循一般 bot authorization。 - Slack native stream fallback 會在 top-level DMs 中 fallback 到 draft preview。
- Matrix preview finalization 與 redaction fallback。
- Matrix 來自已設定 bot accounts、帶標籤的 OpenClaw gateway-failure room echoes
會在
allowBotshandling 前 drop。 - Discord 與 Google Chat shared-room gateway-failure cascade audits 會涵蓋
allowBotsmodes,然後才宣稱那裡有 generic protection。 - Mattermost draft finalization 與 fresh-send fallback。
- Teams native progress finalization。
- Feishu duplicate final suppression。
- QQ Bot accumulator timeout fallback。
- Tlon durable final sends 會保留 model-signature rendering 與 participated thread tracking。
- WhatsApp、Signal、iMessage、Google Chat、LINE、IRC、Nostr、Nextcloud Talk、 Synology Chat、Tlon、Twitch、Zalo 和 Zalo Personal simple durable final sends。
- 開發期間使用目標 Vitest 檔案。
- 在 Testbox 中針對完整變更表面執行
pnpm check:changed。 - 在落地完整 refactor 前,或公開 SDK/export 變更後,在 Testbox 中執行更廣泛的
pnpm check。 - 在移除相容性 wrappers 前,至少針對一個支援編輯的頻道與一個簡單 send-only 頻道, 進行 live 或 qa-channel smoke。
未決問題
- Telegram 是否最終應以完全 durable polling source 取代 grammY runner source, 讓它能控制平台層級 redelivery,而不只是 OpenClaw 的持久化 restart watermark。
- durable live preview state 應儲存在與 final send intent 相同的 queue record, 還是儲存在 sibling live-state store。
plugin-sdk/channel-message發布後,相容性 wrappers 要繼續記錄在文件中多久。- 第三方 Plugin 是否應直接實作 receive adapters,還是只透過
defineChannelMessageAdapter提供 normalize/send/live hooks。 - 哪些 receipt fields 可以安全公開在公開 SDK 中,哪些屬於 internal runtime state。
- self-echo caches 與 participated-thread markers 這類 side effects 應建模為 send-context hooks、adapter-owned finalize steps,還是 receipt subscribers。
- 哪些頻道有 native origin metadata、哪些需要持久化 outbound registries, 以及哪些無法提供可靠的 cross-bot echo suppression。
驗收標準
- 每個隨附訊息頻道都會透過
messages.send傳送最終可見輸出。 - 每個 inbound message channel 都會透過
messages.receive或已記錄的相容性 wrapper 進入。 - 每個 preview/edit/stream channel 都會使用
messages.live進行 draft state 與 finalization。 channel.turn只是 wrapper。- 以 reply 命名的 SDK helpers 是相容性 exports,而不是建議路徑。
- Durable recovery 可以在重新啟動後 replay pending final sends,而不遺失最終回應或重複已 committed sends; platform outcome unknown 的 sends 會在 replay 前 reconcile,或在該 adapter 文件中記錄為 at-least-once。
- 當 durable intent 無法寫入時,durable final sends 會 fail closed, 除非呼叫端明確選擇已記錄的 non-durable mode。
- Legacy channel-turn 與 SDK 相容性 helpers 預設為直接的 channel-owned delivery; generic durable send 只能明確 opt-in。
- Receipts 會保留 multi-part deliveries 的所有平台 message ids, 以及用於 threading/edit convenience 的 primary id。
- Durable wrappers 會在替換 direct delivery callbacks 前保留 channel-local side effects。
- Prepared dispatchers 在其 final delivery path 明確使用傳送情境前,不會被計為 durable。
- Fallback delivery 會處理每個 projected payload。
- Durable fallback delivery 會將每個 projected payload 記錄在一個可 replay 的 intent 或 batch plan 中。
- OpenClaw-originated gateway failure output 對人類可見,但在宣告支援 origin contract 的頻道上, 帶標籤且由 bot 撰寫的 room echoes 會在 bot authorization 前被 drop。
- 文件會說明 send、receive、live、state、receipts、relations、failure policy、migration, 以及 test coverage。