fix(platform): prevent chat loading state flicker during tool call transitions#492
Conversation
…ansitions Add hasIncompleteAssistantMessage check to keep loading indicator active when status transitions between streaming and pending during tool calls.
Greptile SummaryFixes a UI flicker where the chat loading indicator would briefly disappear during tool call transitions. When an assistant message transitions from
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| services/platform/app/features/chat/hooks/use-message-processing.ts | Adds hasIncompleteAssistantMessage computed via useMemo — checks if last assistant message status is non-terminal (streaming/pending). Clean logic, correct use of findLast, proper memoization dependency. |
| services/platform/app/features/chat/components/chat-interface.tsx | Integrates hasIncompleteAssistantMessage into isLoading boolean. This keeps loading indicator active during streaming→pending→streaming transitions. The flag is partially redundant with !!streamingMessage during the streaming phase, but the redundancy is harmless and the pending coverage is the key improvement. |
| services/platform/app/features/chat/hooks/tests/use-message-processing.test.ts | Comprehensive test coverage for hasIncompleteAssistantMessage, streamingMessage, and pendingToolResponse. Covers edge cases: no messages, user-only messages, all four status values, multi-message ordering. |
| services/platform/app/features/chat/hooks/tests/use-chat-pending-state.test.ts | New tests for useChatPendingState covering streaming clearing, fallback clearing, human input response behavior, and combined scenarios. Well-structured with proper use of renderHook, rerender, and act. |
Sequence Diagram
sequenceDiagram
participant User
participant ChatInterface
participant useMessageProcessing
participant UIMessages
User->>ChatInterface: Send message
ChatInterface->>ChatInterface: isPending = true
UIMessages-->>useMessageProcessing: assistant status = "streaming"
useMessageProcessing-->>ChatInterface: streamingMessage ✓, hasIncomplete ✓
ChatInterface->>ChatInterface: isLoading = true (streaming)
Note over UIMessages: Tool call begins
UIMessages-->>useMessageProcessing: assistant status = "pending"
useMessageProcessing-->>ChatInterface: streamingMessage ✗, hasIncomplete ✓
ChatInterface->>ChatInterface: isLoading = true (hasIncomplete prevents flicker)
Note over UIMessages: Tool call completes
UIMessages-->>useMessageProcessing: assistant status = "streaming"
useMessageProcessing-->>ChatInterface: streamingMessage ✓, hasIncomplete ✓
ChatInterface->>ChatInterface: isLoading = true (streaming resumes)
UIMessages-->>useMessageProcessing: assistant status = "success"
useMessageProcessing-->>ChatInterface: streamingMessage ✗, hasIncomplete ✗
ChatInterface->>ChatInterface: isLoading = false
Last reviewed commit: ea94fad
📝 WalkthroughWalkthroughThis PR introduces a new Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@services/platform/app/features/chat/hooks/__tests__/use-message-processing.test.ts`:
- Around line 22-33: The test fixture createUIMessage currently force-casts the
returned object with "as UIMessage"; replace that cast by using TypeScript's
"satisfies UIMessage" on the object literal so the compiler verifies
compatibility without widening types — keep the function signature the same,
merge overrides as before, and remove the trailing "as UIMessage" so the
returned object satisfies UIMessage while preserving precise literal types.
Summary
hasIncompleteAssistantMessagecheck touseMessageProcessingthat detects when the last assistant message is still in a non-terminal state (streamingorpending)isLoadingcomputation inChatInterfaceto keep the loading indicator active during status transitions between streaming and pending (e.g., during tool calls)useMessageProcessinganduseChatPendingStatehooks covering the new behavior and existing functionalityTest plan
hasIncompleteAssistantMessagecovering: no messages, no assistant messages, success/failed/streaming/pending statuses, and multi-message scenariosuseChatPendingStatecovering pending state clearing on streaming, fallback, and human input responses🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests