狀態
已針對共享代理、命令列介面、外掛能力與出站傳遞介面實作:ReplyPayload.presentation承載語意化訊息 UI。ReplyPayload.delivery.pin承載已傳送訊息的釘選要求。- 共享訊息動作公開
presentation、delivery與pin,而不是提供者原生的components、blocks、buttons或card。 - 核心會透過外掛宣告的出站能力轉譯或自動降級呈現內容。
- Discord、Slack、Telegram、Mattermost、MS Teams 與 Feishu 轉譯器會消耗通用合約。
- Discord 頻道控制平面程式碼不再匯入 Carbon 支援的 UI 容器。
問題
頻道 UI 目前分散在數個彼此不相容的介面上:- 核心透過
buildCrossContextComponents擁有 Discord 形狀的跨脈絡轉譯器掛鉤。 - Discord
channel.ts可透過DiscordUiContainer匯入原生 Carbon UI,這會把執行階段 UI 相依性拉進頻道外掛控制平面。 - 代理與命令列介面會公開原生酬載逃生口,例如 Discord
components、Slackblocks、Telegram 或 Mattermostbuttons,以及 Teams 或 Feishucard。 ReplyPayload.channelData同時承載傳輸提示與原生 UI 信封。- 通用
interactive模型已存在,但它比 Discord、Slack、Teams、Feishu、LINE、Telegram 與 Mattermost 已使用的更豐富版面還要狹窄。
目標
- 核心根據宣告能力,為訊息決定最佳語意呈現。
- 外掛宣告能力,並將語意呈現轉譯為原生傳輸酬載。
- Web 控制 UI 與聊天原生 UI 維持分離。
- 原生頻道酬載不會透過共享代理或命令列介面訊息介面公開。
- 不支援的呈現功能會自動降級為最佳文字表示。
- 釘選已傳送訊息等傳遞行為是通用傳遞中繼資料,不是呈現。
非目標
- 不為
buildCrossContextComponents提供向後相容墊片。 - 不為
components、blocks、buttons或card提供公開原生逃生口。 - 核心不匯入頻道原生 UI 函式庫。
- 不為內建頻道提供提供者特定 SDK 介面。
目標模型
在ReplyPayload 新增核心擁有的 presentation 欄位。
interactive 會在遷移期間成為 presentation 的子集:
interactive文字區塊對應到presentation.blocks[].type = "text"。interactive按鈕區塊對應到presentation.blocks[].type = "buttons"。interactive選擇區塊對應到presentation.blocks[].type = "select"。
presentation;interactive 仍是現有回覆產生器的內部舊版解析/轉譯輔助工具。
公開的產生器端 API 將 interactive 視為已棄用。執行階段支援仍會保留,讓現有核准輔助工具與較舊外掛在新程式碼輸出 presentation 時仍能繼續運作。
傳遞中繼資料
新增核心擁有的delivery 欄位,用於非 UI 的傳送行為。
delivery.pin = true表示釘選第一則成功傳遞的訊息。notify預設為false。required預設為false;不支援的頻道或釘選失敗會自動降級為繼續傳遞。- 手動
pin、unpin與list-pins訊息動作會保留給現有訊息使用。
channelData.telegram.pin = true 移至 delivery.pin = true。
執行階段能力合約
將呈現與傳遞轉譯掛鉤新增到執行階段出站配接器,而不是控制平面頻道外掛。- 解析目標頻道與執行階段配接器。
- 要求呈現能力。
- 在轉譯前降級不支援的區塊並套用通用能力限制。
- 呼叫
renderPresentation。 - 若沒有轉譯器,將呈現轉換為文字備援。
- 成功傳送後,若要求且支援
delivery.pin,呼叫pinDeliveredMessage。
頻道對應
Discord:- 在僅執行階段模組中,將
presentation轉譯為 components v2 與 Carbon 容器。 - 將強調色輔助工具保留在輕量模組中。
- 從頻道外掛控制平面程式碼移除
DiscordUiContainer匯入。
- 將
presentation轉譯為 Block Kit。 - 移除代理與命令列介面的
blocks輸入。
- 將文字、脈絡與分隔線轉譯為文字。
- 在已設定且目標介面允許時,將動作與選擇轉譯為行內鍵盤。
- 停用行內按鈕時使用文字備援。
- 將 ACP 主題釘選移至
delivery.pin。
- 在已設定時,將動作轉譯為互動式按鈕。
- 將其他區塊轉譯為文字備援。
- 將
presentation轉譯為 Adaptive Cards。 - 保留手動釘選/取消釘選/列出釘選動作。
- 若 Graph 對目標對話的支援可靠,可選擇實作
pinDeliveredMessage。
- 將
presentation轉譯為互動式卡片。 - 保留手動釘選/取消釘選/列出釘選動作。
- 若 API 行為可靠,可選擇實作
pinDeliveredMessage以釘選已傳送訊息。
- 盡可能將
presentation轉譯為 Flex 或範本訊息。 - 對不支援的區塊退回文字。
- 從
channelData移除 LINE UI 酬載。
- 使用保守格式將呈現轉換為文字。
重構步驟
- 重新套用 Discord 發行修正,將
ui-colors.ts從 Carbon 支援的 UI 拆出,並從extensions/discord/src/channel.ts移除DiscordUiContainer。 - 將
presentation與delivery新增到ReplyPayload、出站酬載正規化、傳遞摘要與掛鉤酬載。 - 在狹窄的 SDK/執行階段子路徑中新增
MessagePresentationschema 與解析器輔助工具。 - 以語意呈現能力取代訊息能力
buttons、cards、components與blocks。 - 新增呈現轉譯與傳遞釘選的執行階段出站配接器掛鉤。
- 以
buildCrossContextPresentation取代跨脈絡元件建構。 - 刪除
src/infra/outbound/channel-adapters.ts,並從頻道外掛型別移除buildCrossContextComponents。 - 將
maybeApplyCrossContextMarker改為附加presentation,而不是原生參數。 - 更新外掛分派傳送路徑,使其只消耗語意呈現與傳遞中繼資料。
- 移除代理與命令列介面的原生酬載參數:
components、blocks、buttons與card。 - 移除建立原生訊息工具 schema 的 SDK 輔助工具,改以呈現 schema 輔助工具取代。
- 從
channelData移除 UI/原生信封;在逐一審查剩餘欄位前,只保留傳輸中繼資料。 - 遷移 Discord、Slack、Telegram、Mattermost、MS Teams、Feishu 與 LINE 轉譯器。
- 更新訊息命令列介面、頻道頁面、外掛 SDK 與能力指南的文件。
- 針對 Discord 與受影響的頻道進入點執行匯入扇出分析。
channelData 傳輸信封的更深入內部清理。若我們想取得超出型別/測試閘門的量化匯入扇出數字,步驟 15 仍是後續驗證。
測試
新增或更新:- 呈現正規化測試。
- 不支援區塊的呈現自動降級測試。
- 外掛分派與核心傳遞路徑的跨脈絡標記測試。
- Discord、Slack、Telegram、Mattermost、MS Teams、Feishu、LINE 與文字備援的頻道轉譯矩陣測試。
- 證明原生欄位已移除的訊息工具 schema 測試。
- 證明原生旗標已移除的命令列介面測試。
- 涵蓋 Carbon 的 Discord 進入點匯入延遲載入迴歸測試。
- 涵蓋 Telegram 與通用備援的傳遞釘選測試。
開放問題
delivery.pin第一階段應該為 Discord、Slack、MS Teams 與 Feishu 實作,還是先只實作 Telegram?delivery最終是否應吸收replyToId、replyToCurrent、silent與audioAsVoice等現有欄位,或維持聚焦於傳送後行為?- 呈現是否應直接支援圖片或檔案參照,還是目前先讓媒體與 UI 版面維持分離?