Статус
Реализовано для общих поверхностей агента, 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, что втягивает зависимости UI времени выполнения в плоскость управления Plugin канала. - Агент и CLI предоставляют нативные обходные пути полезной нагрузки, такие как Discord
components, Slackblocks, Telegram или Mattermostbuttons, а также Teams или Feishucard. ReplyPayload.channelDataпереносит как подсказки транспорта, так и нативные UI-конверты.- Общая модель
interactiveсуществует, но она уже, чем более богатые макеты, уже используемые Discord, Slack, Teams, Feishu, LINE, Telegram и Mattermost.
Цели
- Ядро выбирает лучшее семантическое представление для сообщения на основе объявленных возможностей.
- Расширения объявляют возможности и рендерят семантическое представление в нативные транспортные полезные нагрузки.
- Web Control UI остается отделенным от нативного UI чатов.
- Нативные полезные нагрузки каналов не раскрываются через общую поверхность сообщений агента или CLI.
- Неподдерживаемые функции представления автоматически упрощаются до лучшего текстового представления.
- Поведение доставки, такое как закрепление отправленного сообщения, является общими метаданными доставки, а не представлением.
Нецели
- Нет shim для обратной совместимости для
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.
Метаданные доставки
Добавить принадлежащее ядру полеdelivery для поведения отправки, которое не является UI.
delivery.pin = trueозначает закрепить первое успешно доставленное сообщение.notifyпо умолчанию равноfalse.requiredпо умолчанию равноfalse; неподдерживаемые каналы или неудачное закрепление автоматически упрощаются путем продолжения доставки.- Ручные действия сообщений
pin,unpinиlist-pinsостаются для существующих сообщений.
channelData.telegram.pin = true в delivery.pin = true.
Контракт возможностей времени выполнения
Добавить хуки рендеринга представления и доставки в исходящий адаптер времени выполнения, а не в Plugin канала плоскости управления.- Определить целевой канал и адаптер времени выполнения.
- Запросить возможности представления.
- Упростить неподдерживаемые блоки и применить общие ограничения возможностей перед рендерингом.
- Вызвать
renderPresentation. - Если рендерера нет, преобразовать представление в текстовый резервный вариант.
- После успешной отправки вызвать
pinDeliveredMessage, когда запрошен и поддерживаетсяdelivery.pin.
Сопоставление каналов
Discord:- Рендерить
presentationв components v2 и контейнеры Carbon в модулях только времени выполнения. - Сохранить помощники акцентных цветов в легких модулях.
- Удалить импорты
DiscordUiContainerиз кода Plugin канала плоскости управления.
- Рендерить
presentationв Block Kit. - Удалить ввод
blocksдля агента и CLI.
- Рендерить текст, контекст и разделители как текст.
- Рендерить действия и выбор как встроенные клавиатуры, когда это настроено и разрешено для целевой поверхности.
- Использовать текстовый резервный вариант, когда встроенные кнопки отключены.
- Перенести закрепление темы ACP в
delivery.pin.
- Рендерить действия как интерактивные кнопки, когда это настроено.
- Рендерить остальные блоки как текстовый резервный вариант.
- Рендерить
presentationв Adaptive Cards. - Сохранить ручные действия pin/unpin/list-pins.
- При необходимости реализовать
pinDeliveredMessage, если поддержка Graph надежна для целевой беседы.
- Рендерить
presentationв интерактивные карточки. - Сохранить ручные действия pin/unpin/list-pins.
- При необходимости реализовать
pinDeliveredMessageдля закрепления отправленного сообщения, если поведение API надежно.
- Рендерить
presentationв Flex или шаблонные сообщения, где возможно. - Откатываться к тексту для неподдерживаемых блоков.
- Удалить UI-полезные нагрузки LINE из
channelData.
- Преобразовывать представление в текст с консервативным форматированием.
Шаги рефакторинга
- Повторно применить релизное исправление Discord, которое отделяет
ui-colors.tsот UI на базе Carbon и удаляетDiscordUiContainerизextensions/discord/src/channel.ts. - Добавить
presentationиdeliveryвReplyPayload, нормализацию исходящей полезной нагрузки, сводки доставки и полезные нагрузки хуков. - Добавить схему
MessagePresentationи помощники парсера в узком подпути SDK/времени выполнения. - Заменить возможности сообщений
buttons,cards,componentsиblocksсемантическими возможностями представления. - Добавить хуки исходящего адаптера времени выполнения для рендеринга представления и закрепления доставки.
- Заменить построение межконтекстных компонентов на
buildCrossContextPresentation. - Удалить
src/infra/outbound/channel-adapters.tsи удалитьbuildCrossContextComponentsиз типов Plugin канала. - Изменить
maybeApplyCrossContextMarker, чтобы он прикреплялpresentationвместо нативных параметров. - Обновить пути отправки plugin-dispatch, чтобы они использовали только семантическое представление и метаданные доставки.
- Удалить нативные параметры полезной нагрузки агента и CLI:
components,blocks,buttonsиcard. - Удалить помощники SDK, создающие нативные схемы message-tool, заменив их помощниками схемы представления.
- Удалить UI/нативные конверты из
channelData; оставить только транспортные метаданные, пока каждое оставшееся поле не будет проверено. - Мигрировать рендереры Discord, Slack, Telegram, Mattermost, MS Teams, Feishu и LINE.
- Обновить документацию для message CLI, страниц каналов, Plugin SDK и книги рецептов возможностей.
- Запустить профилирование веерного импорта для Discord и затронутых точек входа каналов.
channelData провайдеров. Шаг 15 остается последующей проверкой, если нам нужны количественные числа веерного импорта сверх проверки типов/тестов.
Тесты
Добавить или обновить:- Тесты нормализации представления.
- Тесты автоматического упрощения представления для неподдерживаемых блоков.
- Тесты межконтекстного маркера для путей plugin dispatch и доставки ядра.
- Матричные тесты рендеринга каналов для Discord, Slack, Telegram, Mattermost, MS Teams, Feishu, LINE и текстового резервного варианта.
- Тесты схемы message tool, доказывающие, что нативные поля удалены.
- Тесты CLI, доказывающие, что нативные флаги удалены.
- Регрессионный тест ленивости импорта точки входа Discord, покрывающий Carbon.
- Тесты закрепления доставки, покрывающие Telegram и общий резервный вариант.
Открытые вопросы
- Следует ли реализовать
delivery.pinдля Discord, Slack, MS Teams и Feishu в первом проходе или сначала только для Telegram? - Должно ли
deliveryсо временем поглотить существующие поля, такие какreplyToId,replyToCurrent,silentиaudioAsVoice, или остаться сфокусированным на поведении после отправки? - Должно ли представление напрямую поддерживать изображения или ссылки на файлы, или пока медиа следует оставить отдельно от макета UI?