LibreChat/client/src/data-provider/queries.ts

132 lines
4.1 KiB
TypeScript
Raw Normal View History

import { QueryKeys, dataService } from 'librechat-data-provider';
♾️ style: Infinite Scroll Nav and Sort Convos by Date/Usage (#1708) * Style: Infinite Scroll and Group convos by date * Style: Infinite Scroll and Group convos by date- Redesign NavBar * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Clean code * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Including OpenRouter and Mistral icon * refactor(Conversations): cleanup use of utility functions and typing * refactor(Nav/NewChat): use localStorage `lastConversationSetup` to determine the endpoint to use, as well as icons -> JSX components, remove use of `endpointSelected` * refactor: remove use of `isFirstToday` * refactor(Nav): remove use of `endpointSelected`, consolidate scrolling logic to its own hook `useNavScrolling`, remove use of recoil `conversation` * refactor: Add spinner to bottom of list, throttle fetching, move query hooks to client workspace * chore: sort by `updatedAt` field * refactor: optimize conversation infinite query, use optimistic updates, add conversation helpers for managing pagination, remove unnecessary operations * feat: gen_title route for generating the title for the conversation * style(Convo): change hover bg-color * refactor: memoize groupedConversations and return as array of tuples, correctly update convos pre/post message stream, only call genTitle if conversation is new, make `addConversation` dynamically either add/update depending if convo exists in pages already, reorganize type definitions * style: rename Header NewChat Button -> HeaderNewChat, add NewChatIcon, closely match main Nav New Chat button to ChatGPT * style(NewChat): add hover bg color * style: cleanup comments, match ChatGPT nav styling, redesign search bar, make part of new chat sticky header, move Nav under same parent as outlet/mobilenav, remove legacy code, search only if searchQuery is not empty * feat: add tests for conversation helpers and ensure no duplicate conversations are ever grouped * style: hover bg-color * feat: alt-click on convo item to open conversation in new tab * chore: send error message when `gen_title` fails --------- Co-authored-by: Walber Cardoso <walbercardoso@gmail.com>
2024-02-03 20:25:35 -05:00
import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
import type {
UseInfiniteQueryOptions,
QueryObserverResult,
UseQueryOptions,
} from '@tanstack/react-query';
import type t from 'librechat-data-provider';
import type {
TPreset,
TFile,
ConversationListResponse,
ConversationListParams,
} from 'librechat-data-provider';
import { findPageForConversation } from '~/utils';
🚀 Feat: Streamline File Strategies & GPT-4-Vision Settings (#1535) * chore: fix `endpoint` typescript issues and typo in console info message * feat(api): files GET endpoint and save only file_id references to messages * refactor(client): `useGetFiles` query hook, update file types, optimistic update of filesQuery on file upload * refactor(buildTree): update to use params object and accept fileMap * feat: map files to messages; refactor(ChatView): messages only available after files are fetched * fix: fetch files only when authenticated * feat(api): AppService - rename app.locals.configs to app.locals.paths - load custom config use fileStrategy from yaml config in app.locals * refactor: separate Firebase and Local strategies, call based on config * refactor: modularize file strategies and employ with use of DALL-E * refactor(librechat.yaml): add fileStrategy field * feat: add source to MongoFile schema, as well as BatchFile, and ExtendedFile types * feat: employ file strategies for upload/delete files * refactor(deleteFirebaseFile): add user id validation for firebase file deletion * chore(deleteFirebaseFile): update jsdocs * feat: employ strategies for vision requests * fix(client): handle messages with deleted files * fix(client): ensure `filesToDelete` always saves/sends `file.source` * feat(openAI): configurable `resendImages` and `imageDetail` * refactor(getTokenCountForMessage): recursive process only when array of Objects and only their values (not keys) aside from `image_url` types * feat(OpenAIClient): calculateImageTokenCost * chore: remove comment * refactor(uploadAvatar): employ fileStrategy for avatars, from social logins or user upload * docs: update docs on how to configure fileStrategy * fix(ci): mock winston and winston related modules, update DALLE3.spec.js with changes made * refactor(redis): change terminal message to reflect current development state * fix(DALL-E-2): pass fileStrategy to dall-e
2024-01-11 11:37:54 -05:00
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 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,
},
);
};
♾️ style: Infinite Scroll Nav and Sort Convos by Date/Usage (#1708) * Style: Infinite Scroll and Group convos by date * Style: Infinite Scroll and Group convos by date- Redesign NavBar * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Clean code * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Style: Infinite Scroll and Group convos by date- Redesign NavBar - Redesign NewChat Component * Including OpenRouter and Mistral icon * refactor(Conversations): cleanup use of utility functions and typing * refactor(Nav/NewChat): use localStorage `lastConversationSetup` to determine the endpoint to use, as well as icons -> JSX components, remove use of `endpointSelected` * refactor: remove use of `isFirstToday` * refactor(Nav): remove use of `endpointSelected`, consolidate scrolling logic to its own hook `useNavScrolling`, remove use of recoil `conversation` * refactor: Add spinner to bottom of list, throttle fetching, move query hooks to client workspace * chore: sort by `updatedAt` field * refactor: optimize conversation infinite query, use optimistic updates, add conversation helpers for managing pagination, remove unnecessary operations * feat: gen_title route for generating the title for the conversation * style(Convo): change hover bg-color * refactor: memoize groupedConversations and return as array of tuples, correctly update convos pre/post message stream, only call genTitle if conversation is new, make `addConversation` dynamically either add/update depending if convo exists in pages already, reorganize type definitions * style: rename Header NewChat Button -> HeaderNewChat, add NewChatIcon, closely match main Nav New Chat button to ChatGPT * style(NewChat): add hover bg color * style: cleanup comments, match ChatGPT nav styling, redesign search bar, make part of new chat sticky header, move Nav under same parent as outlet/mobilenav, remove legacy code, search only if searchQuery is not empty * feat: add tests for conversation helpers and ensure no duplicate conversations are ever grouped * style: hover bg-color * feat: alt-click on convo item to open conversation in new tab * chore: send error message when `gen_title` fails --------- Co-authored-by: Walber Cardoso <walbercardoso@gmail.com>
2024-02-03 20:25:35 -05:00
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, convIndex } = findPageForConversation(convosQuery, { conversationId: id });
if (pageIndex > -1 && convIndex > -1) {
return convosQuery.pages[pageIndex].conversations[convIndex];
}
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], // Include the searchQuery in the query key
({ 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>(
[QueryKeys.allConversations],
({ pageParam = '' }) =>
dataService.listConversations({ ...params, pageNumber: pageParam?.toString() }),
{
getNextPageParam: (lastPage) => {
const currentPageNumber = Number(lastPage.pageNumber);
const totalPages = Number(lastPage.pages); // Convert totalPages to a number
// If the current page number is less than total pages, return the next page number
return currentPageNumber < totalPages ? currentPageNumber + 1 : undefined;
},
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
...config,
},
);
};