← Back to PRs

#9195: Fix: Control UI fails to render new messages after chat.history WebSocket response

by vishaltandale00 open 2026-02-05 00:34 View on GitHub →
app: web-ui stale
## Summary Fixes #9183 - Control UI was failing to render new agent messages after successful chat.history WebSocket responses. ## Problem When a chat run completed and the `final` event was received, `loadChatHistory()` was called to refresh the message list. However, the new messages never appeared in the UI without a manual page refresh. The browser console showed successful `[ws] ⇄ res ✓ chat.history` responses, indicating the data was received but not rendered. ## Root Cause The `GatewayHost` type definition was missing properties required by `loadChatHistory()`: - `chatLoading` - `chatMessages` - `chatThinkingLevel` When `handleGatewayEvent()` called: ```typescript void loadChatHistory(host as unknown as OpenClawApp); ``` The unsafe type cast (`as unknown as OpenClawApp`) passed TypeScript's checks, but at runtime: 1. `loadChatHistory()` tried to assign `state.chatMessages = newMessages` 2. This property didn't exist on the `GatewayHost` interface 3. The assignment had no effect on the OpenClawApp component's reactive `@state() chatMessages` 4. Lit Element never knew to re-render TypeScript allowed the cast because `unknown` bypasses type checking, but the actual object structure didn't match expectations. ## Solution Added the missing properties to the `GatewayHost` type definition: ```typescript type GatewayHost = { // ... existing properties chatLoading: boolean; chatMessages: unknown[]; chatThinkingLevel: string | null; // ... rest }; ``` Now when `loadChatHistory()` updates these properties: 1. The assignments affect the actual OpenClawApp component state 2. The `@state()` decorator detects the change 3. Lit Element triggers a re-render 4. New messages appear automatically ## Why This Works The `GatewayHost` type is used as a constraint for functions that manipulate the OpenClawApp state. By ensuring it includes all properties that event handlers need to update, we guarantee that: - TypeScript type checking is accurate - Runtime property assignments affect the correct Lit Element reactive state - UI re-renders happen automatically when data changes ## Impact ✅ Messages now render immediately after agent replies ✅ No more manual page refreshes needed ✅ Fixes the UX issue reported in #9183 ✅ Type safety improved - prevents similar bugs ✅ Single file changed, minimal risk ## Testing **Before fix:** 1. Send message to agent 2. Agent responds 3. Message doesn't appear 4. Console shows `[ws] ⇄ res ✓ chat.history` 5. Hard refresh (Ctrl+Shift+R) shows the message **After fix:** 1. Send message to agent 2. Agent responds 3. Message appears immediately ✅ 4. No refresh needed --- **Technical note:** This is a type system bug where an unsafe cast (`as unknown as T`) bypassed proper type checking. The fix tightens the type constraint to match runtime requirements. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR updates the `GatewayHost` type in `ui/src/ui/app-gateway.ts` to include chat-related state (`chatLoading`, `chatMessages`, `chatThinkingLevel`, `chatStream`, `chatStreamStartedAt`) that is mutated by `loadChatHistory()` and other chat controllers. By aligning `GatewayHost` with the `OpenClawApp` reactive `@state()` properties, the existing call site `loadChatHistory(host as unknown as OpenClawApp)` now reliably updates real reactive fields instead of assigning to missing properties on an object with an incompatible shape. It also removes two ad-hoc `unknown` casts previously used to reset `chatStream` and `chatStreamStartedAt` on connect. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - The change is a type-level alignment in a single file and matches existing `OpenClawApp` reactive state fields used by chat controllers; it also reduces unsafe casts in the connect path. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs