From d8d5d59d922f50ce1eb7277625886d7eee880050 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Wed, 22 Oct 2025 22:02:29 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20Message=20Cach?= =?UTF-8?q?e=20Clearing=20Logic=20into=20Reusable=20Helper=20(#10226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Agents/AgentDetail.tsx | 7 ++--- client/src/components/Agents/Marketplace.tsx | 9 +++---- .../components/Chat/Menus/HeaderNewChat.tsx | 9 +++---- client/src/components/Nav/MobileNav.tsx | 6 ++--- client/src/components/Nav/NewChat.tsx | 6 ++--- .../Conversations/useNavigateToConvo.tsx | 10 +++++-- client/src/utils/messages.ts | 26 ++++++++++++++++++- 7 files changed, 45 insertions(+), 28 deletions(-) diff --git a/client/src/components/Agents/AgentDetail.tsx b/client/src/components/Agents/AgentDetail.tsx index 3cbfe330ca..ef77734e30 100644 --- a/client/src/components/Agents/AgentDetail.tsx +++ b/client/src/components/Agents/AgentDetail.tsx @@ -11,9 +11,9 @@ import { AgentListResponse, } from 'librechat-data-provider'; import type t from 'librechat-data-provider'; +import { renderAgentAvatar, clearMessagesCache } from '~/utils'; import { useLocalize, useDefaultConvo } from '~/hooks'; import { useChatContext } from '~/Providers'; -import { renderAgentAvatar } from '~/utils'; interface SupportContact { name?: string; @@ -56,10 +56,7 @@ const AgentDetail: React.FC = ({ agent, isOpen, onClose }) => localStorage.setItem(`${LocalStorageKeys.AGENT_ID_PREFIX}0`, agent.id); - queryClient.setQueryData( - [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], - [], - ); + clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); /** Template with agent configuration */ diff --git a/client/src/components/Agents/Marketplace.tsx b/client/src/components/Agents/Marketplace.tsx index 97cf1b20cc..ef882142e2 100644 --- a/client/src/components/Agents/Marketplace.tsx +++ b/client/src/components/Agents/Marketplace.tsx @@ -4,7 +4,7 @@ import { useOutletContext } from 'react-router-dom'; import { useQueryClient } from '@tanstack/react-query'; import { useSearchParams, useParams, useNavigate } from 'react-router-dom'; import { TooltipAnchor, Button, NewChatIcon, useMediaQuery } from '@librechat/client'; -import { PermissionTypes, Permissions, QueryKeys, Constants } from 'librechat-data-provider'; +import { PermissionTypes, Permissions, QueryKeys } from 'librechat-data-provider'; import type t from 'librechat-data-provider'; import type { ContextType } from '~/common'; import { useDocumentTitle, useHasAccess, useLocalize, TranslationKeys } from '~/hooks'; @@ -13,11 +13,11 @@ import MarketplaceAdminSettings from './MarketplaceAdminSettings'; import { SidePanelProvider, useChatContext } from '~/Providers'; import { SidePanelGroup } from '~/components/SidePanel'; import { OpenSidebar } from '~/components/Chat/Menus'; +import { cn, clearMessagesCache } from '~/utils'; import CategoryTabs from './CategoryTabs'; import AgentDetail from './AgentDetail'; import SearchBar from './SearchBar'; import AgentGrid from './AgentGrid'; -import { cn } from '~/utils'; import store from '~/store'; interface AgentMarketplaceProps { @@ -224,10 +224,7 @@ const AgentMarketplace: React.FC = ({ className = '' }) = window.open('/c/new', '_blank'); return; } - queryClient.setQueryData( - [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], - [], - ); + clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); newConversation(); }; diff --git a/client/src/components/Chat/Menus/HeaderNewChat.tsx b/client/src/components/Chat/Menus/HeaderNewChat.tsx index b2dc6416ab..5245ccbf13 100644 --- a/client/src/components/Chat/Menus/HeaderNewChat.tsx +++ b/client/src/components/Chat/Menus/HeaderNewChat.tsx @@ -1,8 +1,8 @@ +import { QueryKeys } from 'librechat-data-provider'; import { useQueryClient } from '@tanstack/react-query'; -import { QueryKeys, Constants } from 'librechat-data-provider'; import { TooltipAnchor, Button, NewChatIcon } from '@librechat/client'; -import type { TMessage } from 'librechat-data-provider'; import { useChatContext } from '~/Providers'; +import { clearMessagesCache } from '~/utils'; import { useLocalize } from '~/hooks'; export default function HeaderNewChat() { @@ -15,10 +15,7 @@ export default function HeaderNewChat() { window.open('/c/new', '_blank'); return; } - queryClient.setQueryData( - [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], - [], - ); + clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); newConversation(); }; diff --git a/client/src/components/Nav/MobileNav.tsx b/client/src/components/Nav/MobileNav.tsx index e945ec5be1..6f11b327ce 100644 --- a/client/src/components/Nav/MobileNav.tsx +++ b/client/src/components/Nav/MobileNav.tsx @@ -5,6 +5,7 @@ import { QueryKeys, Constants } from 'librechat-data-provider'; import type { TMessage } from 'librechat-data-provider'; import type { Dispatch, SetStateAction } from 'react'; import { useLocalize, useNewConvo } from '~/hooks'; +import { clearMessagesCache } from '~/utils'; import store from '~/store'; export default function MobileNav({ @@ -57,10 +58,7 @@ export default function MobileNav({ aria-label={localize('com_ui_new_chat')} className="m-1 inline-flex size-10 items-center justify-center rounded-full hover:bg-surface-hover" onClick={() => { - queryClient.setQueryData( - [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], - [], - ); + clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); newConversation(); }} diff --git a/client/src/components/Nav/NewChat.tsx b/client/src/components/Nav/NewChat.tsx index b3cdd2cac5..026f115103 100644 --- a/client/src/components/Nav/NewChat.tsx +++ b/client/src/components/Nav/NewChat.tsx @@ -5,6 +5,7 @@ import { QueryKeys, Constants } from 'librechat-data-provider'; import { TooltipAnchor, NewChatIcon, MobileSidebar, Sidebar, Button } from '@librechat/client'; import type { TMessage } from 'librechat-data-provider'; import { useLocalize, useNewConvo } from '~/hooks'; +import { clearMessagesCache } from '~/utils'; import store from '~/store'; export default function NewChat({ @@ -33,10 +34,7 @@ export default function NewChat({ window.open('/c/new', '_blank'); return; } - queryClient.setQueryData( - [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], - [], - ); + clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); newConvo(); navigate('/c/new', { state: { focusChat: true } }); diff --git a/client/src/hooks/Conversations/useNavigateToConvo.tsx b/client/src/hooks/Conversations/useNavigateToConvo.tsx index 55f43fa820..2bbb4620b3 100644 --- a/client/src/hooks/Conversations/useNavigateToConvo.tsx +++ b/client/src/hooks/Conversations/useNavigateToConvo.tsx @@ -3,7 +3,13 @@ import { useNavigate } from 'react-router-dom'; import { useQueryClient } from '@tanstack/react-query'; import { QueryKeys, Constants, dataService } from 'librechat-data-provider'; import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider'; -import { buildDefaultConvo, getDefaultEndpoint, getEndpointField, logger } from '~/utils'; +import { + getDefaultEndpoint, + clearMessagesCache, + buildDefaultConvo, + getEndpointField, + logger, +} from '~/utils'; import store from '~/store'; const useNavigateToConvo = (index = 0) => { @@ -80,7 +86,7 @@ const useNavigateToConvo = (index = 0) => { }); } clearAllConversations(true); - queryClient.setQueryData([QueryKeys.messages, currentConvoId], []); + clearMessagesCache(queryClient, currentConvoId); if (convo.conversationId !== Constants.NEW_CONVO && convo.conversationId) { queryClient.invalidateQueries([QueryKeys.conversation, convo.conversationId]); fetchFreshData(convo); diff --git a/client/src/utils/messages.ts b/client/src/utils/messages.ts index fe8ec36499..d436c45077 100644 --- a/client/src/utils/messages.ts +++ b/client/src/utils/messages.ts @@ -1,5 +1,6 @@ -import { ContentTypes } from 'librechat-data-provider'; +import { ContentTypes, QueryKeys, Constants } from 'librechat-data-provider'; import type { TMessage, TMessageContentParts } from 'librechat-data-provider'; +import type { QueryClient } from '@tanstack/react-query'; export const TEXT_KEY_DIVIDER = '|||'; @@ -146,3 +147,26 @@ export const scrollToEnd = (callback?: () => void) => { } } }; + +/** + * Clears messages for both the specified conversation ID and the NEW_CONVO query key. + * This ensures that messages are properly cleared in all contexts, preventing stale data + * from persisting in the NEW_CONVO cache. + * + * @param queryClient - The React Query client instance + * @param conversationId - The conversation ID to clear messages for + */ +export const clearMessagesCache = ( + queryClient: QueryClient, + conversationId: string | undefined | null, +): void => { + const convoId = conversationId ?? Constants.NEW_CONVO; + + // Clear messages for the current conversation + queryClient.setQueryData([QueryKeys.messages, convoId], []); + + // Also clear NEW_CONVO messages if we're not already on NEW_CONVO + if (convoId !== Constants.NEW_CONVO) { + queryClient.setQueryData([QueryKeys.messages, Constants.NEW_CONVO], []); + } +};