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 <noreply@anthropic.com>
This commit is contained in:
Jerome 2025-06-12 14:49:53 +01:00
commit a901e90b59
No known key found for this signature in database

View file

@ -22,7 +22,7 @@ export function ChatInterface() {
selectModel,
isAuthenticated
} = useInference();
const [isLoading, setIsLoading] = useState(false);
const [loadingConversations, setLoadingConversations] = useState<Set<string>>(new Set());
const messagesEndRef = useRef<HTMLDivElement>(null);
const activeConversation = activeConversationId ? getConversation(activeConversationId) : undefined;
@ -38,13 +38,17 @@ export function ChatInterface() {
return;
}
setIsLoading(true);
setLoadingConversations(prev => new Set(prev).add(activeConversationId));
try {
await sendMessage(activeConversationId, content);
} catch (error) {
console.error('Failed to send message:', error);
} finally {
setIsLoading(false);
setLoadingConversations(prev => {
const newSet = new Set(prev);
newSet.delete(activeConversationId);
return newSet;
});
}
};
@ -78,7 +82,8 @@ export function ChatInterface() {
);
}
const isGenerating = agentLoopState?.isRunning || isLoading;
const isCurrentConversationLoading = activeConversationId ? loadingConversations.has(activeConversationId) : false;
const isGenerating = agentLoopState?.isRunning || isCurrentConversationLoading;
return (
<div className="flex-1 flex flex-col h-full">