Streaming + chunking
OpenClaw에는 두 개의 별도 “스트리밍” 계층이 있습니다:- 블록 스트리밍 (채널): 조수의 작성이 완료된 블록을 발행합니다. 이는 일반적인 채널 메시지입니다 (토큰 델타 아님).
- 유사 토큰 스트리밍 (Telegram 전용): 생성을 진행하는 동안 임시 미리보기 메시지를 부분적으로 업데이트합니다.
Block streaming (channel messages)
블록 스트리밍은 조수의 출력을 가능한 한 큼직한 청크로 보냅니다.text_delta/events: 모델 스트림 이벤트 (비스트리밍 모델의 경우 드물 수 있음).chunker:EmbeddedBlockChunker가 최소/최대 경계 및 구분 선호도를 적용합니다.channel send: 실제 발신 메시지 (블록 응답).
agents.defaults.blockStreamingDefault:"on"/"off"(기본값 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)로 UI 클리핑을 피하기 위해 긴 응답을 분할.
text_end:chunker가 발행하는 즉시 블록을 스트리밍합니다; 각text_end에서 플러시.message_end: 조수 메시지가 끝날 때까지 기다렸다가 버퍼된 출력을 플러시.
message_end는 버퍼된 텍스트가 maxChars를 초과하면 여전히 chunker를 사용하여 여러 청크를 끝에서 발행할 수 있습니다.
Chunking algorithm (low/high bounds)
블록 청크는EmbeddedBlockChunker로 구현됩니다:
- 낮은 경계: 버퍼가
minChars이상이 될 때까지 발행하지 않습니다 (강제되지 않은 경우). - 높은 경계:
maxChars이전의 분할을 선호합니다; 강제된 경우maxChars에서 분할합니다. - 구분 선호도:
paragraph→newline→sentence→whitespace→ 강제 줄바꿈. - 코드 펜스: 펜스 내에서는 절대 분할하지 않습니다;
maxChars에서 강제된 경우, 펜스를 닫고 다시 열어 Markdown을 유효하게 유지합니다.
maxChars는 채널의 textChunkLimit에 고정되므로 채널별 캡을 초과할 수 없습니다.
Coalescing (merge streamed blocks)
블록 스트리밍이 활성화되어 있을 때, OpenClaw는 연속 블록 청크를 병합하여 보내기 전까지 밀어냅니다. 이는 “단일 라인 스팸”을 줄이면서도 진행 상황을 제공합니다.- 합성은 유휴 간격(
idleMs)이 될 때까지 기다립니다. - 버퍼는
maxChars로 제한되며 초과하면 플러시됩니다. minChars는 충분한 텍스트가 축적될 때까지 작은 조각의 전송을 방지합니다 (최종 플러시는 항상 남은 텍스트를 보냅니다).- 조인은
blockStreamingChunk.breakPreference에서 파생됩니다 (paragraph→\n\n,newline→\n,sentence→ 공백). - 채널 재정의는
*.blockStreamingCoalesce를 통해 가능합니다 (계정별 설정 포함). - 기본 합성
minChars는 Signal/Slack/Discord의 경우 1500으로 증가하며, 재정의되지 않는 한 유지됩니다.
Human-like pacing between blocks
블록 스트리밍이 켜져 있을 때, 블록 응답 사이에 랜덤하게 멈춤을 추가할 수 있습니다 (첫 번째 블록 이후). 이는 다중 버블 응답이 더 자연스럽게 느껴지도록 합니다.- 설정:
agents.defaults.humanDelay(에이전트별로agents.list[].humanDelay로 재정의). - 모드:
off(기본값),natural(800–2500ms),custom(minMs/maxMs). - 이는 블록 응답에만 적용되며, 최종 응답이나 도구 요약에는 적용되지 않습니다.
“Stream chunks or everything”
이는 다음과 같이 매핑됩니다:- Stream chunks:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(즉시 발행). Telegram이 아닌 채널에는*.blockStreaming: true가 필요합니다. - Stream everything at end:
blockStreamingBreak: "message_end"(한 번 플러시, 매우 긴 경우 여러 청크). - No block streaming:
blockStreamingDefault: "off"(최종 응답만).
*.blockStreaming이 명시적으로 true로 설정되지 않는 한 블록 스트리밍은 해제됩니다. Telegram은 블록 응답 없이 실시간 미리보기를 스트리밍할 수 있습니다 (channels.telegram.streamMode).
구성 위치 알림: blockStreaming* 기본값은 루트 구성 아닌 agents.defaults에 있습니다.
Telegram preview streaming (token-ish)
Telegram은 실시간 미리보기 스트리밍을 지원하는 유일한 채널입니다:- Bot API
sendMessage(첫 번째 업데이트) 및editMessageText(후속 업데이트)를 사용합니다. channels.telegram.streamMode: "partial" | "block" | "off".partial: 최신 스트림 텍스트로 미리보기를 업데이트합니다.block: 청크된 블록에서 미리보기를 업데이트합니다 (동일한 청크 규칙).off: 미리보기 스트리밍 없음.
- 미리보기 청크 구성 (
streamMode: "block"전용):channels.telegram.draftChunk(기본값:minChars: 200,maxChars: 800). - 미리보기 스트리밍은 블록 스트리밍과 별도입니다.
- Telegram 블록 스트리밍이 명시적으로 활성화되면, 중복 스트리밍을 피하기 위해 미리보기 스트리밍이 건너뜁니다.
- 텍스트 전용 최종은 동일한 미리보기 메시지를 편집하여 적용됩니다.
- 비텍스트/복잡한 최종은 정상적인 최종 메시지 전달로 되돌아갑니다.
/reasoning stream이 실시간 미리보기에 추론을 기록합니다 (Telegram 전용).
preview message: 생성 중 업데이트되는 임시 Telegram 메시지.final edit: 동일한 미리보기 메시지에서의 제자리 편집 (텍스트 전용).