← Back to PRs

#22994: fix(gateway): flush text buffer before tool events to prevent data loss

by youngkent open 2026-02-21 22:17 View on GitHub →
gateway size: XS
## Problem When using webchat, text can be truncated mid-stream when tool calls occur. The 150ms throttle in `emitChatDelta` skips broadcasts when deltas arrive faster than 150ms apart. If a tool event arrives while text is buffered but not yet broadcast, the pending text is lost. ### Example scenario: 1. Text "Current" → broadcast (150ms passed) 2. Text "Current time is 23:48:08" → stored in buffer, NOT broadcast (<150ms) 3. Tool event arrives → buffer NOT flushed 4. New text "websocket.js" → overwrites buffer, previous text lost forever ## Solution Flush the pending text buffer before processing any tool event. This ensures all accumulated text is broadcast to webchat clients before tool processing begins. ## Summary - **Problem:** Webchat streaming loses text when tool calls interrupt the 150ms throttle window - **Why it matters:** Users see truncated/incomplete responses during multi-tool-call interactions - **What changed:** Added buffer flush before tool event processing in `server-chat.ts` - **What did NOT change:** Channel messages (Telegram, Discord, etc.) are unaffected - they use `blockReplyPipeline` ## Change Type (select all) - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [ ] API / contracts - [x] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - None (discovered during webchat development) ## User-visible / Behavior Changes Webchat users will no longer experience text truncation during responses that include multiple tool calls. ## Security Impact (required) - New permissions/capabilities? `No` - Secrets/tokens handling changed? `No` - New/changed network calls? `No` - Command/tool execution surface changed? `No` - Data access scope changed? `No` ## Repro + Verification ### Environment - OS: Ubuntu 22.04 - Runtime: Node.js v22 - Model: Claude (any) - Integration: Webchat ### Steps 1. Connect to OpenClaw via webchat interface 2. Send a message that triggers multiple tool calls in quick succession 3. Observe the streamed response text ### Expected Full text visible, including all content between tool calls ### Actual (before fix) Text truncated - content written just before tool calls is lost ## Evidence - [x] Tested manually with webchat interface showing truncation before fix and full text after - [x] Verified Telegram/Discord channels unaffected (use different code path) ## Human Verification (required) - **Verified scenarios:** Multi-tool-call responses via webchat, single tool calls, no tool calls - **Edge cases checked:** Rapid successive tool calls, tool calls at message boundaries - **What I did NOT verify:** Performance impact (minimal - only adds check before tool events) ## Compatibility / Migration - Backward compatible? `Yes` - Config/env changes? `No` - Migration needed? `No` ## Failure Recovery (if this breaks) - **Revert:** Remove the `if (isToolEvent && !isAborted)` block in `server-chat.ts` - **Symptoms:** If broken, webchat would show duplicate text or unexpected deltas ## Risks and Mitigations - **Risk:** Slight increase in broadcast frequency during tool-heavy responses - **Mitigation:** Flush only triggers when there is actually pending text (`pendingText && Date.now() - lastSent >= 1`)

Most Similar PRs