| import { |
| QueryKeys, |
| dataService, |
| defaultOrderQuery, |
| defaultAssistantsVersion, |
| } from 'librechat-data-provider'; |
| import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query'; |
| import type { |
| UseInfiniteQueryOptions, |
| QueryObserverResult, |
| UseQueryOptions, |
| UseQueryResult, |
| } from '@tanstack/react-query'; |
| import type t from 'librechat-data-provider'; |
| import type { |
| Action, |
| TPreset, |
| TFile, |
| TPlugin, |
| FileConfig, |
| ConversationListResponse, |
| ConversationListParams, |
| Assistant, |
| AssistantListParams, |
| AssistantListResponse, |
| AssistantDocument, |
| TEndpointsConfig, |
| TCheckUserKeyResponse, |
| SharedLinkListParams, |
| SharedLinksResponse, |
| } from 'librechat-data-provider'; |
| import { findPageForConversation, addFileToCache } from '~/utils'; |
|
|
| export const useGetFiles = <TData = TFile[] | boolean>( |
| config?: UseQueryOptions<TFile[], unknown, TData>, |
| ): QueryObserverResult<TData, unknown> => { |
| return useQuery<TFile[], unknown, TData>([QueryKeys.files], () => dataService.getFiles(), { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }); |
| }; |
|
|
| export const useGetFileConfig = <TData = FileConfig>( |
| config?: UseQueryOptions<FileConfig, unknown, TData>, |
| ): QueryObserverResult<TData, unknown> => { |
| return useQuery<FileConfig, unknown, TData>( |
| [QueryKeys.fileConfig], |
| () => dataService.getFileConfig(), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useGetPresetsQuery = ( |
| config?: UseQueryOptions<TPreset[]>, |
| ): QueryObserverResult<TPreset[], unknown> => { |
| return useQuery<TPreset[]>([QueryKeys.presets], () => dataService.getPresets(), { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }); |
| }; |
|
|
| export const useGetEndpointsConfigOverride = <TData = unknown | boolean>( |
| config?: UseQueryOptions<unknown | boolean, unknown, TData>, |
| ): QueryObserverResult<TData> => { |
| return useQuery<unknown | boolean, unknown, TData>( |
| [QueryKeys.endpointsConfigOverride], |
| () => dataService.getEndpointsConfigOverride(), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useGetConvoIdQuery = ( |
| id: string, |
| config?: UseQueryOptions<t.TConversation>, |
| ): QueryObserverResult<t.TConversation> => { |
| const queryClient = useQueryClient(); |
| return useQuery<t.TConversation>( |
| [QueryKeys.conversation, id], |
| () => { |
| const defaultQuery = () => dataService.getConversationById(id); |
| const convosQuery = queryClient.getQueryData<t.ConversationData>([ |
| QueryKeys.allConversations, |
| ]); |
|
|
| if (!convosQuery) { |
| return defaultQuery(); |
| } |
|
|
| const { pageIndex, index } = findPageForConversation(convosQuery, { conversationId: id }); |
|
|
| if (pageIndex > -1 && index > -1) { |
| return convosQuery.pages[pageIndex].conversations[index]; |
| } |
|
|
| return defaultQuery(); |
| }, |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useSearchInfiniteQuery = ( |
| params?: ConversationListParams & { searchQuery?: string }, |
| config?: UseInfiniteQueryOptions<ConversationListResponse, unknown>, |
| ) => { |
| return useInfiniteQuery<ConversationListResponse, unknown>( |
| [QueryKeys.searchConversations, params], |
| ({ pageParam = '1' }) => |
| dataService.listConversationsByQuery({ ...params, pageNumber: pageParam }), |
| { |
| getNextPageParam: (lastPage) => { |
| const currentPageNumber = Number(lastPage.pageNumber); |
| const totalPages = Number(lastPage.pages); |
| return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined; |
| }, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useConversationsInfiniteQuery = ( |
| params?: ConversationListParams, |
| config?: UseInfiniteQueryOptions<ConversationListResponse, unknown>, |
| ) => { |
| return useInfiniteQuery<ConversationListResponse, unknown>( |
| params?.isArchived ? [QueryKeys.archivedConversations] : [QueryKeys.allConversations], |
| ({ pageParam = '' }) => |
| dataService.listConversations({ |
| ...params, |
| pageNumber: pageParam?.toString(), |
| isArchived: params?.isArchived || false, |
| }), |
| { |
| getNextPageParam: (lastPage) => { |
| const currentPageNumber = Number(lastPage.pageNumber); |
| const totalPages = Number(lastPage.pages); |
| |
| return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined; |
| }, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useSharedLinksInfiniteQuery = ( |
| params?: SharedLinkListParams, |
| config?: UseInfiniteQueryOptions<SharedLinksResponse, unknown>, |
| ) => { |
| return useInfiniteQuery<SharedLinksResponse, unknown>( |
| [QueryKeys.sharedLinks], |
| ({ pageParam = '' }) => |
| dataService.listSharedLinks({ |
| ...params, |
| pageNumber: pageParam?.toString(), |
| isPublic: params?.isPublic || true, |
| }), |
| { |
| getNextPageParam: (lastPage) => { |
| const currentPageNumber = Number(lastPage.pageNumber); |
| const totalPages = Number(lastPage.pages); |
| |
| return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined; |
| }, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| |
| |
| |
|
|
| |
| |
| |
| export const useAvailableToolsQuery = ( |
| endpoint: t.AssistantsEndpoint, |
| ): QueryObserverResult<TPlugin[]> => { |
| const queryClient = useQueryClient(); |
| const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]); |
| const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]); |
| const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide; |
| const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true; |
| const enabled = !!endpointsConfig?.[endpoint] && keyProvided; |
| const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]; |
| return useQuery<TPlugin[]>( |
| [QueryKeys.tools], |
| () => dataService.getAvailableTools(version, endpoint), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| enabled, |
| }, |
| ); |
| }; |
|
|
| |
| |
| |
| export const useListAssistantsQuery = <TData = AssistantListResponse>( |
| endpoint: t.AssistantsEndpoint, |
| params: Omit<AssistantListParams, 'endpoint'> = defaultOrderQuery, |
| config?: UseQueryOptions<AssistantListResponse, unknown, TData>, |
| ): QueryObserverResult<TData> => { |
| const queryClient = useQueryClient(); |
| const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]); |
| const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]); |
| const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide; |
| const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true; |
| const enabled = !!endpointsConfig?.[endpoint] && keyProvided; |
| const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]; |
| return useQuery<AssistantListResponse, unknown, TData>( |
| [QueryKeys.assistants, endpoint, params], |
| () => dataService.listAssistants({ ...params, endpoint }, version), |
| { |
| |
| |
| |
| |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled && enabled : enabled, |
| }, |
| ); |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| export const useGetAssistantByIdQuery = ( |
| endpoint: t.AssistantsEndpoint, |
| assistant_id: string, |
| config?: UseQueryOptions<Assistant>, |
| ): QueryObserverResult<Assistant> => { |
| const queryClient = useQueryClient(); |
| const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]); |
| const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]); |
| const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide; |
| const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true; |
| const enabled = !!endpointsConfig?.[endpoint] && keyProvided; |
| const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]; |
| return useQuery<Assistant>( |
| [QueryKeys.assistant, assistant_id], |
| () => |
| dataService.getAssistantById({ |
| endpoint, |
| assistant_id, |
| version, |
| }), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| |
| enabled: config?.enabled !== undefined ? config?.enabled && enabled : enabled, |
| }, |
| ); |
| }; |
|
|
| |
| |
| |
| export const useGetActionsQuery = <TData = Action[]>( |
| endpoint: t.AssistantsEndpoint, |
| config?: UseQueryOptions<Action[], unknown, TData>, |
| ): QueryObserverResult<TData> => { |
| const queryClient = useQueryClient(); |
| const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]); |
| const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]); |
| const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide; |
| const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true; |
| const enabled = !!endpointsConfig?.[endpoint] && keyProvided; |
| const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]; |
| return useQuery<Action[], unknown, TData>( |
| [QueryKeys.actions], |
| () => |
| dataService.getActions({ |
| endpoint, |
| version, |
| }), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled && enabled : enabled, |
| }, |
| ); |
| }; |
| |
| |
| |
| export const useGetAssistantDocsQuery = ( |
| endpoint: t.AssistantsEndpoint, |
| config?: UseQueryOptions<AssistantDocument[]>, |
| ): QueryObserverResult<AssistantDocument[], unknown> => { |
| const queryClient = useQueryClient(); |
| const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]); |
| const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]); |
| const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide; |
| const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true; |
| const enabled = !!endpointsConfig?.[endpoint] && keyProvided; |
| const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]; |
| return useQuery<AssistantDocument[]>( |
| [QueryKeys.assistantDocs], |
| () => |
| dataService.getAssistantDocs({ |
| endpoint, |
| version, |
| }), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled && enabled : enabled, |
| }, |
| ); |
| }; |
|
|
| export const useFileDownload = (userId?: string, file_id?: string): QueryObserverResult<string> => { |
| const queryClient = useQueryClient(); |
| return useQuery( |
| [QueryKeys.fileDownload, file_id], |
| async () => { |
| if (!userId || !file_id) { |
| console.warn('No user ID provided for file download'); |
| return; |
| } |
| const response = await dataService.getFileDownload(userId, file_id); |
| const blob = response.data; |
| const downloadURL = window.URL.createObjectURL(blob); |
| try { |
| const metadata: TFile | undefined = JSON.parse(response.headers['x-file-metadata']); |
| if (!metadata) { |
| console.warn('No metadata found for file download', response.headers); |
| return downloadURL; |
| } |
|
|
| addFileToCache(queryClient, metadata); |
| } catch (e) { |
| console.error('Error parsing file metadata, skipped updating file query cache', e); |
| } |
|
|
| return downloadURL; |
| }, |
| { |
| enabled: false, |
| retry: false, |
| }, |
| ); |
| }; |
|
|
| |
|
|
| |
| export const useVoicesQuery = (): UseQueryResult<t.VoiceResponse> => { |
| return useQuery([QueryKeys.voices], () => dataService.getVoices()); |
| }; |
|
|
| export const usePromptGroupsInfiniteQuery = ( |
| params?: t.TPromptGroupsWithFilterRequest, |
| config?: UseInfiniteQueryOptions<t.PromptGroupListResponse, unknown>, |
| ) => { |
| const { name, pageSize, category, ...rest } = params || {}; |
| return useInfiniteQuery<t.PromptGroupListResponse, unknown>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| ({ pageParam = '1' }) => |
| dataService.getPromptGroups({ |
| ...rest, |
| name, |
| category: category || '', |
| pageNumber: pageParam?.toString(), |
| pageSize: (pageSize || 10).toString(), |
| }), |
| { |
| getNextPageParam: (lastPage) => { |
| const currentPageNumber = Number(lastPage.pageNumber); |
| const totalPages = Number(lastPage.pages); |
| return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined; |
| }, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| ...config, |
| }, |
| ); |
| }; |
|
|
| export const useGetPromptGroup = ( |
| id: string, |
| config?: UseQueryOptions<t.TPromptGroup>, |
| ): QueryObserverResult<t.TPromptGroup> => { |
| return useQuery<t.TPromptGroup>( |
| [QueryKeys.promptGroup, id], |
| () => dataService.getPromptGroup(id), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled : true, |
| }, |
| ); |
| }; |
|
|
| export const useGetPrompts = ( |
| filter: t.TPromptsWithFilterRequest, |
| config?: UseQueryOptions<t.TPrompt[]>, |
| ): QueryObserverResult<t.TPrompt[]> => { |
| return useQuery<t.TPrompt[]>( |
| [QueryKeys.prompts, filter.groupId ?? ''], |
| () => dataService.getPrompts(filter), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled : true, |
| }, |
| ); |
| }; |
|
|
| export const useGetCategories = <TData = t.TGetCategoriesResponse>( |
| config?: UseQueryOptions<t.TGetCategoriesResponse, unknown, TData>, |
| ): QueryObserverResult<TData> => { |
| return useQuery<t.TGetCategoriesResponse, unknown, TData>( |
| [QueryKeys.categories], |
| () => dataService.getCategories(), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled : true, |
| }, |
| ); |
| }; |
|
|
| export const useGetRandomPrompts = ( |
| filter: t.TGetRandomPromptsRequest, |
| config?: UseQueryOptions<t.TGetRandomPromptsResponse>, |
| ): QueryObserverResult<t.TGetRandomPromptsResponse> => { |
| return useQuery<t.TGetRandomPromptsResponse>( |
| [QueryKeys.randomPrompts], |
| () => dataService.getRandomPrompts(filter), |
| { |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| ...config, |
| enabled: config?.enabled !== undefined ? config?.enabled : true, |
| }, |
| ); |
| }; |
|
|