- текстові секції
- короткий контекстний текст або текст нижнього колонтитула
- розділювачі
- кнопки
- меню вибору
- заголовок і тон картки
components, Slack
blocks, Telegram buttons, Teams card або Feishu card, до спільного
інструмента повідомлень. Це вихідні дані рендерера, якими володіє канальний Plugin.
Контракт
Автори Plugin імпортують публічний контракт з:value— це значення дії застосунку, яке маршрутизується назад через наявний шлях взаємодії каналу, коли канал підтримує клікабельні елементи керування.url— це кнопка-посилання. Вона може існувати безvalue.labelє обов’язковим і також використовується в текстовому запасному варіанті.styleмає рекомендаційний характер. Рендерери мають зіставляти непідтримувані стилі з безпечним стандартним варіантом, а не провалювати надсилання.
options[].value— це вибране значення застосунку.placeholderмає рекомендаційний характер і може ігноруватися каналами без нативної підтримки вибору.- Якщо канал не підтримує елементи вибору, запасний текст перелічує мітки.
Приклади виробника
Проста картка:Контракт рендерера
Канальні Plugins оголошують підтримку рендерингу у своєму вихідному адаптері:Основний потік рендерингу
КолиReplyPayload або дія повідомлення містить presentation, ядро:
- Нормалізує payload подання.
- Розв’язує вихідний адаптер цільового каналу.
- Читає
presentationCapabilities. - Викликає
renderPresentation, коли адаптер може рендерити payload. - Переходить до консервативного тексту, коли адаптера немає або він не може рендерити.
- Надсилає отриманий payload через звичайний шлях доставки каналу.
- Застосовує метадані доставки, як-от
delivery.pin, після першого успішно надісланого повідомлення.
Правила деградації
Подання має бути безпечним для надсилання в обмежених каналах. Запасний текст містить:titleяк перший рядок- блоки
textяк звичайні абзаци - блоки
contextяк компактні контекстні рядки - блоки
dividerяк візуальний розділювач - мітки кнопок, включно з URL для кнопок-посилань
- мітки варіантів вибору
- Telegram з вимкненими inline-кнопками надсилає текстовий запасний варіант.
- Канал без підтримки вибору перелічує варіанти вибору як текст.
- Кнопка лише з URL стає або нативною кнопкою-посиланням, або запасним рядком URL.
- Необов’язкові збої закріплення не провалюють доставлене повідомлення.
delivery.pin.required: true; якщо закріплення запитано як
обов’язкове і канал не може закріпити надіслане повідомлення, доставка повідомляє про збій.
Зіставлення провайдерів
Поточні вбудовані рендерери:| Канал | Нативна ціль рендерингу | Примітки |
|---|---|---|
| Discord | Компоненти та контейнери компонентів | Зберігає застарілий channelData.discord.components для наявних виробників provider-native payload, але нові спільні надсилання мають використовувати presentation. |
| Slack | Block Kit | Зберігає застарілий channelData.slack.blocks для наявних виробників provider-native payload, але нові спільні надсилання мають використовувати presentation. |
| Telegram | Текст плюс inline-клавіатури | Кнопки/вибори потребують можливості inline-кнопок для цільової поверхні; інакше використовується текстовий запасний варіант. |
| Mattermost | Текст плюс інтерактивні props | Інші блоки деградують до тексту. |
| Microsoft Teams | Adaptive Cards | Звичайний текст message включається з карткою, коли надано обидва. |
| Feishu | Інтерактивні картки | Заголовок картки може використовувати title; тіло уникає дублювання цього заголовка. |
| Звичайні канали | Текстовий запасний варіант | Канали без рендерера все одно отримують читабельний вивід. |
Подання проти InteractiveReply
InteractiveReply — це старіша внутрішня підмножина, яку використовують помічники підтверджень і взаємодій.
Вона підтримує:
- текст
- кнопки
- елементи вибору
MessagePresentation — це канонічний спільний контракт надсилання. Він додає:
- заголовок
- тон
- контекст
- розділювач
- кнопки лише з URL
- загальні метадані доставки через
ReplyPayload.delivery
openclaw/plugin-sdk/interactive-runtime під час зв’язування зі старішим
кодом:
MessagePresentation напряму.
presentationToInteractiveReply(...) зберігає видимий текст подання, зіставляючи
заголовок, текст, контекст, кнопки та елементи вибору зі старішою
формою InteractiveReply. Рендерери компонентів, які вже нативно малюють заголовок, текст,
контекст і блоки розділювачів, мають натомість використовувати
presentationToInteractiveControlsReply(...), а потім додавати лише
елементи керування кнопок і вибору.
renderMessagePresentationFallbackText(...) повертає порожній рядок для
блоків подання, які не мають текстового запасного варіанта, як-от подання лише з розділювачем.
Транспорти, які потребують непорожнього тіла надсилання, можуть передати
emptyFallback, щоб увімкнути мінімальне тіло без зміни стандартного контракту запасного варіанта.
Закріплення доставки
Закріплення — це поведінка доставки, а не подання. Використовуйтеdelivery.pin замість
provider-native полів, як-от channelData.telegram.pin.
Семантика:
pin: trueзакріплює перше успішно доставлене повідомлення.pin.notifyза замовчуванням має значенняfalse.pin.requiredза замовчуванням має значенняfalse.- Необов’язкові збої закріплення деградують і залишають надіслане повідомлення без змін.
- Обов’язкові збої закріплення провалюють доставку.
- Розбиті на частини повідомлення закріплюють першу доставлену частину, а не останню частину.
pin, unpin і pins все ще існують для наявних
повідомлень, де провайдер підтримує ці операції.
Контрольний список автора Plugin
- Оголошуйте
presentationзdescribeMessageTool(...), коли канал може рендерити або безпечно деградувати семантичне подання. - Додайте
presentationCapabilitiesдо runtime вихідного адаптера. - Реалізуйте
renderPresentationу runtime коді, а не в control-plane коді налаштування Plugin. - Тримайте нативні UI-бібліотеки поза гарячими шляхами налаштування/каталогу.
- Зберігайте обмеження платформи в рендерері та тестах.
- Додайте тести запасних варіантів для непідтримуваних кнопок, елементів вибору, URL-кнопок, дублювання заголовка/тексту
та змішаних надсилань
messageплюсpresentation. - Додайте підтримку закріплення доставки через
deliveryCapabilities.pinіpinDeliveredMessageлише тоді, коли провайдер може закріпити id надісланого повідомлення. - Не розкривайте нові provider-native поля карток/блоків/компонентів/кнопок через спільну схему дії повідомлення.