Messages and delivery
Потоковая передача и разбиение на части
OpenClaw использует два независимых уровня потоковой передачи, и на сегодняшний день настоящей потоковой передачи дельт токенов в сообщения каналов нет:
- Потоковая передача блоков (каналы): отправляет завершённые блоки по мере того, как ассистент формирует ответ. Это обычные сообщения канала, а не дельты токенов.
- Потоковый предпросмотр (Telegram/Discord/Slack/Matrix/Mattermost/MS Teams): обновляет временное сообщение предпросмотра во время генерации (отправка + редактирование/добавление).
Потоковая передача блоков (сообщения канала)
Потоковая передача блоков отправляет вывод ассистента крупными фрагментами по мере их готовности.
Вывод модели └─ text_delta/события ├─ (blockStreamingBreak=text_end) │ └─ средство разбиения выдаёт блоки по мере роста буфера └─ (blockStreamingBreak=message_end) └─ средство разбиения сбрасывает буфер при message_end └─ отправка в канал (блочные ответы)text_delta/events: события потока модели (могут быть редкими для непотоковых моделей).chunker:EmbeddedBlockChunkerс применением минимальной/максимальной границы и предпочтительного места разрыва.channel send: фактически отправляемые сообщения (блочные ответы).
Параметры управления (все находятся в agents.defaults, если не указано иное):
| Ключ | Значения / структура | По умолчанию |
|---|---|---|
blockStreamingDefault |
"on" / "off" |
"off" |
blockStreamingBreak |
"text_end" / "message_end" |
- |
blockStreamingChunk |
{ minChars, maxChars, breakPreference? } |
- |
blockStreamingCoalesce |
{ minChars?, maxChars?, idleMs? } (объединять потоковые блоки перед отправкой) |
- |
*.streaming.block.enabled (переопределение для канала) |
true / false, принудительно включает потоковую передачу блоков для канала (и учётной записи) |
- |
*.textChunkLimit (например, channels.whatsapp.textChunkLimit) |
число, жёсткое ограничение | 4000 |
*.streaming.chunkMode |
"length" / "newline" |
"length" |
channels.discord.maxLinesPerMessage |
число, мягкое ограничение строк, разделяющее высокие ответы во избежание обрезки в интерфейсе | 17 |
streaming.chunkMode: "newline" разделяет текст по пустым строкам (границам абзацев),
а не по каждому переводу строки; если текст превышает ограничение,
используется разбиение по длине.
Во встроенных каналах эти переопределения записываются как
channels.<id>.streaming.{chunkMode,block.enabled,block.coalesce}. Плоские
варианты *.chunkMode / *.blockStreaming / *.blockStreamingCoalesce являются
устаревшими для всех встроенных каналов: openclaw doctor --fix переносит их
во вложенную структуру, а схемы каналов отклоняют их. Конфигурации внешних
плагинов SDK, которые всё ещё используют плоские варианты, продолжат работать
через устаревший резервный механизм (с предупреждением во время выполнения)
до следующего цикла выпусков.
Семантика границ для blockStreamingBreak:
text_end: передавать блоки сразу после их выдачи средством разбиения; сбрасывать при каждомtext_end.message_end: ждать завершения сообщения ассистента, затем сбрасывать накопленный вывод. Если накопленный текст превышаетmaxChars, по-прежнему используется средство разбиения, поэтому в конце может быть отправлено несколько фрагментов.
Доставка медиафайлов при потоковой передаче блоков
Потоковая передача медиафайлов должна использовать структурированные поля полезной нагрузки, такие как mediaUrl или
mediaUrls; потоковый текст не анализируется как команда вложения. Когда при потоковой
передаче блоков медиафайл отправляется заранее, OpenClaw запоминает эту доставку для текущего хода. Если
итоговая полезная нагрузка ассистента повторяет тот же URL медиафайла, при итоговой доставке
дубликат медиафайла удаляется, а вложение повторно не отправляется.
Полностью идентичные итоговые полезные нагрузки подавляются. Если итоговая полезная нагрузка добавляет отдельный текст вокруг уже переданного медиафайла, OpenClaw всё равно отправляет новый текст, сохраняя однократную доставку медиафайла. Это предотвращает дублирование голосовых сообщений или файлов в таких каналах, как Telegram.
Алгоритм разбиения (нижняя/верхняя границы)
Разбиение на блоки реализовано в EmbeddedBlockChunker:
- Нижняя граница: не отправлять, пока размер буфера не достигнет
minChars(кроме принудительной отправки). - Верхняя граница: предпочитать разрывы до
maxChars; при принудительном разрыве разделять наmaxChars. - Цепочка предпочтений для разрыва:
paragraph->newline->sentence-> пробельный символ -> жёсткий разрыв. - Блоки кода: никогда не разделять внутри ограждений; при принудительном разрыве на
maxCharsзакрывать и повторно открывать ограждение, чтобы сохранить корректность Markdown.
maxChars ограничивается значением канала textChunkLimit, поэтому превысить
ограничения конкретного канала невозможно.
Объединение (слияние потоковых блоков)
Когда потоковая передача блоков включена, OpenClaw может объединять последовательные фрагменты блоков перед их отправкой, сокращая количество отдельных коротких сообщений и при этом сохраняя постепенную выдачу.
- Перед сбросом объединение ожидает периоды бездействия (
idleMs). - Размер буферов ограничен значением
maxChars; при его превышении буферы сбрасываются. minCharsпредотвращает отправку мелких фрагментов, пока не накопится достаточно текста (при итоговом сбросе оставшийся текст отправляется всегда).- Разделитель определяется значением
blockStreamingChunk.breakPreference:paragraph->\n\n,newline->\n,sentence-> пробел. - Переопределения для каналов доступны через
*.streaming.block.coalesce(включая конфигурации отдельных учётных записей). - Для Discord, Signal и Slack объединение по умолчанию имеет значение
{ minChars: 1500, idleMs: 1000 }, если оно не переопределено.
Имитация естественных пауз между блоками
Когда потоковая передача блоков включена, после первого блока между блочными ответами добавляется случайная пауза, чтобы ответы из нескольких сообщений выглядели естественнее.
agents.defaults.humanDelay.mode |
Поведение |
|---|---|
off (по умолчанию) |
Без паузы |
natural |
Случайная пауза 800-2500ms |
custom |
minMs/maxMs |
Переопределяется для каждого агента через agents.list[].humanDelay. Применяется только к блочным
ответам, но не к итоговым ответам или сводкам инструментов.
«Передавать фрагменты или всё целиком»
- Передавать фрагменты:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(отправлять по мере готовности). Для каналов, кроме Telegram, также требуется*.streaming.block.enabled: true. - Передать всё в конце:
blockStreamingBreak: "message_end"(однократный сброс, возможно с несколькими фрагментами, если текст очень длинный). - Без потоковой передачи блоков:
blockStreamingDefault: "off"(только итоговый ответ).
Потоковая передача блоков отключена, если *.streaming.block.enabled не задано явно
как true (исключение: QQ Bot не имеет ключей streaming.block и передаёт
блочные ответы, если channels.qqbot.streaming.mode не равно "off"). Каналы могут
передавать предпросмотр в реальном времени (channels.<channel>.streaming.mode) без блочных
ответов. Значения blockStreaming* по умолчанию находятся в agents.defaults, а не в
корне конфигурации.
Режимы потокового предпросмотра
Канонический ключ: channels.<channel>.streaming (вложенный { mode, ... }; устаревшие
логические/строковые варианты верхнего уровня преобразуются openclaw doctor --fix).
| Режим | Поведение |
|---|---|
off |
Отключить потоковый предпросмотр |
partial |
Единый предпросмотр заменяется последней версией текста |
block |
Предпросмотр обновляется поэтапно путём разбиения/добавления |
progress |
Предпросмотр хода выполнения/состояния во время генерации, итоговый ответ после завершения |
streaming.mode: "block" — режим потокового предпросмотра для каналов
с поддержкой редактирования, таких как Discord и Telegram; сам по себе он не включает
доставку блоков в эти каналы. Для обычных блочных ответов используйте streaming.block.enabled.
Исключением является Microsoft Teams:
в нём нет транспорта блочного предпросмотра черновика, поэтому streaming.mode: "block" полностью отключает встроенную потоковую передачу, а ответ поступает как обычная
блочная доставка вместо встроенной потоковой передачи частичного результата/хода выполнения. Mattermost также
отличается: в режиме block предпросмотр чередуется между завершённым текстом и
блоками активности инструментов, поэтому предыдущие блоки остаются видимыми как отдельные публикации,
а не перезаписываются в одном редактируемом черновике.
Сопоставление каналов
| Канал | off |
partial |
block |
progress |
|---|---|---|---|---|
| Telegram | Да | Да | Да | редактируемый черновик хода выполнения |
| Discord | Да | Да | Да | редактируемый черновик хода выполнения |
| Slack | Да | Да | Да | Да |
| Mattermost | Да | Да | Да | Да |
| MS Teams | Да | Да | Да | встроенный поток хода выполнения |
Конфигурация фрагментов предпросмотра (streaming.preview.chunk.*, например в
channels.discord.streaming или channels.telegram.streaming) по умолчанию использует
minChars: 200, maxChars: 800 (с ограничением до значения канала textChunkLimit) и
breakPreference: "paragraph".
Только для Slack:
channels.slack.streaming.nativeTransportвключает или отключает вызовы встроенного API потоковой передачи Slack (chat.startStream/chat.appendStream/chat.stopStream), когдаchannels.slack.streaming.mode="partial"(по умолчанию:true).- Для встроенной потоковой передачи Slack и состояния ветки ассистента Slack требуется целевая ветка ответа. Личные сообщения верхнего уровня не показывают такой предпросмотр в виде ветки, но всё равно могут использовать публикации и редактирование черновика предпросмотра Slack.
Миграция устаревших ключей
| Канал | Устаревшие ключи | Состояние |
|---|---|---|
| Telegram | streamMode, скалярное/логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не читается |
| Discord | streamMode, логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не читается |
| Slack | streamMode; логическое streaming; устаревшее nativeStreaming |
Преобразуется в streaming.mode (и streaming.nativeTransport для логической/устаревшей формы) с помощью openclaw doctor --fix; во время выполнения не читается |
| Matrix | скалярное/логическое streaming |
Преобразуется в streaming.mode (включая режим Matrix "quiet") с помощью openclaw doctor --fix; во время выполнения не читается |
| Feishu | логическое streaming |
Преобразуется в streaming.mode с помощью openclaw doctor --fix; во время выполнения не читается |
| QQ Bot | логическое streaming; streaming.c2cStreamApi |
Преобразуется в streaming.mode (и streaming.nativeTransport для логической формы/формы c2cStreamApi) с помощью openclaw doctor --fix; во время выполнения не читается |
Поведение во время выполнения
Telegram
- Использует обновления предпросмотра
sendMessage+editMessageTextв личных сообщениях и группах/темах; итоговый текст редактирует активный предпросмотр на месте. В Telegram эфемерные 30-секундные черновики «набора текста» (sendMessageDraft) не используются для потоковой передачи ответа. - Короткие начальные предпросмотры по-прежнему обрабатываются с задержкой для удобства push-уведомлений, но появляются по истечении ограниченной задержки, чтобы активные запуски не оставались визуально безмолвными.
- Для длинных итоговых ответов сообщение предпросмотра повторно используется для первого фрагмента, а отправляются только оставшиеся фрагменты.
- Режим
blockпереносит предпросмотр в новое сообщение приstreaming.preview.chunk.maxChars(по умолчанию 800, с ограничением по лимиту редактирования Telegram в 4096); в других режимах один предпросмотр увеличивается до 4096 символов. - Режим
progressсохраняет ход выполнения инструментов в редактируемом черновике состояния, отображает метку состояния, когда потоковая передача ответа активна, но строка инструмента ещё недоступна, очищает черновик по завершении и отправляет итоговый ответ через обычный механизм доставки. - Если итоговое редактирование завершается с ошибкой до подтверждения завершённого текста, OpenClaw использует обычную доставку итогового ответа и удаляет устаревший предпросмотр.
- Потоковая передача предпросмотра пропускается, когда потоковая передача блоков Telegram явно включена, чтобы избежать двойной потоковой передачи.
/reasoning streamможет выводить рассуждения во временный предпросмотр, который удаляется после доставки итогового ответа.- Ответы с выбранной цитатой в Telegram являются исключением: когда
replyToModeне равно"off"и присутствует текст выбранной цитаты, OpenClaw пропускает потоковую передачу предпросмотра ответа для этого хода (итоговый ответ должен пройти через нативный механизм ответа с цитатой), поэтому строки предпросмотра хода выполнения инструментов не отображаются. Для ответов на текущее сообщение без текста выбранной цитаты потоковая передача предпросмотра сохраняется. Подробности см. в документации канала Telegram.
Discord
- Использует отправку и редактирование сообщений предпросмотра.
- Режим
blockиспользует разбиение черновика на фрагменты (draftChunk). - Потоковая передача предпросмотра пропускается, когда потоковая передача блоков Discord явно включена.
- Режим
progressдобавляет к итоговому ответу небольшую квитанцию активности-#(число размышлений/вызовов инструментов и прошедшее время) и удаляет черновик состояния после доставки ответа, чтобы в активных каналах над ответом не оставался осиротевший журнал инструментов. При итоговом ответе с ошибкой черновик сохраняется как запись неудачного хода. - Итоговые данные с медиа, ошибками и явными ответами отменяют ожидающие предпросмотры, не отправляя новый черновик, а затем используют обычную доставку.
Slack
partialможет использовать нативную потоковую передачу Slack (chat.startStream/append/stop), когда она доступна.blockиспользует предпросмотры черновиков с добавлением текста.progressиспользует текст предпросмотра состояния, а затем итоговый ответ.- Личные сообщения верхнего уровня без ветки ответов используют публикацию и редактирование черновиков предпросмотра вместо нативной потоковой передачи Slack.
- Нативная потоковая передача и потоковая передача предпросмотра черновика подавляют блочные ответы для этого хода, поэтому ответ Slack передаётся только по одному пути доставки.
- Итоговые данные с медиа/ошибками и итоговые сообщения о ходе выполнения не создают одноразовые сообщения-черновики; ожидающий текст черновика отправляют только итоговые текстовые/блочные сообщения, способные отредактировать предпросмотр.
Mattermost
- В режиме
partialпотоково передаёт размышления и частичный текст ответа в одну публикацию-черновик предпросмотра, которая окончательно оформляется на месте, когда итоговый ответ можно безопасно отправить. - В режиме
progressпотоково передаёт размышления и активность инструментов в один предпросмотр состояния, который окончательно оформляется на месте, когда итоговый ответ можно безопасно отправить. - В режиме
blockчередует публикации с завершённым текстом и активностью инструментов; параллельные и последовательные обновления инструментов используют текущую публикацию активности инструментов. - Если публикация предпросмотра была удалена или по иной причине недоступна во время завершения, вместо неё отправляется новая итоговая публикация.
- Итоговые данные с медиа/ошибками отменяют ожидающие обновления предпросмотра перед обычной доставкой вместо отправки временной публикации предпросмотра.
Matrix
- Черновики предпросмотра окончательно оформляются на месте, когда итоговый текст может повторно использовать событие предпросмотра.
- Итоговые сообщения только с медиа, с ошибкой или с несовпадающей целью ответа отменяют ожидающие обновления предпросмотра перед обычной доставкой; уже видимый устаревший предпросмотр удаляется.
Обновления предпросмотра хода выполнения инструментов
Потоковая передача предпросмотра также может включать обновления хода выполнения инструментов: короткие строки состояния, например «поиск в интернете», «чтение файла» или «вызов инструмента», которые появляются в том же сообщении предпросмотра во время работы инструментов, до итогового ответа. В режиме сервера приложений Codex сообщения-преамбулы/комментарии Codex используют тот же путь предпросмотра, поэтому короткие сообщения о ходе выполнения вроде «Проверяю...» могут потоково поступать в редактируемый черновик, не становясь частью итогового ответа. Благодаря этому многоэтапные ходы с инструментами остаются визуально активными, а не безмолвными между первым предпросмотром размышлений и итоговым ответом.
Длительно работающие инструменты могут выдавать типизированные обновления хода выполнения до возврата результата. Например,
web_fetch запускает пятисекундный таймер при старте: если получение данных всё ещё
ожидается, предпросмотр показывает Fetching page content...; если получение данных завершается или
отменяется раньше, строка хода выполнения не выводится. Последующий итоговый результат инструмента
по-прежнему доставляется модели обычным образом.
Поддерживаемые поверхности:
- Discord, Slack, Telegram и Matrix по умолчанию потоково передают ход выполнения инструментов и обновления преамбулы Codex в редактируемый активный предпросмотр, когда потоковая передача предпросмотра включена. Microsoft Teams использует свой нативный поток хода выполнения в личных чатах.
- Telegram поставляется с включёнными обновлениями предпросмотра хода выполнения инструментов начиная с
v2026.4.22; сохранение их включёнными обеспечивает совместимость с выпущенным поведением. - Mattermost объединяет активность инструментов в одну публикацию предпросмотра в режимах
partialиprogressлибо в одну публикацию активности инструментов между текстовыми блоками в режимеblock(см. выше). - Редактирование хода выполнения инструментов следует активному режиму потоковой передачи предпросмотра; оно
пропускается, когда потоковая передача предпросмотра имеет значение
offили когда потоковая передача блоков взяла сообщение под управление. В Telegramstreaming.mode: "off"предназначен только для итоговых сообщений: общий поток сообщений о ходе выполнения также подавляется, а не доставляется в виде отдельных сообщений состояния, тогда как запросы подтверждения, данные с медиа и ошибки по-прежнему маршрутизируются обычным образом. - Чтобы сохранить потоковую передачу предпросмотра, но скрыть строки хода выполнения инструментов, задайте
для
streaming.preview.toolProgressзначениеfalseв этом канале (по умолчаниюtrue). Чтобы строки хода выполнения инструментов оставались видимыми, но текст команд/выполнения был скрыт, задайте дляstreaming.preview.commandTextзначение"status"или дляstreaming.progress.commandTextзначение"status"; по умолчанию используется"raw", чтобы сохранить выпущенное поведение. Эта политика общая для каналов черновиков/хода выполнения, использующих компактный визуализатор хода выполнения OpenClaw, включая Discord, Matrix, Microsoft Teams, Mattermost, предпросмотры черновиков Slack и Telegram. Чтобы полностью отключить редактирование предпросмотра, задайте дляstreaming.modeзначениеoff.
Отображение черновика хода выполнения
Черновики в режиме хода выполнения (streaming.progress.*) имеют ограничения и настраиваются отдельно для каждого
канала:
| Ключ | По умолчанию | Поведение |
|---|---|---|
streaming.progress.maxLines |
8 |
Максимальное число компактных строк хода выполнения под меткой черновика |
streaming.progress.maxLineChars |
120 |
Максимальное число символов в компактной строке до усечения (с учётом слов) |
streaming.progress.label |
"auto" |
Заголовок черновика; пользовательская строка или false, чтобы скрыть его |
streaming.progress.labels |
встроенный набор | Возможные метки, используемые при label: "auto" |
Канал комментариев о ходе выполнения
Помимо хода выполнения инструментов, компактный визуализатор хода выполнения может отображать в черновике ещё один канал:
streaming.progress.commentary— отображать предварительные комментарии модели перед использованием инструментов (короткое описание действий вроде «Проверю... затем...») вперемежку со строками инструментов в черновике хода выполнения. В Discord и Telegram в режиме хода выполнения та же преамбула формирует заголовок состояния, даже если этот необязательный канал выключен; другие каналы сохраняют существующее поведение хода выполнения. См. Черновики хода выполнения.
{ "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" } } } }}Связанные материалы
- Рефакторинг жизненного цикла сообщений — целевая общая архитектура предпросмотра, редактирования, потоковой передачи и завершения
- Черновики хода выполнения — видимые сообщения о выполняемой работе, обновляемые во время длительных ходов
- Сообщения — жизненный цикл и доставка сообщений
- Повторные попытки — поведение повторных попыток при сбое доставки
- Каналы — поддержка потоковой передачи для каждого канала