shelley: refresh conversations list on reconnect
Philip Zeyliger
and
Shelley
created 1 month ago
Prompt: When shelley comes back from a reconnection, it needs to refresh the conversations list, since it could have missed updates.
When the SSE stream reconnects after a disconnection, conversation list
updates may have been missed. Refresh the full conversations list on
reconnect to ensure the sidebar is up to date.
Uses a hasConnectedRef to distinguish initial connection from reconnects,
avoiding a redundant fetch on first load.
Co-authored-by: Shelley <shelley@exe.dev>
Change summary
ui/src/App.tsx | 10 ++++++++++
ui/src/components/ChatInterface.tsx | 11 ++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
Detailed changes
@@ -294,6 +294,15 @@ function App() {
}
};
+ const refreshConversations = async () => {
+ try {
+ const convs = await api.getConversations();
+ setConversations(convs);
+ } catch (err) {
+ console.error("Failed to refresh conversations:", err);
+ }
+ };
+
const startNewConversation = () => {
// Save the current conversation's cwd to localStorage so the new conversation picks it up
if (currentConversation?.cwd) {
@@ -468,6 +477,7 @@ function App() {
openDiffViewerTrigger={diffViewerTrigger}
modelsRefreshTrigger={modelsRefreshTrigger}
onOpenModelsModal={() => setModelsModalOpen(true)}
+ onReconnect={refreshConversations}
/>
</div>
@@ -457,6 +457,7 @@ interface ChatInterfaceProps {
openDiffViewerTrigger?: number; // increment to trigger opening diff viewer
modelsRefreshTrigger?: number; // increment to trigger models list refresh
onOpenModelsModal?: () => void;
+ onReconnect?: () => void;
}
function ChatInterface({
@@ -475,6 +476,7 @@ function ChatInterface({
openDiffViewerTrigger,
modelsRefreshTrigger,
onOpenModelsModal,
+ onReconnect,
}: ChatInterfaceProps) {
const [messages, setMessages] = useState<Message[]>([]);
const [loading, setLoading] = useState(true);
@@ -607,6 +609,7 @@ function ChatInterface({
const periodicRetryRef = useRef<number | null>(null);
const heartbeatTimeoutRef = useRef<number | null>(null);
const lastSequenceIdRef = useRef<number>(-1);
+ const hasConnectedRef = useRef(false);
const userScrolledRef = useRef(false);
// Load messages and set up streaming
@@ -638,8 +641,9 @@ function ChatInterface({
if (heartbeatTimeoutRef.current) {
clearTimeout(heartbeatTimeoutRef.current);
}
- // Reset sequence ID when conversation changes
+ // Reset sequence ID and connection tracking when conversation changes
lastSequenceIdRef.current = -1;
+ hasConnectedRef.current = false;
};
}, [conversationId]);
@@ -926,6 +930,11 @@ function ChatInterface({
eventSource.onopen = () => {
console.log("Message stream connected");
+ // Refresh conversations list on reconnect (may have missed updates while disconnected)
+ if (hasConnectedRef.current) {
+ onReconnect?.();
+ }
+ hasConnectedRef.current = true;
// Reset reconnect attempts and clear periodic retry on successful connection
setReconnectAttempts(0);
setIsDisconnected(false);