components、Slack
blocks、Telegram buttons、Teams card 或 Feishu card)新增到共享的
訊息工具。這些是由通道外掛擁有的轉譯器輸出。
合約
外掛作者從以下位置匯入公開合約:action.type: "command"會透過核心的命令 路徑執行原生斜線命令。將此用於內建命令按鈕和選單。action.type: "callback"會透過通道的 互動路徑攜帶不透明的外掛資料。通道外掛不得將回呼資料重新解讀為斜線 命令。value是舊版不透明回呼值。新的控制項應使用action, 讓通道外掛可以對應命令和回呼,而不必從文字猜測。url是連結按鈕。它可以在沒有value的情況下存在。webApp描述通道原生的網頁應用程式按鈕。Telegram 會將此轉譯 為web_app,且僅在私人聊天中支援。為了相容性,web_app仍會 在寬鬆 JSON 酬載中被接受,但 TypeScript 產生器 應使用webApp。label是必填,也會用於文字後援。style是建議性質。轉譯器應將不支援的樣式對應到安全的 預設值,而不是讓傳送失敗。priority是選用。當通道宣告動作限制且控制項 必須被捨棄時,核心會優先保留較高優先度的按鈕,並保留 相同優先度按鈕之間的原始順序。當所有控制項都能容納時,會保留作者指定的 順序。disabled是選用。通道必須透過supportsDisabled選擇加入;否則 核心會將停用的控制項降級為非互動後援文字。停用的按鈕在後援文字中一律只轉譯標籤, 即使它帶有command動作。reusable是選用。支援可重複使用原生回呼的通道可以 在成功互動後保留動作可用。將它用於 可重複或冪等的動作,例如重新整理、檢查或更多詳細資料; 一般一次性的核准和破壞性動作則不要設定。
options[].action與按鈕action具有相同的命令/回呼意義。options[].value是舊版選取的應用程式值。placeholder是建議性質,沒有原生 選單支援的通道可能會忽略它。- 如果通道不支援選單,後援文字會列出標籤。
產生器範例
簡單卡片:轉譯器合約
通道外掛在其外送配接器上宣告轉譯支援:limits 描述核心可在呼叫
轉譯器前調整的通用封套:
核心轉譯流程
當ReplyPayload 或訊息動作包含 presentation 時,核心會:
- 正規化呈現酬載。
- 解析目標通道的外送配接器。
- 讀取
presentationCapabilities。 - 當配接器宣告限制時,套用通用能力限制,例如動作數量、標籤長度和 選單選項數量。
- 當配接器可以轉譯酬載時,呼叫
renderPresentation。 - 當配接器不存在或無法轉譯時,後援為保守文字。
- 透過一般通道傳遞路徑傳送產生的酬載。
- 在第一則成功
傳送的訊息之後,套用傳遞中繼資料,例如
delivery.pin。
降級規則
呈現必須能安全地傳送到能力受限的通道。 後援文字包含:title作為第一行text區塊作為一般段落context區塊作為精簡脈絡行divider區塊作為視覺分隔線- 按鈕標籤,包括連結按鈕的 URL
- 選單選項標籤
按鈕值後援可見性
當通道無法轉譯互動控制項時,按鈕和選單值 會後援為純文字。後援行為會保留可用性,同時 保持不透明回呼資料的私密性:command型別的動作 會轉譯為label: \command“,讓使用者可以 複製命令並在通道輸入中手動執行。callback型別的動作 和舊版value欄位會轉譯為 僅標籤。不透明回呼值不會在後援文字中暴露。url/webApp按鈕會在按鈕 標籤旁轉譯 URL 文字,因為 URL 是面向使用者的。- 選單選項 會轉譯為僅標籤。底層選項值不會 在後援文字中暴露。
- 停用行內按鈕的 Telegram 會傳送文字後援。
- 不支援選單的通道會將選單選項列為文字。
- 僅 URL 的按鈕會變成原生連結按鈕或後援 URL 行。
- 選用的釘選失敗不會讓已傳遞的訊息失敗。
delivery.pin.required: true;如果要求釘選為
必須且通道無法釘選已傳送的訊息,傳遞會回報失敗。
提供者對應
目前內建的轉譯器:| 通道 | 原生呈現目標 | 備註 |
|---|---|---|
| Discord | 元件與元件容器 | 為現有提供者原生酬載產生器保留舊版 channelData.discord.components,但新的共用傳送應使用 presentation。 |
| Feishu | 互動式卡片 | 卡片標頭可以使用 title;本文會避免重複該標題。 |
| Matrix | 文字後援加上結構化事件欄位 | 按鈕/選單會宣告為支援,但每個區塊目前都會呈現為 renderMessagePresentationFallbackText 輸出,並放在 com.openclaw.presentation 事件欄位中,而不是原生互動小工具。 |
| Mattermost | 文字加上互動式屬性 | 不支援選單與分隔線;這些區塊會降級為文字。 |
| Microsoft Teams | Adaptive Cards | 同時提供純 message 文字與卡片時,文字會包含在卡片中。不支援選單、樣式與停用狀態。 |
| Slack | Block Kit | 為現有提供者原生酬載產生器保留舊版 channelData.slack.blocks,但新的共用傳送應使用 presentation。 |
| Telegram | 文字加上行內鍵盤 | 按鈕/選單需要目標介面具備行內按鈕能力;否則會使用文字後援。 |
| 純文字通道 | 文字後援 | 沒有呈現器的通道仍會取得可讀輸出。 |
Presentation 與 InteractiveReply
InteractiveReply 是核准與互動輔助工具使用的較舊內部子集。
它支援:
- 文字
- 按鈕
- 選單
MessagePresentation 是標準的共用傳送合約。它新增:
- 標題
- 語氣
- 脈絡
- 分隔線
- 僅限 URL 的按鈕
- 透過
ReplyPayload.delivery提供的通用傳遞中繼資料
openclaw/plugin-sdk/interactive-runtime 中的輔助工具:
OC_I18N_900011
新程式碼應直接接受或產生 MessagePresentation。現有的
interactive 酬載是 presentation 已棄用的子集;執行階段
仍支援較舊的產生器。
值得了解的未棄用輔助工具:
normalizeMessagePresentation(raw)/hasMessagePresentationBlocks(value)會驗證未型別化酬載並將其強制轉換為MessagePresentation(例如來自命令列介面--presentation旗標的 JSON)。isMessagePresentationInteractiveBlock(block)會將區塊縮窄為buttons|select聯集。resolveMessagePresentationActionValue(action)/resolveMessagePresentationControlValue(control)會讀取action上有效的 命令/回呼值;resolveMessagePresentationControlValue會後援到舊版value欄位。
InteractiveReply* 型別與轉換輔助工具在 SDK 中標記為
@deprecated:
InteractiveReply,InteractiveReplyBlock,InteractiveReplyButton,InteractiveReplyOption,InteractiveReplySelectBlock, andInteractiveReplyTextBlocknormalizeInteractiveReply(...)hasInteractiveReplyBlocks(...)interactiveReplyToPresentation(...)presentationToInteractiveReply(...)presentationToInteractiveControlsReply(...)resolveInteractiveTextFallback(...)reduceInteractiveReply(...)
presentationToInteractiveReply(...) 與
presentationToInteractiveControlsReply(...) 仍可作為舊版通道實作的呈現器
橋接使用。新的產生器程式碼不應呼叫它們;請傳送 presentation,並讓核心/通道調整處理呈現。
核准輔助工具也有以 presentation 為優先的替代項目:
- 使用
buildApprovalPresentationFromActionDescriptors(...),而不是buildApprovalInteractiveReplyFromActionDescriptors(...) - 使用
buildApprovalPresentation(...),而不是buildApprovalInteractiveReply(...) - 使用
buildExecApprovalPresentation(...),而不是buildExecApprovalInteractiveReply(...)
renderMessagePresentationFallbackText(...) 對沒有文字後援的
presentation 區塊會回傳空字串,例如只有分隔線的
presentation。需要非空傳送本文的傳輸可以傳入
emptyFallback 來選擇使用最小本文,而不變更預設後援
合約。
傳遞釘選
釘選是傳遞行為,不是 presentation。請使用delivery.pin,而不是
channelData.telegram.pin 等提供者原生欄位。
語意:
pin: true會釘選第一則成功傳遞的訊息。pin.notify預設為false。pin.required預設為false。- 選用釘選失敗會降級,並保留已傳送的訊息。
- 必要釘選失敗會使傳遞失敗。
- 分塊訊息會釘選第一個已傳遞的分塊,而不是尾端分塊。
pin、unpin 與 pins 訊息動作,
前提是提供者支援這些操作。
外掛作者檢查清單
- 當通道可以呈現語意 presentation,或可安全降級時,從
describeMessageTool(...)宣告presentation。 - 將
presentationCapabilities新增至執行階段輸出配接器。 - 在執行階段程式碼中實作
renderPresentation,不要在控制平面外掛 設定程式碼中實作。 - 讓原生 UI 函式庫遠離熱門設定/目錄路徑。
- 已知時,在
presentationCapabilities.limits上宣告通用能力限制。 - 在呈現器與測試中保留最終平台限制。
- 為不支援的按鈕、選單、URL 按鈕、標題/文字重複,以及混合
message加上presentation的傳送新增後援測試。 - 只有在提供者可以釘選已傳送訊息 ID 時,才透過
deliveryCapabilities.pin與pinDeliveredMessage新增傳遞釘選支援。 - 不要透過共用訊息動作結構描述公開新的提供者原生卡片/區塊/元件/按鈕欄位。