← Back to PRs

#15118: Fix webchat ghost bubble when model replies with NO_REPLY

by jwchmodx open 2026-02-13 02:05 View on GitHub →
app: web-ui size: S
## Summary Fixes #15060 When the model returns `NO_REPLY` during streaming, the webchat was rendering an empty bubble artifact. This PR detects `NO_REPLY` text in the message rendering logic and prevents the ghost bubble from appearing. ## Changes - Added `isSilentReplyText()` helper function to detect NO_REPLY messages in the UI - Modified `renderGroupedMessage()` to skip rendering when message text is NO_REPLY - Exported `renderGroupedMessage()` to enable unit testing - Added comprehensive test suite for NO_REPLY scenarios (7 tests) ## Test plan - ✅ All 7 new NO_REPLY tests pass - ✅ All existing UI tests pass (199/204 total, 5 pre-existing failures unrelated to this change) - ✅ `pnpm build` succeeds - ✅ `pnpm check` passes (formatting, type-checking, linting) ## Technical details The fix works by checking the extracted text before rendering and returning `nothing` from Lit when the text matches `NO_REPLY`. This prevents the bubble from being created in the DOM. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR prevents “ghost” webchat bubbles by treating `NO_REPLY` assistant outputs as silent and returning Lit’s `nothing` from `renderGroupedMessage()`. Changes are localized to `ui/src/ui/chat/grouped-render.ts` (new `isSilentReplyText()` and exporting `renderGroupedMessage()` for testing) plus a new Vitest suite covering several `NO_REPLY`/empty-text scenarios. One correctness concern: the UI `isSilentReplyText()` implementation diverges from the server’s boundary-based `isSilentReplyText` in `src/auto-reply/tokens.ts`, which can cause the UI to suppress messages the server would not consider silent and the new tests currently lock in that divergent behavior. <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable but has a semantic mismatch that can hide real chat content. - The rendering change is small and targeted, but the new UI-only `isSilentReplyText()` does not match the server’s boundary-based definition, so it can suppress non-silent outputs; the accompanying tests currently encode that behavior. - ui/src/ui/chat/grouped-render.ts and ui/src/ui/chat/grouped-render.test.ts <sub>Last reviewed commit: d950f43</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs