fix(webchat): filter NO_REPLY token from streaming and final replies (#16269)#16286
Merged
steipete merged 1 commit intoopenclaw:mainfrom Feb 14, 2026
Merged
Conversation
Comment on lines
+232
to
+235
| if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) { | ||
| chatRunState.buffers.delete(clientRunId); | ||
| return; | ||
| } |
Contributor
There was a problem hiding this comment.
deleting the buffer here means subsequent text won't accumulate correctly if streaming continues after NO_REPLY
the buffer stores the cumulative text for the run, so deleting it on NO_REPLY breaks future deltas. instead, just return early without modifying the buffer:
Suggested change
| if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) { | |
| chatRunState.buffers.delete(clientRunId); | |
| return; | |
| } | |
| if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) { | |
| return; | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/server-chat.ts
Line: 232:235
Comment:
deleting the buffer here means subsequent text won't accumulate correctly if streaming continues after `NO_REPLY`
the buffer stores the cumulative text for the run, so deleting it on `NO_REPLY` breaks future deltas. instead, just return early without modifying the buffer:
```suggestion
if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) {
return;
}
```
How can I resolve this? If you propose a fix, please make it concise.
Contributor
Author
There was a problem hiding this comment.
Good catch — updated to return early without modifying the buffer.
235b118 to
8b2e6cd
Compare
robbyczgw-cla
commented
Feb 14, 2026
Contributor
Author
robbyczgw-cla
left a comment
There was a problem hiding this comment.
Good catch — updated to return early without deleting the buffer. Streaming continues correctly now.
8b2e6cd to
d29ca08
Compare
The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
d29ca08 to
33885cb
Compare
Contributor
|
Landed via squash onto main.
Thanks @robbyczgw-cla! |
Swader
pushed a commit
to Swader/openclaw
that referenced
this pull request
Feb 14, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
akoscz
pushed a commit
to akoscz/openclaw
that referenced
this pull request
Feb 15, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
GwonHyeok
pushed a commit
to learners-superpumped/openclaw
that referenced
this pull request
Feb 15, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
vincentkoc
pushed a commit
to vincentkoc/openclaw
that referenced
this pull request
Feb 15, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
snowzlm
pushed a commit
to snowzlm/openclaw
that referenced
this pull request
Feb 15, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…penclaw#16286) The webchat channel sent NO_REPLY as visible text to clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming path bypassed this check. Fixes openclaw#16269
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The webchat channel sent
NO_REPLYas visible text to WebSocket clients instead of suppressing it. Other channels (Telegram, Discord) already filter this token via the reply dispatcher, but the webchat streaming/outbound path bypassed this check.Root Cause
In
src/gateway/server-chat.ts,createAgentEventHandler()forwarded assistant stream text directly to webchat chat events without applying silent-token filtering:emitChatDelta(...)sentstate: \"delta\"payloads fromevt.data.textas-is.emitChatFinal(...)built finalstate: \"final\"message fromchatRunState.buffersas-is.evt.stream === \"assistant\"(emitChatDelta) and lifecycle end/error (emitChatFinal).Because this path bypasses the normal reply dispatcher normalization,
NO_REPLYcould leak both in streaming updates and in the final chat payload.Changes
src/gateway/server-chat.ts:isSilentReplyTextandSILENT_REPLY_TOKENfromsrc/auto-reply/tokens.ts.emitChatDelta, suppress delta emission when streamed text is silent token.emitChatFinal, suppress finalmessagewhen buffered text is silent token.src/gateway/server-chat.agent-events.test.ts:message: undefined)Testing
npm run lint✅npm test -- src/gateway/server-chat.agent-events.test.ts✅npm test -- --testPathPattern=\"web\"❌ (current Vitest CLI in this repo does not support--testPathPattern; returnsUnknown option --testPathPattern)Edge Cases Considered
Greptile Overview
Greptile Summary
prevented
NO_REPLYtoken from appearing in webchat stream deltas and final messages by addingisSilentReplyTextchecks inemitChatDeltaandemitChatFinalKey Changes
isSilentReplyTextandSILENT_REPLY_TOKENfromsrc/auto-reply/tokens.tsemitChatDelta) and final message path (emitChatFinal)NO_REPLYis suppressed in both streaming and final eventsIssue Found
emitChatDeltadeletes the buffer onNO_REPLY, which breaks cumulative text tracking if more text streams after the silent token (see inline comment on src/gateway/server-chat.ts:232)Confidence Score: 3/5
NO_REPLYleak and follows existing channel patterns, but the buffer deletion inemitChatDeltawill break text accumulation if streaming continues after the silent tokenLast reviewed commit: 6adf2eb