← Back to PRs

#14966: fix(webchat): preserve user message visibility after chat.send

by BenediktSchackenberg open 2026-02-12 20:37 View on GitHub →
app: web-ui size: S
## Summary Fixes #14928 When sending a message in webchat, the user's message would disappear after submission. ## Root Cause When a chat message is sent: 1. User message is added to local `chatMessages` array 2. `chat.send` request is made to server 3. On `final` event, `loadChatHistory()` is called 4. `loadChatHistory()` **replaces** local messages with server data 5. If server hasn't persisted the user message yet → **message disappears** ## Solution Added `preserveLocalUser` option to `loadChatHistory()` that: - Captures local user messages (those without IDs, indicating they're local-only) - After fetching server history, merges any missing local user messages back - Uses timestamp matching to avoid duplicates ## Changes `ui/src/ui/controllers/chat.ts`: - Extended `loadChatHistory()` with `opts?: { preserveLocalUser?: boolean }` - Added logic to preserve and merge local user messages `ui/src/ui/app-gateway.ts`: - Pass `{ preserveLocalUser: true }` when calling `loadChatHistory()` on final events ## Testing - [x] `pnpm build` - ✅ Success - [x] `pnpm check` - ✅ Success - [x] `pnpm test` - ✅ 270 tests passed ## AI Disclosure 🤖 AI-assisted (Claude), fully tested locally before submission. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR updates the webchat final-event flow to avoid a just-sent user message disappearing when `loadChatHistory()` refreshes from the server before the message has been persisted. Changes include: - `ui/src/ui/controllers/chat.ts`: adds an optional `preserveLocalUser` flag to `loadChatHistory()` that captures local-only user messages (role `user` without an `id`) and merges any missing ones back after fetching `chat.history`. - `ui/src/ui/app-gateway.ts`: passes `{ preserveLocalUser: true }` when refreshing history on `final` chat events. The approach fits into the existing pattern where the gateway event handler triggers a history reload on `final` to keep the chat UI up to date, but now attempts to retain local optimistic messages during that reload. <h3>Confidence Score: 3/5</h3> - This PR is likely safe to merge after fixing message ordering and improving duplicate detection for preserved local messages. - Core change is small and localized, but the merge strategy can reorder chat history and the timestamp-only de-duplication can incorrectly drop or duplicate messages in realistic edge cases (multiple sends within the same ms or timestamp normalization differences). - ui/src/ui/controllers/chat.ts <sub>Last reviewed commit: 4cbec25</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