Messages and delivery

Потокове передавання та фрагментація

OpenClaw має два окремі рівні потокового передавання:

  • Потокове передавання блоків (канали): надсилає завершені блоки під час написання відповіді асистентом. Це звичайні повідомлення каналу (не дельти токенів).
  • Потокове передавання попереднього перегляду (Telegram/Discord/Slack): оновлює тимчасове повідомлення попереднього перегляду під час генерування.

Сьогодні справжнього потокового передавання дельт токенів у повідомлення каналу немає. Потокове передавання попереднього перегляду працює на рівні повідомлень (надсилання + редагування/додавання).

Потокове передавання блоків (повідомлення каналу)

Потокове передавання блоків надсилає вивід асистента грубими фрагментами, щойно він стає доступним.

Code
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.
  • Пріоритет розриву: paragraphnewlinesentencewhitespace → жорсткий розрив.
  • Кодові блоки: ніколи не розбивати всередині блоків; коли примусово на 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 або коли потокове передавання блоків перебрало повідомлення. У Telegram streaming.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 — відображати передінструментальний коментар моделі (💬) — коротку оповідь «Я перевірю… потім…» — упереміш із рядками інструментів у чернетці поступу.
json
{  "channels": {    "discord": {      "streaming": { "mode": "progress", "progress": { "commentary": true } }    }  }}

Залиште рядки поступу видимими, але приховайте необроблений текст команд/виконання:

json
{  "channels": {    "telegram": {      "streaming": {        "mode": "partial",        "preview": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

Використовуйте ту саму форму під іншим ключем компактного каналу поступу, наприклад channels.discord, channels.matrix, channels.msteams, channels.mattermost або попередні перегляди чернеток Slack. Для режиму чернетки поступу розмістіть ту саму політику в streaming.progress:

json
{  "channels": {    "telegram": {      "streaming": {        "mode": "progress",        "progress": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

Пов’язане

Was this useful?
On this page

On this page