Ця сторінка є цільовим дизайном для заміни розрізнених допоміжних засобів обробки turn у каналах, відправлення відповідей, потокового попереднього перегляду та вихідної доставки одним надійним життєвим циклом повідомлення. Коротко:Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
- Основними примітивами мають бути receive і send, а не reply.
- Відповідь є лише відношенням у вихідному повідомленні.
- Turn є зручністю для обробки вхідного повідомлення, а не власником доставки.
- Надсилання має бути контекстним:
begin, render, preview або stream, final send, commit, fail. - Отримання також має бути контекстним: normalize, dedupe, route, record, dispatch, platform ack, fail.
- Публічний SDK Plugin має звестися до однієї невеликої поверхні повідомлень каналу.
Проблеми
Поточний стек каналів виріс із кількох слушних локальних потреб:- Прості вхідні адаптери використовують
runtime.channel.turn.run. - Розширені адаптери використовують
runtime.channel.turn.runPrepared. - Застарілі допоміжні засоби використовують
dispatchInboundReplyWithBase,recordInboundSessionAndDispatchReply, допоміжні засоби payload для відповідей, розбиття відповідей на частини, посилання на відповіді та допоміжні засоби вихідного runtime. - Потоковий попередній перегляд живе у специфічних для каналів dispatcher-ах.
- Надійність фінальної доставки додається навколо наявних шляхів payload для відповідей.
Цілі
- Один життєвий цикл ядра для всіх шляхів отримання та надсилання повідомлень каналів.
- Надійні фінальні надсилання за замовчуванням у новому життєвому циклі повідомлень після того, як адаптер оголошує поведінку, безпечну для повторного відтворення.
- Спільна семантика попереднього перегляду, редагування, stream, фіналізації, повторних спроб, відновлення та receipt.
- Невелика поверхня SDK Plugin, яку сторонні plugins можуть вивчити та підтримувати.
- Сумісність для наявних викликів
channel.turnпід час міграції. - Чіткі точки розширення для нових можливостей каналів.
- Жодних специфічних для платформи гілок у ядрі.
- Жодних повідомлень каналу з token-delta. Потокова передача каналом залишається попереднім переглядом повідомлення, редагуванням, додаванням або доставкою завершеного блока.
- Структуровані метадані походження від OpenClaw для операційного/системного виводу, щоб видимі збої Gateway не входили повторно у спільні кімнати з увімкненими bot як нові prompts.
Не цілі
- Не видаляти
runtime.channel.turn.*на першому етапі. - Не змушувати кожен канал використовувати однакову нативну поведінку транспорту.
- Не навчати ядро тем Telegram, нативних streams Slack, редагувань Matrix, карток Feishu, голосу QQ або activities Teams.
- Не публікувати всі внутрішні допоміжні засоби міграції як стабільний API SDK.
- Не робити повторні спроби такими, що повторно відтворюють завершені неідемпотентні операції платформи.
Еталонна модель
Vercel Chat має добру публічну ментальну модель:ChatThreadChannelMessage- методи адаптера, як-от
postMessage,editMessage,deleteMessage,stream,startTypingі отримання історії - адаптер стану для dedupe, блокувань, черг і збереження
- Надійні наміри вихідного надсилання перед прямими викликами транспорту.
- Явні контексти надсилання з begin, commit і fail.
- Контексти отримання, які знають політику platform ack.
- Receipts, які переживають перезапуск і можуть керувати редагуваннями, видаленнями, відновленням і придушенням дублікатів.
- Менший публічний SDK. Вбудовані plugins можуть використовувати внутрішні допоміжні засоби runtime, але сторонні plugins мають бачити один узгоджений API повідомлень.
- Специфічна для агентів поведінка: сесії, transcripts, потокова передача блоків, перебіг роботи інструментів, approvals, медіадирективи, тихі відповіді та історія згадок у групах.
thread.post() недостатньо для OpenClaw. Вони приховують межу транзакції, яка вирішує, чи можна відновити надсилання.
Модель ядра
Новий домен має жити у внутрішньому просторі імен ядра, наприкладsrc/channels/message/*.
Він має чотири поняття:
receive володіє життєвим циклом вхідних повідомлень.
send володіє життєвим циклом вихідних повідомлень.
live володіє станом попереднього перегляду, редагування, прогресу та stream.
state володіє надійним зберіганням намірів, receipts, ідемпотентністю, відновленням, блокуваннями та dedupe.
Терміни повідомлень
Повідомлення
Нормалізоване повідомлення є платформонейтральним:Ціль
Ціль описує, де живе повідомлення:Відношення
Відповідь є відношенням, а не коренем API:Походження
Походження описує, хто створив повідомлення і як OpenClaw має обробляти відлуння цього повідомлення. Воно відокремлене від відношення: повідомлення може бути відповіддю користувачу і водночас бути операційним виводом, що походить від OpenClaw.allowBots увімкнено.
Receipt
Receipts є сутностями першого класу:Контекст отримання
Отримання не має бути голим викликом допоміжного засобу. Ядру потрібен контекст, який знає dedupe, маршрутизацію, запис сесії та політику platform ack.- Transport ack: повідомляє webhook або socket платформи, що OpenClaw прийняв envelope події. Деякі платформи вимагають цього до dispatch.
- Polling offset ack: просуває курсор, щоб ту саму подію не отримували знову. Він не має просуватися далі за роботу, яку неможливо відновити.
- Inbound record ack: підтверджує, що OpenClaw зберіг достатньо вхідних метаданих для dedupe і маршрутизації повторної доставки.
- Видимий користувачу receipt: необов’язкова поведінка читання/status/typing; ніколи не є межею надійності.
ReceiveAckPolicy контролює лише підтвердження транспорту або polling. Його не можна повторно використовувати для read receipts або статусних reactions.
Перед авторизацією bot отримання має застосувати спільну політику відлуння OpenClaw, коли канал може декодувати метадані походження повідомлення:
allowBots.
Політика ack є явною:
getUpdates fetch offset Telegram усе ще контролюється polling library, тож глибший наступний крок — повністю надійне джерело polling, якщо нам потрібна redelivery на рівні платформи понад restart watermark OpenClaw. Webhook платформи можуть потребувати негайного HTTP ack, але їм усе одно потрібні inbound dedupe і надійні наміри вихідного надсилання, бо webhooks можуть доставлятися повторно.
Контекст надсилання
Надсилання також базується на контексті:unknown_after_send, а не сліпо
відтворюватися. Канали без звіряння можуть обрати повторну відправку щонайменше
один раз лише якщо видимі дублікати повідомлень є прийнятним, задокументованим
компромісом для цього каналу й відношення. Поточний міст звіряння SDK вимагає,
щоб адаптер оголосив reconcileUnknownSend, а потім просить
durableFinal.reconcileUnknownSend класифікувати невідомий запис як sent,
not_sent або unresolved; лише not_sent дозволяє повторне відтворення, а
невирішені записи залишаються кінцевими або повторюють тільки перевірку
звіряння.
Політика стійкості має бути явною:
required означає, що ядро має відмовляти закрито, коли не може записати
стійкий намір. best_effort може продовжити виконання, коли збереження
недоступне. disabled зберігає стару поведінку прямого надсилання. Під час
міграції застарілі обгортки й публічні допоміжні засоби сумісності за
замовчуванням використовують disabled; вони не мають виводити required з
того факту, що канал має універсальний вихідний адаптер.
Контексти надсилання також володіють локальними для каналу ефектами після
надсилання. Міграція не є безпечною, якщо стійка доставка обходить локальну
поведінку, яка раніше була прив’язана до шляху прямого надсилання каналу.
Приклади включають кеші пригнічення самовідлуння, маркери участі в тредах,
нативні якорі редагування, рендеринг підпису моделі та платформно-специфічні
запобіжники дублікатів. Ці ефекти мають або перейти в адаптер надсилання,
адаптер рендерингу, або іменований хук контексту надсилання, перш ніж цей канал
зможе ввімкнути стійку універсальну фінальну доставку.
Допоміжні засоби надсилання мають повертати квитанції аж до свого викликувача.
Стійкі обгортки не можуть ковтати ідентифікатори повідомлень або замінювати
результат доставки каналу на undefined; буферизовані диспетчери використовують
ці ідентифікатори для якорів тредів, подальших редагувань, фіналізації прев’ю
та пригнічення дублікатів.
Резервні надсилання працюють із пакетами, а не з одиночними payload. Перезаписи
тихої відповіді, резервний варіант для медіа, резервний варіант для картки та
проекція фрагментів можуть усі створювати більше ніж одне доставне
повідомлення, тож контекст надсилання має або доставити весь спроєктований
пакет, або явно задокументувати, чому чинний лише один payload.
unknown_after_send,
доки адаптер його не звірить.
Живий контекст
Поведінка прев’ю, редагування, прогресу та stream має бути одним життєвим циклом із явним увімкненням.- Telegram надсилає та редагує прев’ю, з новим фінальним повідомленням після застарівання прев’ю за віком.
- Discord надсилає та редагує прев’ю, скасовує для медіа/помилки/явної відповіді.
- Slack використовує нативний stream або чернеткове прев’ю залежно від форми треду.
- Mattermost фіналізує чернетковий допис.
- Matrix фіналізує чернеткову подію або редагує її за невідповідності.
- Teams використовує нативний stream прогресу.
- QQ Bot використовує stream або накопичений резервний варіант.
Поверхня адаптера
Ціль публічного SDK має бути одним підшляхом:origin.decode повертає метадані походження OpenClaw. Адаптер
отримання надає факти платформи, як-от автора-бота й форму кімнати; ядро володіє
рішенням про відкидання й порядком, щоб канали не реалізовували текстові фільтри
повторно.
Адаптер походження:
MessageOrigin. Канали лише перекладають його в нативні
метадані транспорту й назад. Slack відображає це на
chat.postMessage({ metadata }) та вхідне message.metadata; Matrix може
відобразити це на додатковий вміст події; канали без нативних метаданих можуть
використовувати квитанцію/вихідний реєстр, коли це найкраще доступне
наближення.
Можливості:
Скорочення публічного SDK
Нова публічна поверхня має поглинути або оголосити застарілими ці концептуальні області:reply-runtimereply-dispatch-runtimereply-referencereply-chunkingreply-payloadinbound-reply-dispatchchannel-reply-pipeline- більшість публічних використань
outbound-runtime - допоміжні засоби життєвого циклу чернеткового stream ad hoc
plugin-sdk/channel-message, щойно він
з’явиться.
Зв’язок із ходом каналу
runtime.channel.turn.* має залишатися під час міграції.
Він має стати адаптером сумісності:
channel.turn.runPrepared також має спочатку залишитися:
channel.turn можна оголосити застарілим. Його не слід
видаляти, доки не буде опублікованого шляху міграції SDK і контрактних тестів,
які доводять, що старі плагіни все ще працюють або завершуються з чіткою
помилкою версії.
Запобіжники сумісності
Під час міграції універсальна стійка доставка вмикається явно для будь-якого каналу, чий наявний callback доставки має побічні ефекти поза “надіслати цей payload”. Застарілі точки входу за замовчуванням не є стійкими:channel.turn.runіdispatchAssembledChannelTurnвикористовують callback доставки каналу, якщо цей канал явно не надає перевірений об’єкт політики/параметрів стійкості.channel.turn.runPreparedзалишається під керуванням каналу, доки підготовлений диспетчер явно не викличе контекст надсилання.- Публічні допоміжні засоби сумісності, як-от
recordInboundSessionAndDispatchReply,dispatchInboundReplyWithBase, і допоміжні засоби direct-DM, ніколи не впроваджують універсальну стійку доставку перед наданим викликувачем callbackdeliverабоreply.
durable: undefined означає “не стійкий”. Стійкий
шлях вмикається лише явним значенням політики/параметрів. durable: false може
залишатися як написання для сумісності, але реалізація не має вимагати від
кожного немігруваного каналу додавати його.
Поточний код мосту має зберігати рішення про стійкість явним:
- Стійка фінальна доставка повертає дискримінований статус.
handled_visibleіhandled_no_sendє термінальними;unsupportedіnot_applicableможуть відкотитися до доставки, що належить каналу;failedпоширює збій надсилання. - Загальна стійка фінальна доставка обмежується можливостями адаптера, як-от тиха доставка, збереження цілі відповіді, збереження нативної цитати та хуки надсилання повідомлень. Якщо паритету бракує, слід обирати доставку, що належить каналу, а не загальне надсилання, яке змінює видиму для користувача поведінку.
- Стійкі надсилання на основі черги надають посилання на намір доставки. Наявні
поля сесії
pendingFinalDelivery*можуть переносити ідентифікатор наміру під час переходу; кінцевий стан — це сховищеMessageSendIntentзамість замороженого тексту відповіді плюс спеціальних контекстних полів.
- Адаптер загального надсилання виконує таку саму поведінку рендерингу й транспорту, як старий прямий шлях.
- Локальні побічні ефекти після надсилання збережено через контекст надсилання.
- Адаптер повертає квитанції або результати доставки з усіма ідентифікаторами повідомлень платформи.
- Підготовлені шляхи диспетчера або викликають новий контекст надсилання, або залишаються задокументованими як такі, що перебувають поза стійкою гарантією.
- Резервна доставка обробляє кожне спроєктоване навантаження, а не лише перше.
- Стійка резервна доставка записує весь масив спроєктованого навантаження як один намір або пакетний план, придатний для повторного відтворення.
- Доставка монітора iMessage записує надіслані повідомлення в кеш відлуння після успішного надсилання. Стійкі фінальні надсилання все ще мають заповнювати цей кеш, інакше OpenClaw може повторно поглинути власні фінальні відповіді як вхідні повідомлення користувача.
- Tlon додає необов’язковий підпис моделі й записує гілки з участю після групових відповідей. Загальна стійка доставка не повинна обходити ці ефекти; або перенесіть їх в адаптери рендерингу/надсилання/фіналізації Tlon, або залиште Tlon на шляху, що належить каналу.
- Discord та інші підготовлені диспетчери вже володіють прямою доставкою й поведінкою попереднього перегляду. Вони не покриваються стійкою гарантією зібраного ходу, доки їхні підготовлені диспетчери явно не спрямують фінальні повідомлення через контекст надсилання.
- Тиха резервна доставка Telegram має доставляти повний масив спроєктованого навантаження. Скорочений шлях для одного навантаження може відкинути додаткові резервні навантаження після проєкції.
- LINE, BlueBubbles, Zalo, Nostr та інші наявні зібрані/допоміжні шляхи можуть мати обробку токенів відповіді, проксіювання медіа, кеші надісланих повідомлень, очищення завантаження/статусу або цілі лише для зворотного виклику. Вони залишаються на доставці, що належить каналу, доки ці семантики не будуть представлені адаптером надсилання й перевірені тестами.
- Допоміжні засоби прямих DM можуть мати зворотний виклик відповіді, який є єдиною правильною
транспортною ціллю. Загальне вихідне надсилання не повинно вгадувати з
OriginatingToабоToй пропускати цей зворотний виклик. - Вивід збою OpenClaw gateway має залишатися видимим для людей, але позначені
відлуння кімнати, створені ботом, мають відкидатися до авторизації
allowBots. Канали не повинні реалізовувати це фільтрами префіксів видимого тексту, окрім як короткого аварійного тимчасового заходу; стійкий контракт — це структуровані метадані походження.
Внутрішнє сховище
Стійка черга має зберігати наміри надсилання повідомлень, а не навантаження відповідей.Класи збоїв
Адаптери каналів класифікують транспортні збої на закриті категорії:- Повторювати
transientіrate_limit. - Не повторювати
invalid_payload, якщо не існує резервного рендерингу. - Не повторювати
authабоpermission, доки конфігурація не зміниться. - Для
not_foundдозволити live-фіналізації відкотитися від редагування до нового надсилання, коли канал оголошує це безпечним. - Для
conflictвикористовуйте правила квитанції/ідемпотентності, щоб вирішити, чи повідомлення вже існує. - Будь-яка помилка після того, як адаптер міг завершити платформне введення-виведення, але до коміту
квитанції, стає
unknown_after_send, якщо адаптер не може довести, що платформна операція не відбулася.
Зіставлення каналів
| Канал | Ціль міграції |
|---|---|
| Telegram | Отримання політики підтвердження плюс надійні фінальні надсилання. Live-адаптер відповідає за надсилання плюс редагування попереднього перегляду, фінальне надсилання застарілого попереднього перегляду, теми, пропуск попереднього перегляду відповіді з цитатою, резервний варіант для медіа та обробку retry-after. |
| Discord | Send-адаптер обгортає наявну надійну доставку корисного навантаження. Live-адаптер відповідає за редагування чернетки, чернетку прогресу, скасування попереднього перегляду медіа/помилки, збереження цілі відповіді та квитанції з ідентифікаторами повідомлень. Перевірте відлуння збоїв Gateway OpenClaw, створені ботом, у спільних кімнатах; використовуйте вихідний реєстр або інший нативний еквівалент, якщо Discord не може передавати метадані походження у звичайних повідомленнях. |
| Slack | Send-адаптер обробляє звичайні публікації в чаті. Live-адаптер вибирає нативний потік, коли форма треду це підтримує, інакше чернетку попереднього перегляду. Квитанції зберігають часові мітки тредів. Origin-адаптер відображає збої Gateway OpenClaw у Slack chat.postMessage.metadata і відкидає позначені відлуння бот-кімнат до авторизації allowBots. |
| Send-адаптер відповідає за надсилання тексту/медіа з надійними фінальними намірами. Receive-адаптер обробляє групові згадки та ідентичність відправника. Live може залишатися відсутнім, доки WhatsApp не матиме редагованого транспорту. | |
| Matrix | Live-адаптер відповідає за редагування подій-чернеток, фіналізацію, редагування, обмеження для зашифрованих медіа та резервний варіант у разі невідповідності цілі відповіді. Receive-адаптер відповідає за гідратацію та дедуплікацію зашифрованих подій. Origin-адаптер має кодувати походження збою Gateway OpenClaw у вміст події Matrix і відкидати відлуння кімнат налаштованого бота до обробки allowBots. |
| Mattermost | Live-адаптер відповідає за одну публікацію-чернетку, згортання прогресу/інструментів, фіналізацію на місці та резервне свіже надсилання. |
| Microsoft Teams | Live-адаптер відповідає за нативну поведінку прогресу та блокового потоку. Send-адаптер відповідає за активності та квитанції вкладень/карток. |
| Feishu | Render-адаптер відповідає за рендеринг тексту/карток/raw. Live-адаптер відповідає за потокові картки та придушення дубльованих фінальних повідомлень. Send-адаптер відповідає за коментарі, сесії тем, медіа та придушення голосу. |
| QQ Bot | Live-адаптер відповідає за C2C-потокове передавання, тайм-аут акумулятора та резервне фінальне надсилання. Render-адаптер відповідає за медіатеги та текст як голос. |
| Signal | Простий Receive-адаптер плюс Send-адаптер. Без Live-адаптера, якщо signal-cli не додасть надійну підтримку редагування. |
| iMessage and BlueBubbles | Простий Receive-адаптер плюс Send-адаптер. Надсилання iMessage має зберігати заповнення echo-cache монітора, перш ніж надійні фінальні повідомлення зможуть обходити доставку через монітор. Специфічні для BlueBubbles введення, реакції та вкладення залишаються можливостями адаптера. |
| Google Chat | Простий Receive-адаптер плюс Send-адаптер із відношенням треду, зіставленим із spaces та ідентифікаторами тредів. Перевірте поведінку кімнат allowBots=true щодо позначених відлунь збоїв Gateway OpenClaw. |
| LINE | Простий Receive-адаптер плюс Send-адаптер з обмеженнями reply-token, змодельованими як можливість цілі/відношення. |
| Nextcloud Talk | Receive-міст SDK плюс Send-адаптер. |
| IRC | Простий Receive-адаптер плюс Send-адаптер, без надійних квитанцій редагування. |
| Nostr | Receive-адаптер плюс Send-адаптер для зашифрованих DM; квитанції є ідентифікаторами подій. |
| QA Channel | Адаптер контрактних тестів для поведінки отримання, надсилання, live, повторних спроб і відновлення. |
| Synology Chat | Простий Receive-адаптер плюс Send-адаптер. |
| Tlon | Send-адаптер має зберігати рендеринг model-signature та відстеження тредів з участю, перш ніж буде ввімкнено загальну надійну фінальну доставку. |
| Twitch | Простий Receive-адаптер плюс Send-адаптер із класифікацією обмежень швидкості. |
| Zalo | Простий Receive-адаптер плюс Send-адаптер. |
| Zalo Personal | Простий Receive-адаптер плюс Send-адаптер. |
План міграції
Фаза 1: Внутрішній домен повідомлень
- Додайте типи
src/channels/message/*для повідомлень, цілей, відношень, походжень, квитанцій, можливостей, надійних намірів, контексту отримання, контексту надсилання, live-контексту та класів збоїв. - Додайте
origin?: MessageOriginдо типу корисного навантаження моста міграції, який використовується поточною доставкою відповідей, а потім перенесіть це поле доChannelMessageі типів відрендерених повідомлень, коли рефакторинг замінить корисні навантаження відповідей. - Тримайте це внутрішнім, доки адаптери й тести не підтвердять форму.
- Додайте чисті модульні тести для переходів станів і серіалізації.
Фаза 2: Ядро надійного надсилання
- Перенесіть наявну вихідну чергу з надійності reply-payload до надійних намірів надсилання повідомлень.
- Дозвольте надійному наміру надсилання містити спроєктований масив корисних навантажень або план пакета, а не лише один reply payload.
- Збережіть поточну поведінку відновлення черги через сумісне перетворення.
- Змусьте
deliverOutboundPayloadsвикликатиmessages.send. - Зробіть надійність фінального надсилання типовою та закривайтеся зі збоєм, коли надійний намір не може бути записаний у новому життєвому циклі повідомлення, після того як адаптер оголосить безпечність повторного відтворення. Наявні шляхи сумісності channel-turn і SDK залишаються direct-send за замовчуванням протягом цієї фази.
- Послідовно записуйте квитанції.
- Повертайте квитанції та результати доставки початковому викликачу диспетчера замість трактування надійного надсилання як кінцевого побічного ефекту.
- Зберігайте походження повідомлення через надійні наміри надсилання, щоб відновлення, повторне відтворення та фрагментовані надсилання зберігали операційне походження OpenClaw.
Фаза 3: Міст Channel Turn
- Повторно реалізуйте
channel.turn.runіdispatchAssembledChannelTurnповерхmessages.receiveіmessages.send. - Зберігайте поточні типи фактів стабільними.
- Зберігайте застарілу поведінку за замовчуванням. Канал assembled-turn стає надійним лише тоді, коли його адаптер явно вмикає це з політикою надійності, безпечною для повторного відтворення.
- Залиште
durable: falseяк сумісний аварійний вихід для шляхів, які фіналізують нативні редагування та ще не можуть безпечно повторно відтворюватися, але не покладайтеся на маркериfalseдля захисту немігровних каналів. - Вмикайте надійність assembled-turn за замовчуванням лише в новому життєвому циклі повідомлень, після того як зіставлення каналу доведе, що загальний шлях надсилання зберігає стару семантику доставки каналу.
Фаза 4: Міст підготовленого диспетчера
- Замініть
deliverDurableInboundReplyPayloadмостом контексту надсилання. - Збережіть старий допоміжний засіб як обгортку.
- Спочатку перенесіть Telegram, WhatsApp, Slack, Signal, iMessage і Discord, тому що вони вже мають стійку роботу з фінальними повідомленнями або простіші шляхи надсилання.
- Вважайте кожен підготовлений диспетчер непокритим, доки він явно не підключиться до контексту надсилання. Документація та записи журналу змін мають казати «зібрані channel turns» або називати перенесені шляхи каналів, а не заявляти про всі автоматичні фінальні відповіді.
- Збережіть поведінку
recordInboundSessionAndDispatchReply, допоміжних засобів direct-DM та подібних публічних допоміжних засобів сумісності. Пізніше вони можуть надати явне підключення до контексту надсилання, але не повинні автоматично намагатися виконати загальне стійке доставлення перед callback доставки, яким володіє викликач.
Етап 5: Уніфікований життєвий цикл у реальному часі
- Побудуйте
messages.liveз двома адаптерами доказу:- Telegram для надсилання, редагування та надсилання застарілого фінального повідомлення.
- Matrix для фіналізації чернетки та резервного редагування з видаленням.
- Потім перенесіть Discord, Slack, Mattermost, Teams, QQ Bot і Feishu.
- Видаліть дубльований код фіналізації попереднього перегляду лише після того, як кожен канал матиме тести паритету.
Етап 6: Публічний SDK
- Додайте
openclaw/plugin-sdk/channel-message. - Задокументуйте його як рекомендований API Plugin каналів.
- Оновіть експорти пакетів, інвентар entrypoint, згенеровані базові лінії API та документацію SDK Plugin.
- Додайте
MessageOrigin, хуки кодування/декодування джерела та спільний предикатshouldDropOpenClawEchoдо поверхні SDK channel-message. - Збережіть обгортки сумісності для старих підшляхів.
- Позначте допоміжні засоби SDK з назвами reply як застарілі в документації після перенесення вбудованих plugins.
Етап 7: Усі відправники
Перенесіть усіх вихідних виробників, що не є відповідями, наmessages.send:
- сповіщення cron і heartbeat
- завершення завдань
- результати хуків
- запити на схвалення та результати схвалення
- надсилання інструмента повідомлень
- оголошення про завершення subagent
- явні надсилання CLI або Control UI
- шляхи автоматизації/трансляції
Етап 8: Виведення Turn з ужитку
- Збережіть
channel.turnяк обгортку принаймні на одне вікно сумісності. - Опублікуйте нотатки щодо міграції.
- Запустіть тести сумісності SDK Plugin зі старими імпортами.
- Видаліть або приховайте старі внутрішні допоміжні засоби лише після того, як вони більше не потрібні жодному вбудованому plugin, а сторонні контракти матимуть стабільну заміну.
План тестування
Модульні тести:- Серіалізація та відновлення стійкого наміру надсилання.
- Повторне використання ключа ідемпотентності та придушення дублікатів.
- Фіксація підтвердження та пропуск повторного відтворення.
- Відновлення
unknown_after_send, яке виконує звіряння перед повторним відтворенням, коли адаптер підтримує звіряння. - Політика класифікації збоїв.
- Послідовність політики ack для отримання.
- Зіставлення зв’язків для надсилань reply, followup, system і broadcast.
- Фабрика джерела збоїв Gateway і предикат
shouldDropOpenClawEcho. - Збереження джерела через нормалізацію payload, розбиття на chunks, серіалізацію стійкої черги та відновлення.
- Простий адаптер
channel.turn.runусе ще записує та надсилає. - Застаріле доставлення assembled-turn не стає стійким, якщо канал явно не підключився.
- Міст
channel.turn.runPreparedусе ще записує та фіналізує. - Публічні допоміжні засоби сумісності за замовчуванням викликають callback доставки, яким володіє викликач, і не виконують загальне надсилання перед цими callback.
- Стійке резервне доставлення після перезапуску повторно відтворює весь спроєктований масив payload і не може залишити пізніші payload незаписаними після раннього збою.
- Стійке доставлення assembled-turn повертає ідентифікатори повідомлень платформи буферизованому диспетчеру.
- Користувацькі хуки доставки все ще повертають ідентифікатори повідомлень платформи, коли стійке доставлення вимкнене або недоступне.
- Фінальна відповідь переживає перезапуск між завершенням асистента та надсиланням на платформу.
- Чернетка попереднього перегляду фіналізується на місці, коли це дозволено.
- Чернетка попереднього перегляду скасовується або редагується з видаленням, коли невідповідність медіа/помилки/цілі відповіді вимагає звичайного доставлення.
- Потокове передавання блоків і потокове передавання попереднього перегляду не доставляють один і той самий текст одночасно.
- Медіа, передане потоково раніше, не дублюється у фінальному доставленні.
- Відповідь у темі Telegram із polling ack, відкладеним до безпечної завершеної водяної позначки контексту отримання.
- Відновлення polling Telegram для прийнятих, але не доставлених оновлень, покрите збереженою моделлю safe-completed offset.
- Застарілий попередній перегляд Telegram надсилає нове фінальне повідомлення та очищує попередній перегляд.
- Тихий fallback Telegram надсилає кожен спроєктований fallback payload.
- Стійкість тихого fallback Telegram атомарно записує повний спроєктований fallback-масив, а не один single-payload стійкий намір на кожну ітерацію циклу.
- Скасування попереднього перегляду Discord для медіа/помилки/явної відповіді.
- Фінальні повідомлення підготовленого диспетчера Discord проходять через контекст надсилання до того, як документація або журнал змін заявлятимуть про стійкість фінальних відповідей Discord.
- Стійкі фінальні надсилання iMessage заповнюють echo-кеш надісланих повідомлень монітора.
- Застарілі шляхи доставки LINE, BlueBubbles, Zalo і Nostr не обходяться загальним стійким надсиланням, доки не існують їхні тести паритету адаптерів.
- Доставка через callback Direct-DM/Nostr залишається авторитетною, якщо її явно не перенесено на повну ціль повідомлення та replay-safe адаптер надсилання.
- Позначені повідомлення про збій Gateway OpenClaw у Slack залишаються видимими вихідними повідомленнями, позначені
ехо в кімнаті від bot відкидаються перед
allowBots, а непозначені повідомлення bot з тим самим видимим текстом усе ще проходять звичайну авторизацію bot. - Резервний native stream Slack до draft preview у DMs верхнього рівня.
- Фіналізація попереднього перегляду Matrix і резервне редагування з видаленням.
- Позначені ехо в кімнаті про збій Gateway OpenClaw у Matrix від налаштованих облікових записів bot
відкидаються перед обробкою
allowBots. - Аудити каскаду збоїв Gateway у спільних кімнатах Discord і Google Chat покривають
режими
allowBotsперед заявами про загальний захист там. - Фіналізація чернетки Mattermost і fallback зі свіжим надсиланням.
- Фіналізація native progress Teams.
- Придушення дубльованих фінальних повідомлень Feishu.
- Резервний fallback за timeout акумулятора QQ Bot.
- Стійкі фінальні надсилання Tlon зберігають рендеринг підпису моделі та відстеження ланцюжка з участю.
- Прості стійкі фінальні надсилання WhatsApp, Signal, iMessage, Google Chat, LINE, IRC, Nostr, Nextcloud Talk, Synology Chat, Tlon, Twitch, Zalo і Zalo Personal.
- Цільові файли Vitest під час розробки.
pnpm check:changedу Testbox для всієї зміненої поверхні.- Ширший
pnpm checkу Testbox перед landing повного рефакторингу або після змін публічного SDK/експортів. - Live або qa-channel smoke принаймні для одного каналу з можливістю редагування та одного простого каналу лише з надсиланням перед видаленням обгорток сумісності.
Відкриті питання
- Чи має Telegram зрештою замінити джерело runner grammY на повністю стійке джерело polling, яке може контролювати redelivery на рівні платформи, а не лише збережену водяну позначку перезапуску OpenClaw.
- Чи має стійкий live preview стан зберігатися в тому самому записі черги, що й фінальний намір надсилання, або в суміжному сховищі live-state.
- Як довго обгортки сумісності залишаються задокументованими після
виходу
plugin-sdk/channel-message. - Чи мають сторонні plugins реалізовувати адаптери отримання напряму, чи лише
надавати хуки normalize/send/live через
defineChannelMessageAdapter. - Які поля підтвердження безпечно відкривати в публічному SDK порівняно з внутрішнім runtime станом.
- Чи слід моделювати побічні ефекти, як-от self-echo кеші та participated-thread маркери, як хуки контексту надсилання, кроки фіналізації, якими володіє адаптер, або підписників підтверджень.
- Які канали мають нативні метадані джерела, яким потрібні збережені вихідні реєстри, а які не можуть забезпечити надійне придушення cross-bot echo.
Критерії прийняття
- Кожен вбудований канал повідомлень надсилає фінальний видимий output через
messages.send. - Кожен inbound канал повідомлень входить через
messages.receiveабо задокументовану обгортку сумісності. - Кожен канал попереднього перегляду/редагування/потокового передавання використовує
messages.liveдля стану чернетки та фіналізації. channel.turnє лише обгорткою.- Допоміжні засоби SDK з назвами reply є експортами сумісності, а не рекомендованим шляхом.
- Стійке відновлення може повторно відтворити очікувані фінальні надсилання після перезапуску без втрати фінальної відповіді або дублювання вже зафіксованих надсилань; надсилання, чий результат на платформі невідомий, звіряються перед повторним відтворенням або документуються як at-least-once для цього адаптера.
- Стійкі фінальні надсилання fail closed, коли стійкий намір неможливо записати, якщо викликач явно не вибрав задокументований нестійкий режим.
- Застарілі channel-turn і допоміжні засоби сумісності SDK за замовчуванням використовують пряме доставлення, яким володіє канал; загальне стійке надсилання є лише явним opt-in.
- Підтвердження зберігають усі ідентифікатори повідомлень платформи для багаточастинних доставлень і основний ідентифікатор для зручності threading/edit.
- Стійкі обгортки зберігають локальні побічні ефекти каналу перед заміною прямих callback доставки.
- Підготовлені диспетчери не вважаються стійкими, доки їхній шлях фінального доставлення явно не використовує контекст надсилання.
- Резервне доставлення обробляє кожен спроєктований payload.
- Стійке резервне доставлення записує кожен спроєктований payload в один придатний до повторного відтворення намір або batch plan.
- Вивід збоїв Gateway, ініційований OpenClaw, видимий людям, але позначені ехо в кімнаті від bot-authored відкидаються перед авторизацією bot на каналах, які декларують підтримку контракту джерела.
- Документація пояснює send, receive, live, state, receipts, relations, failure policy, migration і test coverage.