fix(balance/models): request only when authenticated, modelsQuery "optimistic" update (#1031)

* fix(balanceQuery/modelsQuery): request only when authenticated

* style: match new chat capitalization to official

* fix(modelsQuery): update selected model optimistically

* ci: update e2e changes, disable title in ci env

* fix(ci): get new chat button by data-testid and not text
This commit is contained in:
Danny Avila 2023-10-09 15:10:23 -04:00 committed by GitHub
parent 2dd545eaa4
commit b3aac97710
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 34 additions and 15 deletions

View file

@ -34,6 +34,7 @@ jobs:
DOMAIN_SERVER: ${{ secrets.DOMAIN_SERVER }}
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 # Skip downloading during npm install
PLAYWRIGHT_BROWSERS_PATH: 0 # Places binaries to node_modules/@playwright/test
TITLE_CONVO: false
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3

View file

@ -17,12 +17,14 @@ import { cn } from '~/utils/';
import store from '~/store';
export default function NavLinks() {
const balanceQuery = useGetUserBalance();
const { user, isAuthenticated } = useAuthContext();
const { data: startupConfig } = useGetStartupConfig();
const balanceQuery = useGetUserBalance({
enabled: !!isAuthenticated && startupConfig?.checkBalance,
});
const [showExports, setShowExports] = useState(false);
const [showClearConvos, setShowClearConvos] = useState(false);
const [showSettings, setShowSettings] = useState(false);
const { user } = useAuthContext();
const localize = useLocalize();
const conversation = useRecoilValue(store.conversation) ?? ({} as TConversation);

View file

@ -13,6 +13,7 @@ export default function NewChat() {
return (
<a
data-testid="new-chat-button"
onClick={clickHandler}
className="flex h-11 flex-shrink-0 flex-grow cursor-pointer items-center gap-3 rounded-md border border-white/20 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10"
>

View file

@ -1,6 +1,12 @@
import { useCallback } from 'react';
import { useSetRecoilState, useResetRecoilState, useRecoilCallback, useRecoilValue } from 'recoil';
import { TConversation, TMessagesAtom, TSubmission, TPreset } from 'librechat-data-provider';
import type {
TConversation,
TMessagesAtom,
TSubmission,
TPreset,
TModelsConfig,
} from 'librechat-data-provider';
import { buildDefaultConvo, getDefaultEndpoint } from '~/utils';
import store from '~/store';
@ -17,8 +23,9 @@ const useConversation = () => {
conversation: TConversation,
messages: TMessagesAtom = null,
preset: TPreset | null = null,
modelsData?: TModelsConfig,
) => {
const modelsConfig = snapshot.getLoadable(store.modelsConfig).contents;
const modelsConfig = modelsData ?? snapshot.getLoadable(store.modelsConfig).contents;
const { endpoint = null } = conversation;
if (endpoint === null) {
@ -45,7 +52,7 @@ const useConversation = () => {
);
const newConversation = useCallback(
(template = {}, preset?: TPreset) => {
(template = {}, preset?: TPreset, modelsData?: TModelsConfig) => {
switchToConversation(
{
conversationId: 'new',
@ -57,6 +64,7 @@ const useConversation = () => {
},
[],
preset,
modelsData,
);
},
[switchToConversation],

View file

@ -29,11 +29,13 @@ export default function useServerStream(submission: TSubmission | null) {
const setIsSubmitting = useSetRecoilState(store.isSubmitting);
const setConversation = useSetRecoilState(store.conversation);
const resetLatestMessage = useResetRecoilState(store.latestMessage);
const { token } = useAuthContext();
const { token, isAuthenticated } = useAuthContext();
const { data: startupConfig } = useGetStartupConfig();
const { refreshConversations } = useConversations();
const balanceQuery = useGetUserBalance();
const balanceQuery = useGetUserBalance({
enabled: !!isAuthenticated && startupConfig?.checkBalance,
});
const messageHandler = (data: string, submission: TSubmission) => {
const {

View file

@ -2,7 +2,7 @@
export default {
com_ui_examples: 'Examples',
com_ui_new_chat: 'New chat',
com_ui_new_chat: 'New Chat',
com_ui_example_quantum_computing: 'Explain quantum computing in simple terms',
com_ui_example_10_year_old_b_day: 'Got any creative ideas for a 10 year old\'s birthday?',
com_ui_example_http_in_js: 'How do I make an HTTP request in Javascript?',

View file

@ -10,10 +10,11 @@ import {
} from 'librechat-data-provider';
import { Nav, MobileNav } from '~/components/Nav';
import { useAuthContext, useServerStream } from '~/hooks';
import { useAuthContext, useServerStream, useConversation } from '~/hooks';
import store from '~/store';
export default function Root() {
const { newConversation } = useConversation();
const { user, isAuthenticated } = useAuthContext();
const [navVisible, setNavVisible] = useState(() => {
const savedNavVisible = localStorage.getItem('navVisible');
@ -30,7 +31,7 @@ export default function Root() {
const searchEnabledQuery = useGetSearchEnabledQuery();
const endpointsQuery = useGetEndpointsQuery();
const modelsQuery = useGetModelsQuery();
const modelsQuery = useGetModelsQuery({ enabled: isAuthenticated });
const presetsQuery = useGetPresetsQuery({ enabled: !!user });
useEffect(() => {
@ -48,6 +49,7 @@ export default function Root() {
useEffect(() => {
if (modelsQuery.data) {
setModelsConfig(modelsQuery.data);
newConversation(modelsQuery.data);
} else if (modelsQuery.isError) {
console.error('Failed to get models', modelsQuery.error);
}

View file

@ -86,7 +86,7 @@ test.describe('Messaging suite', () => {
expect(currentUrl).toBe(initialUrl);
//cleanup the conversation
await page.getByText('New chat', { exact: true }).click();
await page.getByTestId('new-chat-button').click();
expect(page.url()).toBe(initialUrl);
// Click on the first conversation
@ -166,7 +166,7 @@ test.describe('Messaging suite', () => {
const currentUrl = page.url();
const conversationId = currentUrl.split(basePath).pop() ?? '';
expect(isUUID(conversationId)).toBeTruthy();
await page.getByText('New chat', { exact: true }).click();
await page.getByTestId('new-chat-button').click();
expect(page.url()).toBe(initialUrl);
});
});

View file

@ -105,7 +105,7 @@ export const getAIEndpoints = () => {
return request.get(endpoints.aiEndpoints());
};
export const getModels = () => {
export const getModels = async (): Promise<t.TModelsConfig> => {
return request.get(endpoints.models());
};

View file

@ -238,11 +238,14 @@ export const useGetEndpointsQuery = (): QueryObserverResult<t.TEndpointsConfig>
});
};
export const useGetModelsQuery = (): QueryObserverResult<t.TModelsConfig> => {
return useQuery([QueryKeys.models], () => dataService.getModels(), {
export const useGetModelsQuery = (
config?: UseQueryOptions<t.TModelsConfig>,
): QueryObserverResult<t.TModelsConfig> => {
return useQuery<t.TModelsConfig>([QueryKeys.models], () => dataService.getModels(), {
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
...config,
});
};