Skip to content

Commit a901e90

Browse files
Fix agent loop UI bleeding between conversations
## Problem When starting an agent loop in one conversation and switching to another, the "assistant thinking" UI would incorrectly appear in the second conversation, even though it was idle. ## Root Cause The `isLoading` state in ChatInterface was global/shared across all conversations. When conversation A started generating, `isLoading` was set to `true`. Switching to conversation B would still show the thinking UI because `isGenerating = agentLoopState?.isRunning || isLoading` evaluated to `true` due to the shared loading state. ## Solution - **Conversation-specific loading**: Changed from single `isLoading` boolean to `loadingConversations` Set tracking which conversations are loading - **Isolated state**: Each conversation now has independent loading state - **Proper cleanup**: Loading state is properly added/removed per conversation ## Technical Changes - Replaced `useState<boolean>` with `useState<Set<string>>` - Updated `handleSendMessage` to add/remove conversation IDs from Set - Modified `isGenerating` calculation to check current conversation only ## User Experience - ✅ **Isolated UI state**: Thinking UI only appears for actually running conversations - ✅ **No cross-conversation interference**: Switching conversations shows correct state - ✅ **Maintained functionality**: All existing behavior preserved 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent d9e63a7 commit a901e90

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/components/ChatInterface.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function ChatInterface() {
2222
selectModel,
2323
isAuthenticated
2424
} = useInference();
25-
const [isLoading, setIsLoading] = useState(false);
25+
const [loadingConversations, setLoadingConversations] = useState<Set<string>>(new Set());
2626
const messagesEndRef = useRef<HTMLDivElement>(null);
2727

2828
const activeConversation = activeConversationId ? getConversation(activeConversationId) : undefined;
@@ -38,13 +38,17 @@ export function ChatInterface() {
3838
return;
3939
}
4040

41-
setIsLoading(true);
41+
setLoadingConversations(prev => new Set(prev).add(activeConversationId));
4242
try {
4343
await sendMessage(activeConversationId, content);
4444
} catch (error) {
4545
console.error('Failed to send message:', error);
4646
} finally {
47-
setIsLoading(false);
47+
setLoadingConversations(prev => {
48+
const newSet = new Set(prev);
49+
newSet.delete(activeConversationId);
50+
return newSet;
51+
});
4852
}
4953
};
5054

@@ -78,7 +82,8 @@ export function ChatInterface() {
7882
);
7983
}
8084

81-
const isGenerating = agentLoopState?.isRunning || isLoading;
85+
const isCurrentConversationLoading = activeConversationId ? loadingConversations.has(activeConversationId) : false;
86+
const isGenerating = agentLoopState?.isRunning || isCurrentConversationLoading;
8287

8388
return (
8489
<div className="flex-1 flex flex-col h-full">

0 commit comments

Comments
 (0)