ステータス
共有エージェント、CLI、Plugin 機能、および送信配信サーフェスに実装済みです。ReplyPayload.presentationはセマンティックなメッセージ UI を保持します。ReplyPayload.delivery.pinは送信済みメッセージのピン留め要求を保持します。- 共有メッセージアクションでは、プロバイダー固有の
components、blocks、buttons、cardの代わりに、presentation、delivery、pinを公開します。 - コアは、Plugin が宣言した送信機能を通じてプレゼンテーションをレンダリングするか、自動的にデグレードします。
- Discord、Slack、Telegram、Mattermost、MS Teams、Feishu のレンダラーは汎用コントラクトを使用します。
- Discord チャンネルのコントロールプレーンコードは、Carbon ベースの UI コンテナーをインポートしなくなりました。
問題
チャンネル UI は現在、互換性のない複数のサーフェスに分かれています。- コアは、
buildCrossContextComponentsを通じて Discord 形式のクロスコンテキストレンダラーフックを所有しています。 - Discord の
channel.tsは、DiscordUiContainerを通じてネイティブ Carbon UI をインポートできるため、ランタイム UI の依存関係がチャンネル Plugin のコントロールプレーンに取り込まれます。 - エージェントと CLI は、Discord の
components、Slack のblocks、Telegram または Mattermost のbuttons、Teams または Feishu のcardなど、ネイティブペイロードへのエスケープハッチを公開しています。 ReplyPayload.channelDataは、トランスポートヒントとネイティブ UI エンベロープの両方を保持します。- 汎用の
interactiveモデルは存在しますが、Discord、Slack、Teams、Feishu、LINE、Telegram、Mattermost ですでに使用されている、よりリッチなレイアウトよりも限定的です。
目標
- コアは、宣言された機能からメッセージに最適なセマンティックプレゼンテーションを決定します。
- 拡張機能は機能を宣言し、セマンティックプレゼンテーションをネイティブのトランスポートペイロードにレンダリングします。
- Web Control UI はチャットのネイティブ UI とは分離したままにします。
- ネイティブのチャンネルペイロードを、共有エージェントまたは CLI のメッセージサーフェスを通じて公開しません。
- サポートされていないプレゼンテーション機能は、最適なテキスト表現へ自動的にデグレードします。
- 送信済みメッセージのピン留めなどの配信動作は、プレゼンテーションではなく汎用の配信メタデータです。
対象外
buildCrossContextComponentsの後方互換性シムは提供しません。components、blocks、buttons、cardに対する公開ネイティブエスケープハッチは提供しません。- コアからチャンネルネイティブ UI ライブラリをインポートしません。
- バンドルされたチャンネル向けのプロバイダー固有 SDK シームは提供しません。
ターゲットモデル
コアが所有するpresentation フィールドを ReplyPayload に追加します。
interactive は presentation のサブセットになります。
interactiveテキストブロックはpresentation.blocks[].type = "text"にマッピングされます。interactiveボタンブロックはpresentation.blocks[].type = "buttons"にマッピングされます。interactive選択ブロックはpresentation.blocks[].type = "select"にマッピングされます。
presentation を使用します。interactive は、既存の返信生成元向けの内部レガシーパーサー/レンダリングヘルパーとして残ります。
公開される生成元向け API では、interactive を非推奨として扱います。既存の承認ヘルパーと古い Plugin が引き続き
動作するよう、ランタイムサポートは維持しますが、新しいコードは presentation を出力します。
配信メタデータ
UI ではない送信動作のために、コアが所有するdelivery フィールドを追加します。
delivery.pin = trueは、最初に正常配信されたメッセージをピン留めすることを意味します。notifyのデフォルトはfalseです。requiredのデフォルトはfalseです。未対応のチャンネルまたはピン留めの失敗時は、配信を継続することで自動的にデグレードします。- 既存メッセージ向けの手動
pin、unpin、list-pinsメッセージアクションは維持します。
channelData.telegram.pin = true から delivery.pin = true に移動する必要があります。
ランタイム機能コントラクト
プレゼンテーションと配信のレンダーフックは、コントロールプレーンのチャンネル Plugin ではなく、ランタイム送信アダプターに追加します。- 対象チャンネルとランタイムアダプターを解決します。
- プレゼンテーション機能を問い合わせます。
- レンダリング前に、未対応のブロックをデグレードし、汎用の機能制限を 適用します。
renderPresentationを呼び出します。- レンダラーが存在しない場合、プレゼンテーションをテキストフォールバックに変換します。
- 送信に成功した後、
delivery.pinが要求され、かつサポートされている場合はpinDeliveredMessageを呼び出します。
チャンネルマッピング
Discord:presentationを、ランタイム専用モジュール内の components v2 と Carbon コンテナーにレンダリングします。- アクセントカラーヘルパーは軽量モジュールに保持します。
- チャンネル Plugin のコントロールプレーンコードから
DiscordUiContainerのインポートを削除します。
presentationを Block Kit にレンダリングします。- エージェントと CLI の
blocks入力を削除します。
- テキスト、コンテキスト、区切り線をテキストとしてレンダリングします。
- 設定済みで対象サーフェスに許可されている場合、アクションと選択をインラインキーボードとしてレンダリングします。
- インラインボタンが無効な場合はテキストフォールバックを使用します。
- ACP トピックのピン留めを
delivery.pinに移動します。
- 設定されている場合、アクションをインタラクティブボタンとしてレンダリングします。
- その他のブロックはテキストフォールバックとしてレンダリングします。
presentationを Adaptive Cards にレンダリングします。- 手動のピン留め/ピン留め解除/ピン一覧アクションは維持します。
- 対象の会話で Graph のサポートが信頼できる場合は、必要に応じて
pinDeliveredMessageを実装します。
presentationをインタラクティブカードにレンダリングします。- 手動のピン留め/ピン留め解除/ピン一覧アクションは維持します。
- API の動作が信頼できる場合は、送信済みメッセージのピン留め用に、必要に応じて
pinDeliveredMessageを実装します。
- 可能な場合、
presentationを Flex またはテンプレートメッセージにレンダリングします。 - 未対応のブロックはテキストにフォールバックします。
channelDataから LINE UI ペイロードを削除します。
- 控えめな書式でプレゼンテーションをテキストに変換します。
リファクタリング手順
ui-colors.tsを Carbon ベースの UI から分離し、extensions/discord/src/channel.tsからDiscordUiContainerを削除する Discord リリース修正を再適用します。ReplyPayload、送信ペイロードの正規化、配信サマリー、フックペイロードに、presentationとdeliveryを追加します。- 限定的な SDK/ランタイムサブパスに
MessagePresentationスキーマとパーサーヘルパーを追加します。 - メッセージ機能の
buttons、cards、components、blocksを、セマンティックプレゼンテーション機能に置き換えます。 - プレゼンテーションのレンダリングと配信時のピン留め用に、ランタイム送信アダプターフックを追加します。
- クロスコンテキストのコンポーネント構築を
buildCrossContextPresentationに置き換えます。 src/infra/outbound/channel-adapters.tsを削除し、チャンネル Plugin 型からbuildCrossContextComponentsを削除します。- ネイティブパラメーターの代わりに
presentationを付加するようmaybeApplyCrossContextMarkerを変更します。 - セマンティックプレゼンテーションと配信メタデータのみを使用するよう、Plugin ディスパッチの送信パスを更新します。
- エージェントと CLI のネイティブペイロードパラメーター、
components、blocks、buttons、cardを削除します。 - ネイティブのメッセージツールスキーマを作成する SDK ヘルパーを削除し、プレゼンテーションスキーマヘルパーに置き換えます。
channelDataから UI/ネイティブエンベロープを削除します。残りの各フィールドがレビューされるまでは、トランスポートメタデータのみを保持します。- Discord、Slack、Telegram、Mattermost、MS Teams、Feishu、LINE のレンダラーを移行します。
- メッセージ CLI、チャンネルページ、Plugin SDK、機能クックブックのドキュメントを更新します。
- Discord および影響を受けるチャンネルエントリーポイントのインポートファンアウトをプロファイリングします。
channelData トランスポートエンベロープを対象とする、より詳細な内部クリーンアップとして残っています。手順 15 は、型/テストゲートを超えて定量化されたインポートファンアウトの数値が必要な場合の、後続の検証として残っています。
テスト
以下を追加または更新します。- プレゼンテーション正規化テスト。
- 未対応ブロックに対するプレゼンテーションの自動デグレードテスト。
- Plugin ディスパッチとコア配信パスのクロスコンテキストマーカーテスト。
- Discord、Slack、Telegram、Mattermost、MS Teams、Feishu、LINE、およびテキストフォールバックのチャンネルレンダリングマトリックステスト。
- ネイティブフィールドが削除されたことを証明するメッセージツールスキーマテスト。
- ネイティブフラグが削除されたことを証明する CLI テスト。
- Carbon を対象とする Discord エントリーポイントのインポート遅延読み込み回帰テスト。
- Telegram と汎用フォールバックを対象とする配信ピン留めテスト。
未解決の質問
- 最初の実装では
delivery.pinを Discord、Slack、MS Teams、Feishu に対応させるべきですか、それともまず Telegram のみに対応させるべきですか? - 最終的に
deliveryにreplyToId、replyToCurrent、silent、audioAsVoiceなどの既存フィールドを統合すべきですか、それとも送信後の動作に重点を置いたままにすべきですか? - プレゼンテーションで画像やファイル参照を直接サポートすべきですか、それとも現時点ではメディアを UI レイアウトから分離したままにすべきですか?