From c9e76819e99aa773e137ee0f8e08efb282aae358 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 11 Mar 2025 09:38:49 -0600 Subject: [PATCH 1/5] initialize listing data --- .../api/buster_rest/chats/queryRequests.ts | 13 +++--------- web/src/api/buster_rest/metrics/requests.ts | 20 +++++++++---------- web/src/api/query_keys/chat.ts | 3 ++- .../useBusterChatListByFilter.tsx | 4 +--- 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/web/src/api/buster_rest/chats/queryRequests.ts b/web/src/api/buster_rest/chats/queryRequests.ts index 57ca1e942..4e4d15412 100644 --- a/web/src/api/buster_rest/chats/queryRequests.ts +++ b/web/src/api/buster_rest/chats/queryRequests.ts @@ -8,25 +8,18 @@ import { updateChat, deleteChat } from './requests'; -import type { BusterChatListItem, IBusterChat } from '@/api/asset_interfaces/chat'; +import type { IBusterChat } from '@/api/asset_interfaces/chat'; import { queryKeys } from '@/api/query_keys'; import { updateChatToIChat } from '@/lib/chat'; import { RustApiError } from '@/api/buster_rest/errors'; export const useGetListChats = (params?: Parameters[0]) => { - const queryFn = useMemoizedFn((): Promise => { - return getListChats(params); - }); + const queryFn = useMemoizedFn(() => getListChats(params)); - const res = useQuery({ + return useQuery({ ...queryKeys.chatsGetList(params), queryFn }); - - return { - ...res, - data: res.data || [] - }; }; export const prefetchGetListChats = async ( diff --git a/web/src/api/buster_rest/metrics/requests.ts b/web/src/api/buster_rest/metrics/requests.ts index 7344fe519..0070a881e 100644 --- a/web/src/api/buster_rest/metrics/requests.ts +++ b/web/src/api/buster_rest/metrics/requests.ts @@ -29,26 +29,24 @@ export const listMetrics_server = async (params: ListMetricsParams) => { return await serverFetch('/metrics/list', { params }); }; -export const getMetricData = async (params: { id: string }) => { - return mainApi.get(`/metrics/data`, { params }).then((res) => res.data); +export const getMetricData = async ({ id }: { id: string }) => { + return mainApi.get(`/metrics/data/${id}`).then((res) => res.data); }; export const updateMetric = async (params: UpdateMetricParams) => { - return mainApi.put(`/metrics/update`, { params }).then((res) => res.data); -}; - -export const deleteMetrics = async (params: { ids: string[] }) => { return mainApi - .delete(`/metrics/delete`, { params }) + .put(`/metrics/update/${params.id}`, { params }) .then((res) => res.data); }; -export const duplicateMetrics = async (params: { +export const deleteMetrics = async (params: { ids: string[] }) => { + return mainApi.delete(`/metrics/delete`, { params }).then((res) => res.data); +}; + +export const duplicateMetric = async (params: { id: string; message_id: string; share_with_same_people: boolean; }) => { - return mainApi - .post(`/metrics/duplicate`, { params }) - .then((res) => res.data); + return mainApi.post(`/metrics/duplicate`, { params }).then((res) => res.data); }; diff --git a/web/src/api/query_keys/chat.ts b/web/src/api/query_keys/chat.ts index 38bfbfdb6..33cf91d8e 100644 --- a/web/src/api/query_keys/chat.ts +++ b/web/src/api/query_keys/chat.ts @@ -27,7 +27,8 @@ const chatsMessagesFetchingData = (messageId: string) => const chatsGetList = (filters?: GetChatListParams) => queryOptions({ queryKey: ['chats', 'list', filters] as const, - staleTime: 10 * 1000 + staleTime: 10 * 1000, + initialData: [] }); const chatsBlackBoxMessages = (messageId: string) => diff --git a/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx b/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx index d59690534..6af087310 100644 --- a/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx +++ b/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx @@ -12,10 +12,8 @@ export const useBusterChatListByFilter = ( const { data: chatsList, isFetched: isFetchedChatsList } = useGetListChats(filters); - //ACTIONS - return { - list: chatsList || [], + list: chatsList, isFetched: isFetchedChatsList }; }; From 8108a3315505b59cd34a900193504fb52acbec93 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 11 Mar 2025 09:43:38 -0600 Subject: [PATCH 2/5] update bar animation --- .../ReasoningMessages/BarContainer.tsx | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/web/src/controllers/ReasoningController/ReasoningMessages/BarContainer.tsx b/web/src/controllers/ReasoningController/ReasoningMessages/BarContainer.tsx index b50cbe845..e7d4e1936 100644 --- a/web/src/controllers/ReasoningController/ReasoningMessages/BarContainer.tsx +++ b/web/src/controllers/ReasoningController/ReasoningMessages/BarContainer.tsx @@ -13,10 +13,14 @@ export const BarContainer: React.FC<{ children?: React.ReactNode; title: string; secondaryTitle?: string; -}> = React.memo(({ showBar, status, children, title, secondaryTitle }) => { +}> = React.memo(({ showBar, isCompletedStream, status, children, title, secondaryTitle }) => { return (
- +
@@ -31,37 +35,44 @@ BarContainer.displayName = 'BarContainer'; const VerticalBarContainer: React.FC<{ showBar: boolean; status: BusterChatMessageReasoning_status; -}> = React.memo(({ showBar, status }) => { + isCompletedStream: boolean; +}> = React.memo(({ showBar, isCompletedStream, status }) => { return (
- +
); }); VerticalBarContainer.displayName = 'BarContainer'; -const VerticalBar: React.FC<{ show?: boolean }> = ({ show }) => { - return ( -
- -
- ); -}; +const VerticalBar: React.FC<{ show?: boolean; isCompletedStream: boolean }> = React.memo( + ({ show, isCompletedStream }) => { + return ( +
+ + + +
+ ); + } +); + +VerticalBar.displayName = 'VerticalBar'; const TitleContainer: React.FC<{ title: string; From 8cfccc7bc1a8257a1a49d61e309ef539811c7d6a Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 11 Mar 2025 09:46:57 -0600 Subject: [PATCH 3/5] Update AIWarning.tsx --- .../ChatContent/ChatInput/AIWarning.tsx | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/AIWarning.tsx b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/AIWarning.tsx index 8abf479e2..9005217bd 100644 --- a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/AIWarning.tsx +++ b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/AIWarning.tsx @@ -1,14 +1,17 @@ import React from 'react'; import { Text } from '@/components/ui/typography'; -export const AIWarning = React.memo(() => { - return ( -
- - Our AI may make mistakes. Check important info. - -
- ); -}); +export const AIWarning = React.memo( + () => { + return ( +
+ + Our AI may make mistakes. Check important info. + +
+ ); + }, + () => true +); AIWarning.displayName = 'AIWarning'; From e8081b0df1883c7c1a1032d0f40bd125088c0646 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 11 Mar 2025 09:59:37 -0600 Subject: [PATCH 4/5] put toaster back in place --- .../BusterNotifications/BusterNotifications.tsx | 3 ++- .../context/BusterReactQuery/getQueryClient.ts | 4 ++-- .../ChatLayout/ChatContext/ChatContext.tsx | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/web/src/context/BusterNotifications/BusterNotifications.tsx b/web/src/context/BusterNotifications/BusterNotifications.tsx index 6c0d34133..a54a0427c 100644 --- a/web/src/context/BusterNotifications/BusterNotifications.tsx +++ b/web/src/context/BusterNotifications/BusterNotifications.tsx @@ -1,5 +1,6 @@ 'use client'; +import { Toaster } from '@/components/ui/toaster/Toaster'; import React, { PropsWithChildren } from 'react'; import { toast, type ExternalToast } from 'sonner'; import { useContextSelector, createContext } from 'use-context-selector'; @@ -167,7 +168,7 @@ export const BusterNotificationsProvider: React.FC = ({ child return ( {children} - {/* */} + ); }; diff --git a/web/src/context/BusterReactQuery/getQueryClient.ts b/web/src/context/BusterReactQuery/getQueryClient.ts index 8ce582f88..d8c73b245 100644 --- a/web/src/context/BusterReactQuery/getQueryClient.ts +++ b/web/src/context/BusterReactQuery/getQueryClient.ts @@ -21,8 +21,8 @@ function makeQueryClient(params?: { enabled: (params?.enabled ?? true) && baseEnabled, queryFn: () => Promise.resolve(), retry: (failureCount, error) => { - if (params?.openErrorNotification && failureCount > 0) { - params.openErrorNotification(error); + if (params?.openErrorNotification) { + // params.openErrorNotification(error); } return false; } diff --git a/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx b/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx index 834fabeeb..1a5e73ad6 100644 --- a/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx +++ b/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx @@ -4,6 +4,9 @@ import type { SelectedFile } from '../interfaces'; import { useAutoChangeLayout } from './useAutoChangeLayout'; import { useGetChat } from '@/api/buster_rest/chats'; import { useMessageIndividual } from '@/context/Chats'; +import { useQueries } from '@tanstack/react-query'; +import { queryKeys } from '@/api/query_keys'; +import { IBusterChatMessage } from '@/api/asset_interfaces/chat'; const useChatIndividualContext = ({ chatId, @@ -28,7 +31,19 @@ const useChatIndividualContext = ({ //MESSAGES const currentMessageId = chatMessageIds[chatMessageIds.length - 1]; - const isStreamingMessage = useMessageIndividual(currentMessageId, (x) => !x?.isCompletedStream); + + const isStreamingMessage = useQueries({ + queries: chatMessageIds.map((messageId) => { + const queryKey = queryKeys.chatsMessages(messageId); + return { + ...queryKey, + select: (data: IBusterChatMessage | undefined) => !data?.isCompletedStream, + enabled: false + }; + }) + }).some((query) => query.data); + + console.log('isCompletedStreamQueries', isStreamingMessage); useAutoChangeLayout({ lastMessageId: currentMessageId, From d0a32dad5d3b76bcb32b396aea61c7e73238e268 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 11 Mar 2025 10:11:34 -0600 Subject: [PATCH 5/5] rip out duplicate filters thing --- .../api/buster_rest/chats/queryRequests.ts | 14 +++++++++++--- web/src/api/buster_rest/chats/requests.ts | 4 ++-- .../organizations/queryRequests.ts | 3 +-- web/src/api/query_keys/chat.ts | 2 +- .../_ChatsListContainer/ChatListContainer.tsx | 7 ++++--- .../context/Chats/ChatListProvider/index.ts | 1 - .../useBusterChatListByFilter.tsx | 19 ------------------- web/src/context/Chats/index.ts | 8 +------- .../ChatContent/ChatInput/ChatInput.tsx | 8 ++------ .../ChatContent/ChatInput/useChatInputFlow.ts | 12 +++++++++--- .../ChatLayout/ChatContext/ChatContext.tsx | 8 +++----- 11 files changed, 34 insertions(+), 52 deletions(-) delete mode 100644 web/src/context/Chats/ChatListProvider/index.ts delete mode 100644 web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx diff --git a/web/src/api/buster_rest/chats/queryRequests.ts b/web/src/api/buster_rest/chats/queryRequests.ts index 4e4d15412..22fe2badf 100644 --- a/web/src/api/buster_rest/chats/queryRequests.ts +++ b/web/src/api/buster_rest/chats/queryRequests.ts @@ -12,12 +12,20 @@ import type { IBusterChat } from '@/api/asset_interfaces/chat'; import { queryKeys } from '@/api/query_keys'; import { updateChatToIChat } from '@/lib/chat'; import { RustApiError } from '@/api/buster_rest/errors'; +import { useMemo } from 'react'; -export const useGetListChats = (params?: Parameters[0]) => { - const queryFn = useMemoizedFn(() => getListChats(params)); +export const useGetListChats = ( + filters?: Omit[0], 'page_token' | 'page_size'> +) => { + const filtersCompiled: Parameters[0] = useMemo( + () => ({ admin_view: false, page_token: 0, page_size: 3000, ...filters }), + [filters] + ); + + const queryFn = useMemoizedFn(() => getListChats(filtersCompiled)); return useQuery({ - ...queryKeys.chatsGetList(params), + ...queryKeys.chatsGetList(filtersCompiled), queryFn }); }; diff --git a/web/src/api/buster_rest/chats/requests.ts b/web/src/api/buster_rest/chats/requests.ts index 28a16977a..f29e03803 100644 --- a/web/src/api/buster_rest/chats/requests.ts +++ b/web/src/api/buster_rest/chats/requests.ts @@ -13,7 +13,7 @@ const CHATS_BASE = '/chats'; export const getListChats = async (params?: GetChatListParams): Promise => { const { page_token = 0, page_size = 1000, admin_view = false } = params || {}; return mainApi - .get(`${CHATS_BASE}/list`, { + .get(`${CHATS_BASE}`, { params: { page_token, page_size, admin_view } }) .then((res) => res.data); @@ -24,7 +24,7 @@ export const getListChats_server = async ( params?: GetChatListParams ): Promise => { const { page_token = 0, page_size = 1000, admin_view = false } = params || {}; - return await serverFetch(`${CHATS_BASE}/list`, { + return await serverFetch(`${CHATS_BASE}`, { params: { page_token, page_size, admin_view } }); }; diff --git a/web/src/api/buster_rest/organizations/queryRequests.ts b/web/src/api/buster_rest/organizations/queryRequests.ts index 5707119aa..fdaadd0a3 100644 --- a/web/src/api/buster_rest/organizations/queryRequests.ts +++ b/web/src/api/buster_rest/organizations/queryRequests.ts @@ -16,8 +16,7 @@ export const useGetOrganizationUsers = (organizationId: string) => { queryKey, staleTime: 10 * 1000, queryFn, - enabled: !!organizationId, - initialData: [] + enabled: !!organizationId }); }; diff --git a/web/src/api/query_keys/chat.ts b/web/src/api/query_keys/chat.ts index 33cf91d8e..be41802a5 100644 --- a/web/src/api/query_keys/chat.ts +++ b/web/src/api/query_keys/chat.ts @@ -27,7 +27,7 @@ const chatsMessagesFetchingData = (messageId: string) => const chatsGetList = (filters?: GetChatListParams) => queryOptions({ queryKey: ['chats', 'list', filters] as const, - staleTime: 10 * 1000, + staleTime: 0, initialData: [] }); diff --git a/web/src/app/app/(primary_layout)/chats/_ChatsListContainer/ChatListContainer.tsx b/web/src/app/app/(primary_layout)/chats/_ChatsListContainer/ChatListContainer.tsx index 5379e10aa..e8ba6131a 100644 --- a/web/src/app/app/(primary_layout)/chats/_ChatsListContainer/ChatListContainer.tsx +++ b/web/src/app/app/(primary_layout)/chats/_ChatsListContainer/ChatListContainer.tsx @@ -1,15 +1,16 @@ 'use client'; import React, { useState } from 'react'; -import { useBusterChatListByFilter } from '@/context/Chats'; import { ChatItemsContainer } from './ChatItemsContainer'; +import { useGetListChats } from '@/api/buster_rest/chats'; +import { GetChatListParams } from '@/api/request_interfaces/chats'; export const ChatListContainer: React.FC<{}> = ({}) => { - const [filters, setFilters] = useState[0]>({ + const [filters, setFilters] = useState>({ admin_view: false }); - const { list, isFetched } = useBusterChatListByFilter(filters); + const { data: list, isFetched } = useGetListChats(filters); return ; }; diff --git a/web/src/context/Chats/ChatListProvider/index.ts b/web/src/context/Chats/ChatListProvider/index.ts deleted file mode 100644 index 49bde0dc1..000000000 --- a/web/src/context/Chats/ChatListProvider/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useBusterChatListByFilter'; diff --git a/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx b/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx deleted file mode 100644 index 6af087310..000000000 --- a/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useGetListChats } from '@/api/buster_rest/chats'; -import { GetChatListParams } from '@/api/request_interfaces/chats'; -import { useMemo } from 'react'; - -export const useBusterChatListByFilter = ( - filtersProp: Omit -) => { - const filters = useMemo( - () => ({ ...filtersProp, page_token: 0, page_size: 3000 }), - [filtersProp] - ); - - const { data: chatsList, isFetched: isFetchedChatsList } = useGetListChats(filters); - - return { - list: chatsList, - isFetched: isFetchedChatsList - }; -}; diff --git a/web/src/context/Chats/index.ts b/web/src/context/Chats/index.ts index fbf5edeec..c056cb94b 100644 --- a/web/src/context/Chats/index.ts +++ b/web/src/context/Chats/index.ts @@ -1,12 +1,6 @@ import { useBusterNewChatContextSelector } from './NewChatProvider'; import { useBusterChatContextSelector, useMessageIndividual } from './ChatProvider'; -import { useBusterChatListByFilter } from './ChatListProvider'; export * from './BusterChatProvider'; -export { - useBusterNewChatContextSelector, - useBusterChatContextSelector, - useBusterChatListByFilter, - useMessageIndividual -}; +export { useBusterNewChatContextSelector, useBusterChatContextSelector, useMessageIndividual }; diff --git a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/ChatInput.tsx b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/ChatInput.tsx index 81a524b54..3a68443d1 100644 --- a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/ChatInput.tsx +++ b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/ChatInput.tsx @@ -18,7 +18,7 @@ export const ChatInput: React.FC<{}> = React.memo(({}) => { return !inputHasText(inputValue); }, [inputValue]); - const { onSubmitPreflight } = useChatInputFlow({ + const { onSubmitPreflight, onStopChat } = useChatInputFlow({ disableSubmit, inputValue, setInputValue, @@ -30,10 +30,6 @@ export const ChatInput: React.FC<{}> = React.memo(({}) => { setInputValue(e.target.value); }); - const onStop = useMemoizedFn(() => { - // setInputValue(''); - }); - return (
= React.memo(({}) => { autoResize={autoResizeConfig} onSubmit={onSubmitPreflight} onChange={onChange} - onStop={onStop} + onStop={onStopChat} loading={loading} disabledSubmit={disableSubmit} autoFocus diff --git a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.ts b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.ts index 280b9c7c2..1c7125d3d 100644 --- a/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.ts +++ b/web/src/layouts/ChatLayout/ChatContainer/ChatContent/ChatInput/useChatInputFlow.ts @@ -25,7 +25,7 @@ export const useChatInputFlow = ({ const onStartNewChat = useBusterNewChatContextSelector((state) => state.onStartNewChat); const onFollowUpChat = useBusterNewChatContextSelector((state) => state.onFollowUpChat); const onStartChatFromFile = useBusterNewChatContextSelector((state) => state.onStartChatFromFile); - const onStopChat = useBusterNewChatContextSelector((state) => state.onStopChat); + const onStopChatContext = useBusterNewChatContextSelector((state) => state.onStopChat); const currentMessageId = useChatIndividualContextSelector((x) => x.currentMessageId); const flow: FlowType = useMemo(() => { @@ -39,7 +39,7 @@ export const useChatInputFlow = ({ if (disableSubmit || !chatId || !currentMessageId) return; if (loading) { - onStopChat({ chatId: chatId!, messageId: currentMessageId }); + onStopChat(); return; } @@ -79,5 +79,11 @@ export const useChatInputFlow = ({ }, 50); }); - return { onSubmitPreflight }; + const onStopChat = useMemoizedFn(() => { + onStopChatContext({ chatId: chatId!, messageId: currentMessageId }); + textAreaRef.current?.focus(); + textAreaRef.current?.select(); + }); + + return { onSubmitPreflight, onStopChat }; }; diff --git a/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx b/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx index 1a5e73ad6..f27e3cb60 100644 --- a/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx +++ b/web/src/layouts/ChatLayout/ChatContext/ChatContext.tsx @@ -3,7 +3,6 @@ import { createContext, useContextSelector } from 'use-context-selector'; import type { SelectedFile } from '../interfaces'; import { useAutoChangeLayout } from './useAutoChangeLayout'; import { useGetChat } from '@/api/buster_rest/chats'; -import { useMessageIndividual } from '@/context/Chats'; import { useQueries } from '@tanstack/react-query'; import { queryKeys } from '@/api/query_keys'; import { IBusterChatMessage } from '@/api/asset_interfaces/chat'; @@ -40,10 +39,9 @@ const useChatIndividualContext = ({ select: (data: IBusterChatMessage | undefined) => !data?.isCompletedStream, enabled: false }; - }) - }).some((query) => query.data); - - console.log('isCompletedStreamQueries', isStreamingMessage); + }), + combine: (result) => result.some((res) => res.data) + }); useAutoChangeLayout({ lastMessageId: currentMessageId,