Messages and delivery
Потокове передавання та фрагментація
OpenClaw має два окремі рівні потокового передавання:
- Потокове передавання блоків (канали): надсилає завершені блоки під час написання відповіді асистентом. Це звичайні повідомлення каналу (не дельти токенів).
- Потокове передавання попереднього перегляду (Telegram/Discord/Slack): оновлює тимчасове повідомлення попереднього перегляду під час генерування.
Сьогодні справжнього потокового передавання дельт токенів у повідомлення каналу немає. Потокове передавання попереднього перегляду працює на рівні повідомлень (надсилання + редагування/додавання).
Потокове передавання блоків (повідомлення каналу)
Потокове передавання блоків надсилає вивід асистента грубими фрагментами, щойно він стає доступним.
Model output └─ text_delta/events ├─ (blockStreamingBreak=text_end) │ └─ chunker emits blocks as buffer grows └─ (blockStreamingBreak=message_end) └─ chunker flushes at message_end └─ channel send (block replies)Легенда:
text_delta/events: події потоку моделі (можуть бути розрідженими для непотокових моделей).chunker:EmbeddedBlockChunker, що застосовує мінімальні/максимальні межі + пріоритет розриву.channel send: фактичні вихідні повідомлення (блокові відповіді).
Елементи керування:
agents.defaults.blockStreamingDefault:"on"/"off"(типово вимкнено).- Перевизначення каналів:
*.blockStreaming(і варіанти для окремих облікових записів), щоб примусово встановити"on"/"off"для кожного каналу. agents.defaults.blockStreamingBreak:"text_end"або"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(об’єднує потокові блоки перед надсиланням).- Жорстке обмеження каналу:
*.textChunkLimit(наприклад,channels.whatsapp.textChunkLimit). - Режим фрагментації каналу:
*.chunkMode(lengthтипово,newlineрозбиває за порожніми рядками (межами абзаців) перед фрагментацією за довжиною). - М’яке обмеження Discord:
channels.discord.maxLinesPerMessage(типово 17) розбиває високі відповіді, щоб уникнути обрізання в інтерфейсі.
Семантика меж:
text_end: передавати блоки, щойноchunkerїх видає; скидати буфер на кожномуtext_end.message_end: чекати завершення повідомлення асистента, а потім скидати буферизований вивід.
message_end усе одно використовує chunker, якщо буферизований текст перевищує maxChars, тому наприкінці він може видати кілька фрагментів.
Доставлення медіа з потоковим передаванням блоків
Потокові медіа мають використовувати структуровані поля корисного навантаження, як-от mediaUrl або
mediaUrls; потоковий текст не розбирається як команда вкладення. Коли потокове
передавання блоків надсилає медіа рано, OpenClaw запам’ятовує цю доставку для поточного ходу. Якщо
фінальне корисне навантаження асистента повторює ту саму URL-адресу медіа, фінальна доставка
вилучає дубльоване медіа замість повторного надсилання вкладення.
Точні дублікати фінальних корисних навантажень пригнічуються. Якщо фінальне корисне навантаження додає окремий текст навколо медіа, яке вже було передано потоково, OpenClaw усе одно надсилає новий текст, зберігаючи одноразову доставку медіа. Це запобігає дублюванню голосових нотаток або файлів у таких каналах, як Telegram.
Алгоритм фрагментації (нижня/верхня межі)
Фрагментацію блоків реалізує EmbeddedBlockChunker:
- Нижня межа: не видавати, доки буфер >=
minChars(якщо не примусово). - Верхня межа: надавати перевагу розбиттю перед
maxChars; якщо примусово, розбивати наmaxChars. - Пріоритет розриву:
paragraph→newline→sentence→whitespace→ жорсткий розрив. - Кодові блоки: ніколи не розбивати всередині блоків; коли примусово на
maxChars, закрити + знову відкрити блок, щоб Markdown залишався коректним.
maxChars обмежується значенням textChunkLimit каналу, тому неможливо перевищити обмеження окремого каналу.
Об’єднання (злиття потокових блоків)
Коли потокове передавання блоків увімкнено, OpenClaw може об’єднувати послідовні фрагменти блоків перед надсиланням. Це зменшує «спам одним рядком», водночас зберігаючи поступовий вивід.
- Об’єднання чекає на паузи без активності (
idleMs) перед скиданням. - Буфери обмежені
maxCharsі будуть скинуті, якщо перевищать його. minCharsзапобігає надсиланню крихітних фрагментів, доки не накопичиться достатньо тексту (фінальне скидання завжди надсилає залишковий текст).- Роздільник визначається з
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ пробіл). - Перевизначення каналів доступні через
*.blockStreamingCoalesce(включно з конфігураціями для окремих облікових записів). - Типове значення
minCharsдля об’єднання підвищено до 1500 для Signal/Slack/Discord, якщо його не перевизначено.
Людиноподібний темп між блоками
Коли потокове передавання блоків увімкнено, можна додати рандомізовану паузу між блоковими відповідями (після першого блоку). Це робить відповіді з кількох бульбашок природнішими.
- Конфігурація:
agents.defaults.humanDelay(перевизначення для кожного агента черезagents.list[].humanDelay). - Режими:
off(типово),natural(800-2500ms),custom(minMs/maxMs). - Застосовується лише до блокових відповідей, не до фінальних відповідей або підсумків інструментів.
«Передавати фрагменти або все»
Це відповідає:
- Передавати фрагменти:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(надсилати в міру генерування). Канали, крім Telegram, також потребують*.blockStreaming: true. - Передавати все наприкінці:
blockStreamingBreak: "message_end"(одне скидання, можливо кілька фрагментів, якщо дуже довго). - Без потокового передавання блоків:
blockStreamingDefault: "off"(лише фінальна відповідь).
Примітка щодо каналу: потокове передавання блоків вимкнене, якщо
*.blockStreaming явно не встановлено в true. Канали можуть передавати живий попередній перегляд
(channels.<channel>.streaming) без блокових відповідей.
Нагадування про розташування конфігурації: типові значення blockStreaming* містяться в
agents.defaults, а не в кореневій конфігурації.
Режими потокового передавання попереднього перегляду
Канонічний ключ: channels.<channel>.streaming
Режими:
off: вимкнути потокове передавання попереднього перегляду.partial: один попередній перегляд, який замінюється найновішим текстом.block: попередній перегляд оновлюється фрагментованими/доданими кроками.progress: попередній перегляд прогресу/стану під час генерування, фінальна відповідь після завершення.
streaming.mode: "block" — це режим потокового передавання попереднього перегляду для каналів із можливістю редагування,
таких як Discord і Telegram. Він не вмикає там доставлення блоків каналу.
Використовуйте streaming.block.enabled або застарілий ключ каналу blockStreaming, коли
потрібні звичайні блокові відповіді. Microsoft Teams є винятком: він не має
транспорту блоків чернеткового попереднього перегляду, тому streaming.mode: "block" зіставляється з блоковою
доставкою Teams замість нативного часткового/прогресового потокового передавання.
Зіставлення каналів
| Канал | off |
partial |
block |
progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | редагована чернетка прогресу |
| Discord | ✅ | ✅ | ✅ | редагована чернетка прогресу |
| Slack | ✅ | ✅ | ✅ | ✅ |
| Mattermost | ✅ | ✅ | ✅ | ✅ |
| MS Teams | ✅ | ✅ | ✅ | нативний потік прогресу |
Лише Slack:
channels.slack.streaming.nativeTransportперемикає виклики нативного API потокового передавання Slack, колиchannels.slack.streaming.mode="partial"(типово:true).- Нативне потокове передавання Slack і статус потоку асистента Slack потребують цільового потоку відповіді. DM верхнього рівня не показують такий попередній перегляд у стилі потоку, але все одно можуть використовувати публікації й редагування чернеткового попереднього перегляду Slack.
Міграція застарілих ключів:
- Telegram: застарілі значення
streamModeі скалярні/булеві значенняstreamingвиявляються та мігруються шляхами сумісності doctor/config доstreaming.mode. - Discord:
streamMode+ булевийstreamingзалишаються runtime-псевдонімами для перелікуstreaming; запустітьopenclaw doctor --fix, щоб переписати збережену конфігурацію. - Slack:
streamModeзалишається runtime-псевдонімом дляstreaming.mode; булевийstreamingзалишається runtime-псевдонімом дляstreaming.modeплюсstreaming.nativeTransport; застарілийnativeStreamingзалишається runtime-псевдонімом дляstreaming.nativeTransport. Запустітьopenclaw doctor --fix, щоб переписати збережену конфігурацію.
Поведінка під час виконання
Telegram:
- Використовує оновлення попереднього перегляду
sendMessage+editMessageTextу DM і групах/темах. - Короткі початкові попередні перегляди все ще мають debounce для UX push-сповіщень, але Telegram тепер матеріалізує їх після обмеженої затримки, щоб активні запуски не залишалися візуально безмовними.
- Фінальний текст редагує активний попередній перегляд на місці; довгі фінальні відповіді повторно використовують це повідомлення для першого фрагмента й надсилають лише решту фрагментів.
- Режим
blockпереносить попередній перегляд у нове повідомлення наstreaming.preview.chunk.maxChars(типово 800, обмежено лімітом редагування Telegram 4096); інші режими нарощують один попередній перегляд до 4096 символів. - Режим
progressтримає прогрес інструментів у редагованій чернетці стану, матеріалізує мітку стану, коли потокове передавання відповіді активне, але рядка інструмента ще немає, очищає цю чернетку після завершення та надсилає фінальну відповідь через звичайну доставку. - Якщо фінальне редагування зазнає невдачі до підтвердження завершеного тексту, OpenClaw використовує звичайну фінальну доставку й очищає застарілий попередній перегляд.
- Потокове передавання попереднього перегляду пропускається, коли потокове передавання блоків Telegram явно ввімкнено (щоб уникнути подвійного потокового передавання).
/reasoning streamможе записувати reasoning у тимчасовий попередній перегляд, який видаляється після фінальної доставки.
Discord:
- Використовує надсилання + редагування повідомлень попереднього перегляду.
- Режим
blockвикористовує фрагментацію чернетки (draftChunk). - Потокове передавання попереднього перегляду пропускається, коли потокове передавання блоків Discord явно ввімкнено.
- Фінальні медіа, помилки та корисні навантаження з явною відповіддю скасовують очікувані попередні перегляди без скидання нової чернетки, а потім використовують звичайну доставку.
Slack:
partialможе використовувати нативне потокове передавання Slack (chat.startStream/append/stop), коли доступно.blockвикористовує чернеткові попередні перегляди в стилі додавання.progressвикористовує текст попереднього перегляду стану, а потім фінальну відповідь.- DM верхнього рівня без потоку відповіді використовують публікації й редагування чернеткового попереднього перегляду замість нативного потокового передавання Slack.
- Нативне та чернеткове потокове передавання попереднього перегляду пригнічують блокові відповіді для цього ходу, тож відповідь Slack передається потоково лише одним шляхом доставки.
- Фінальні корисні навантаження медіа/помилок і фінали прогресу не створюють одноразових чернеткових повідомлень; лише текстові/блокові фінали, які можуть редагувати попередній перегляд, скидають очікуваний текст чернетки.
Mattermost:
- Передає thinking, активність інструментів і частковий текст відповіді в один чернетковий допис попереднього перегляду, який фіналізується на місці, коли фінальну відповідь безпечно надсилати.
- Повертається до надсилання нового фінального допису, якщо допис попереднього перегляду було видалено або він інакше недоступний під час фіналізації.
- Фінальні корисні навантаження медіа/помилок скасовують очікувані оновлення попереднього перегляду перед звичайною доставкою замість скидання тимчасового допису попереднього перегляду.
Matrix:
- Чернеткові попередні перегляди фіналізуються на місці, коли фінальний текст може повторно використати подію попереднього перегляду.
- Фінали лише з медіа, помилками та з невідповідністю цілі відповіді скасовують очікувані оновлення попереднього перегляду перед звичайною доставкою; уже видимий застарілий попередній перегляд редагується.
Оновлення попереднього перегляду прогресу інструментів
Потокове передавання попереднього перегляду також може включати оновлення прогресу інструментів - короткі рядки стану, як-от «пошук в інтернеті», «читання файлу» або «виклик інструмента», - які з’являються в тому самому повідомленні попереднього перегляду, поки інструменти виконуються, перед фінальною відповіддю. У режимі app-server Codex повідомлення преамбули/коментарів Codex використовують той самий шлях попереднього перегляду, тому короткі нотатки прогресу на кшталт «Перевіряю...» можуть потоково потрапляти в редаговану чернетку, не стаючи частиною фінальної відповіді. Це підтримує візуальну активність багатоетапних ходів з інструментами замість мовчання між першим попереднім переглядом thinking і фінальною відповіддю.
Довготривалі інструменти можуть видавати типізований прогрес до повернення результату. Наприклад,
web_fetch встановлює п’ятисекундний таймер під час запуску: якщо fetch усе ще
очікує, попередній перегляд може показати Fetching page content...; якщо fetch завершується
або скасовується до цього, рядок прогресу не видається. Пізніший фінальний результат інструмента
все одно доставляється моделі звичайним способом.
Підтримувані поверхні:
- Discord, Slack, Telegram і Matrix за замовчуванням транслюють поступ інструментів і оновлення преамбули Codex у живе редагування попереднього перегляду, коли активне потокове передавання попереднього перегляду. Microsoft Teams використовує власний потік поступу в особистих чатах.
- Telegram постачається з увімкненими оновленнями попереднього перегляду поступу інструментів із
v2026.4.22; якщо залишити їх увімкненими, це збереже випущену поведінку. - Mattermost уже згортає активність інструментів у свій єдиний допис чернетки попереднього перегляду (див. вище).
- Редагування поступу інструментів відповідають активному режиму потокового передавання попереднього перегляду; їх пропускають, коли потокове передавання попереднього перегляду має значення
offабо коли потокове передавання блоків перебрало повідомлення. У Telegramstreaming.mode: "off"означає лише фінальний результат: загальний шум поступу також пригнічується, а не доставляється як окремі статусні повідомлення, тоді як запити на схвалення, медіавміст і помилки й далі маршрутизуються звичайно. - Щоб зберегти потокове передавання попереднього перегляду, але приховати рядки поступу інструментів, установіть
streaming.preview.toolProgressнаfalseдля цього каналу. Щоб залишити рядки поступу інструментів видимими, але приховати текст команд/виконання, установітьstreaming.preview.commandTextна"status"абоstreaming.progress.commandTextна"status"; типове значення —"raw", щоб зберегти випущену поведінку. Ця політика спільна для каналів чернеток/поступу, які використовують компактний рендерер поступу OpenClaw, зокрема Discord, Matrix, Microsoft Teams, Mattermost, попередні перегляди чернеток Slack і Telegram. Щоб повністю вимкнути редагування попереднього перегляду, установітьstreaming.modeнаoff. - Вибрані відповіді з цитатою в Telegram є винятком: коли
replyToModeне дорівнює"off"і присутній вибраний текст цитати, OpenClaw пропускає потік попереднього перегляду відповіді для цього ходу, тож рядки попереднього перегляду поступу інструментів не можуть відобразитися. Відповіді на поточне повідомлення без вибраного тексту цитати й далі зберігають потокове передавання попереднього перегляду. Докладніше див. у документації каналу Telegram.
Смуга поступу commentary
Окрім поступу інструментів, компактний рендерер поступу може показувати в чернетці ще одну смугу:
streaming.progress.commentary— відображати передінструментальний коментар моделі (💬) — коротку оповідь «Я перевірю… потім…» — упереміш із рядками інструментів у чернетці поступу.
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "commentary": true } } } }}Залиште рядки поступу видимими, але приховайте необроблений текст команд/виконання:
{ "channels": { "telegram": { "streaming": { "mode": "partial", "preview": { "toolProgress": true, "commandText": "status" } } } }}Використовуйте ту саму форму під іншим ключем компактного каналу поступу, наприклад channels.discord, channels.matrix, channels.msteams, channels.mattermost або попередні перегляди чернеток Slack. Для режиму чернетки поступу розмістіть ту саму політику в streaming.progress:
{ "channels": { "telegram": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}Пов’язане
- Рефакторинг життєвого циклу повідомлень - цільовий дизайн спільного попереднього перегляду, редагування, потоку й фіналізації
- Чернетки поступу - видимі повідомлення про роботу в процесі, що оновлюються під час довгих ходів
- Повідомлення - життєвий цикл повідомлень і доставка
- Повторна спроба - поведінка повторної спроби в разі збою доставки
- Канали - підтримка потокового передавання для кожного каналу