Стан
Реалізовано для спільного агента, CLI, можливостей Plugin і поверхонь вихідної доставки:ReplyPayload.presentationпередає семантичний UI повідомлення.ReplyPayload.delivery.pinпередає запити на закріплення надісланого повідомлення.- Спільні дії повідомлень надають
presentation,deliveryіpinзамість провайдернихcomponents,blocks,buttonsабоcard. - Ядро рендерить або автоматично деградує презентацію через оголошені Plugin вихідні можливості.
- Рендерери Discord, Slack, Telegram, Mattermost, MS Teams і Feishu використовують узагальнений контракт.
- Код площини керування каналу Discord більше не імпортує UI-контейнери на базі Carbon.
Проблема
UI каналів зараз розділений між кількома несумісними поверхнями:- Ядро володіє кросконтекстним хуком рендерера у формі Discord через
buildCrossContextComponents. - Discord
channel.tsможе імпортувати нативний Carbon UI черезDiscordUiContainer, що затягує runtime-залежності UI у площину керування канального Plugin. - Агент і CLI надають нативні аварійні виходи payload, як-от Discord
components, Slackblocks, Telegram або Mattermostbuttons, а також Teams або Feishucard. ReplyPayload.channelDataмістить і транспортні підказки, і нативні UI-конверти.- Узагальнена модель
interactiveіснує, але вона вужча за багатші макети, які вже використовуються Discord, Slack, Teams, Feishu, LINE, Telegram і Mattermost.
Цілі
- Ядро обирає найкращу семантичну презентацію для повідомлення на основі оголошених можливостей.
- Розширення оголошують можливості й рендерять семантичну презентацію в нативні транспортні payload.
- Web Control UI залишається окремим від нативного chat UI.
- Нативні payload каналів не відкриваються через спільну поверхню повідомлень агента або CLI.
- Непідтримувані функції презентації автоматично деградують до найкращого текстового представлення.
- Поведінка доставки, наприклад закріплення надісланого повідомлення, є узагальненими метаданими доставки, а не презентацією.
Нецілі
- Немає shim зворотної сумісності для
buildCrossContextComponents. - Немає публічних нативних аварійних виходів для
components,blocks,buttonsабоcard. - Немає імпортів канально-нативних UI-бібліотек у ядрі.
- Немає провайдер-специфічних SDK-швів для bundled каналів.
Цільова модель
Додайте полеpresentation, яким володіє ядро, до ReplyPayload.
interactive стає підмножиною presentation під час міграції:
- Текстовий блок
interactiveвідображається вpresentation.blocks[].type = "text". - Блок кнопок
interactiveвідображається вpresentation.blocks[].type = "buttons". - Блок select
interactiveвідображається вpresentation.blocks[].type = "select".
presentation; interactive залишається внутрішнім застарілим helper для парсингу/рендерингу для наявних виробників відповідей.
Публічний API для виробників вважає interactive застарілим. Підтримка runtime
залишається, щоб наявні helper-и approvals і старіші Plugin продовжували
працювати, тоді як новий код emit-ить presentation.
Метадані доставки
Додайте полеdelivery, яким володіє ядро, для поведінки надсилання, що не є UI.
delivery.pin = trueозначає закріпити перше успішно доставлене повідомлення.notifyза замовчуванням дорівнюєfalse.requiredза замовчуванням дорівнюєfalse; непідтримувані канали або невдале закріплення автоматично деградують, продовжуючи доставку.- Ручні дії повідомлення
pin,unpinіlist-pinsзалишаються для наявних повідомлень.
channelData.telegram.pin = true на delivery.pin = true.
Runtime-контракт можливостей
Додайте хуки рендерингу презентації та доставки до вихідного runtime-адаптера, а не до Plugin каналу площини керування.- Визначити цільовий канал і runtime-адаптер.
- Запитати можливості презентації.
- Деградувати непідтримувані блоки й застосувати узагальнені ліміти можливостей перед рендерингом.
- Викликати
renderPresentation. - Якщо рендерера немає, перетворити презентацію на текстовий fallback.
- Після успішного надсилання викликати
pinDeliveredMessage, коли запитаноdelivery.pinі це підтримується.
Мапінг каналів
Discord:- Рендерити
presentationу components v2 і Carbon-контейнери в runtime-only модулях. - Тримати helper-и accent color у легких модулях.
- Прибрати імпорти
DiscordUiContainerз коду площини керування канального Plugin.
- Рендерити
presentationу Block Kit. - Прибрати введення
blocksагента й CLI.
- Рендерити текст, контекст і розділювачі як текст.
- Рендерити дії та select як inline keyboards, коли це налаштовано й дозволено для цільової поверхні.
- Використовувати текстовий fallback, коли inline-кнопки вимкнено.
- Перенести закріплення ACP topic у
delivery.pin.
- Рендерити дії як інтерактивні кнопки, коли це налаштовано.
- Рендерити інші блоки як текстовий fallback.
- Рендерити
presentationу Adaptive Cards. - Зберегти ручні дії pin/unpin/list-pins.
- За бажання реалізувати
pinDeliveredMessage, якщо підтримка Graph надійна для цільової розмови.
- Рендерити
presentationв interactive cards. - Зберегти ручні дії pin/unpin/list-pins.
- За бажання реалізувати
pinDeliveredMessageдля закріплення надісланого повідомлення, якщо поведінка API надійна.
- Рендерити
presentationу Flex або template messages, де можливо. - Повертатися до тексту для непідтримуваних блоків.
- Прибрати UI payload LINE з
channelData.
- Перетворювати презентацію на текст із консервативним форматуванням.
Кроки рефакторингу
- Повторно застосувати release-виправлення Discord, яке відокремлює
ui-colors.tsвід UI на базі Carbon і прибираєDiscordUiContainerзextensions/discord/src/channel.ts. - Додати
presentationіdeliveryдоReplyPayload, нормалізації вихідних payload, підсумків доставки й hook payload. - Додати схему
MessagePresentationі parser helper-и у вузькому підшляху SDK/runtime. - Замінити можливості повідомлень
buttons,cards,componentsіblocksна семантичні можливості презентації. - Додати хуки вихідного runtime-адаптера для рендерингу презентації та закріплення доставки.
- Замінити побудову кросконтекстних компонентів на
buildCrossContextPresentation. - Видалити
src/infra/outbound/channel-adapters.tsі прибратиbuildCrossContextComponentsз типів Plugin каналу. - Змінити
maybeApplyCrossContextMarker, щоб прикріплюватиpresentationзамість нативних params. - Оновити шляхи надсилання plugin-dispatch, щоб вони споживали лише семантичну презентацію й метадані доставки.
- Прибрати нативні params payload агента й CLI:
components,blocks,buttonsіcard. - Прибрати SDK helper-и, що створюють нативні схеми message-tool, замінивши їх helper-ами схеми презентації.
- Прибрати UI/нативні конверти з
channelData; залишити тільки транспортні метадані, доки кожне поле, що залишилося, не буде переглянуто. - Мігрувати рендерери Discord, Slack, Telegram, Mattermost, MS Teams, Feishu і LINE.
- Оновити документацію для message CLI, сторінок каналів, Plugin SDK і capability cookbook.
- Запустити профілювання import fanout для Discord і зачеплених entrypoint каналів.
channelData. Крок 15 залишається подальшою валідацією, якщо нам потрібні кількісні показники import-fanout понад type/test gate.
Тести
Додати або оновити:- Тести нормалізації презентації.
- Тести автоматичної деградації презентації для непідтримуваних блоків.
- Тести кросконтекстного маркера для plugin dispatch і шляхів доставки ядра.
- Матричні тести рендерингу каналів для Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE і текстового fallback.
- Тести схеми message tool, що доводять відсутність нативних полів.
- Тести CLI, що доводять відсутність нативних прапорців.
- Регресія лінивості імпорту entrypoint Discord, що покриває Carbon.
- Тести закріплення доставки, що покривають Telegram і узагальнений fallback.
Відкриті питання
- Чи слід реалізувати
delivery.pinдля Discord, Slack, MS Teams і Feishu в першому проході, чи спочатку лише Telegram? - Чи має
deliveryз часом поглинути наявні поля, як-отreplyToId,replyToCurrent,silentіaudioAsVoice, чи залишитися зосередженим на поведінці після надсилання? - Чи має презентація підтримувати зображення або посилання на файли напряму, чи медіа наразі мають залишатися окремими від UI-макета?