mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 06:00:56 +02:00
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:
parent
2dd545eaa4
commit
b3aac97710
10 changed files with 34 additions and 15 deletions
1
.github/workflows/playwright.yml
vendored
1
.github/workflows/playwright.yml
vendored
|
@ -34,6 +34,7 @@ jobs:
|
||||||
DOMAIN_SERVER: ${{ secrets.DOMAIN_SERVER }}
|
DOMAIN_SERVER: ${{ secrets.DOMAIN_SERVER }}
|
||||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 # Skip downloading during npm install
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 # Skip downloading during npm install
|
||||||
PLAYWRIGHT_BROWSERS_PATH: 0 # Places binaries to node_modules/@playwright/test
|
PLAYWRIGHT_BROWSERS_PATH: 0 # Places binaries to node_modules/@playwright/test
|
||||||
|
TITLE_CONVO: false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
|
|
|
@ -17,12 +17,14 @@ import { cn } from '~/utils/';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
export default function NavLinks() {
|
export default function NavLinks() {
|
||||||
const balanceQuery = useGetUserBalance();
|
const { user, isAuthenticated } = useAuthContext();
|
||||||
const { data: startupConfig } = useGetStartupConfig();
|
const { data: startupConfig } = useGetStartupConfig();
|
||||||
|
const balanceQuery = useGetUserBalance({
|
||||||
|
enabled: !!isAuthenticated && startupConfig?.checkBalance,
|
||||||
|
});
|
||||||
const [showExports, setShowExports] = useState(false);
|
const [showExports, setShowExports] = useState(false);
|
||||||
const [showClearConvos, setShowClearConvos] = useState(false);
|
const [showClearConvos, setShowClearConvos] = useState(false);
|
||||||
const [showSettings, setShowSettings] = useState(false);
|
const [showSettings, setShowSettings] = useState(false);
|
||||||
const { user } = useAuthContext();
|
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
||||||
const conversation = useRecoilValue(store.conversation) ?? ({} as TConversation);
|
const conversation = useRecoilValue(store.conversation) ?? ({} as TConversation);
|
||||||
|
|
|
@ -13,6 +13,7 @@ export default function NewChat() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
data-testid="new-chat-button"
|
||||||
onClick={clickHandler}
|
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"
|
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"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useSetRecoilState, useResetRecoilState, useRecoilCallback, useRecoilValue } from 'recoil';
|
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 { buildDefaultConvo, getDefaultEndpoint } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
|
@ -17,8 +23,9 @@ const useConversation = () => {
|
||||||
conversation: TConversation,
|
conversation: TConversation,
|
||||||
messages: TMessagesAtom = null,
|
messages: TMessagesAtom = null,
|
||||||
preset: TPreset | null = 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;
|
const { endpoint = null } = conversation;
|
||||||
|
|
||||||
if (endpoint === null) {
|
if (endpoint === null) {
|
||||||
|
@ -45,7 +52,7 @@ const useConversation = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const newConversation = useCallback(
|
const newConversation = useCallback(
|
||||||
(template = {}, preset?: TPreset) => {
|
(template = {}, preset?: TPreset, modelsData?: TModelsConfig) => {
|
||||||
switchToConversation(
|
switchToConversation(
|
||||||
{
|
{
|
||||||
conversationId: 'new',
|
conversationId: 'new',
|
||||||
|
@ -57,6 +64,7 @@ const useConversation = () => {
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
preset,
|
preset,
|
||||||
|
modelsData,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[switchToConversation],
|
[switchToConversation],
|
||||||
|
|
|
@ -29,11 +29,13 @@ export default function useServerStream(submission: TSubmission | null) {
|
||||||
const setIsSubmitting = useSetRecoilState(store.isSubmitting);
|
const setIsSubmitting = useSetRecoilState(store.isSubmitting);
|
||||||
const setConversation = useSetRecoilState(store.conversation);
|
const setConversation = useSetRecoilState(store.conversation);
|
||||||
const resetLatestMessage = useResetRecoilState(store.latestMessage);
|
const resetLatestMessage = useResetRecoilState(store.latestMessage);
|
||||||
const { token } = useAuthContext();
|
const { token, isAuthenticated } = useAuthContext();
|
||||||
|
|
||||||
const { data: startupConfig } = useGetStartupConfig();
|
const { data: startupConfig } = useGetStartupConfig();
|
||||||
const { refreshConversations } = useConversations();
|
const { refreshConversations } = useConversations();
|
||||||
const balanceQuery = useGetUserBalance();
|
const balanceQuery = useGetUserBalance({
|
||||||
|
enabled: !!isAuthenticated && startupConfig?.checkBalance,
|
||||||
|
});
|
||||||
|
|
||||||
const messageHandler = (data: string, submission: TSubmission) => {
|
const messageHandler = (data: string, submission: TSubmission) => {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
com_ui_examples: 'Examples',
|
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_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_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?',
|
com_ui_example_http_in_js: 'How do I make an HTTP request in Javascript?',
|
||||||
|
|
|
@ -10,10 +10,11 @@ import {
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
|
|
||||||
import { Nav, MobileNav } from '~/components/Nav';
|
import { Nav, MobileNav } from '~/components/Nav';
|
||||||
import { useAuthContext, useServerStream } from '~/hooks';
|
import { useAuthContext, useServerStream, useConversation } from '~/hooks';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
|
const { newConversation } = useConversation();
|
||||||
const { user, isAuthenticated } = useAuthContext();
|
const { user, isAuthenticated } = useAuthContext();
|
||||||
const [navVisible, setNavVisible] = useState(() => {
|
const [navVisible, setNavVisible] = useState(() => {
|
||||||
const savedNavVisible = localStorage.getItem('navVisible');
|
const savedNavVisible = localStorage.getItem('navVisible');
|
||||||
|
@ -30,7 +31,7 @@ export default function Root() {
|
||||||
|
|
||||||
const searchEnabledQuery = useGetSearchEnabledQuery();
|
const searchEnabledQuery = useGetSearchEnabledQuery();
|
||||||
const endpointsQuery = useGetEndpointsQuery();
|
const endpointsQuery = useGetEndpointsQuery();
|
||||||
const modelsQuery = useGetModelsQuery();
|
const modelsQuery = useGetModelsQuery({ enabled: isAuthenticated });
|
||||||
const presetsQuery = useGetPresetsQuery({ enabled: !!user });
|
const presetsQuery = useGetPresetsQuery({ enabled: !!user });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -48,6 +49,7 @@ export default function Root() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (modelsQuery.data) {
|
if (modelsQuery.data) {
|
||||||
setModelsConfig(modelsQuery.data);
|
setModelsConfig(modelsQuery.data);
|
||||||
|
newConversation(modelsQuery.data);
|
||||||
} else if (modelsQuery.isError) {
|
} else if (modelsQuery.isError) {
|
||||||
console.error('Failed to get models', modelsQuery.error);
|
console.error('Failed to get models', modelsQuery.error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ test.describe('Messaging suite', () => {
|
||||||
expect(currentUrl).toBe(initialUrl);
|
expect(currentUrl).toBe(initialUrl);
|
||||||
|
|
||||||
//cleanup the conversation
|
//cleanup the conversation
|
||||||
await page.getByText('New chat', { exact: true }).click();
|
await page.getByTestId('new-chat-button').click();
|
||||||
expect(page.url()).toBe(initialUrl);
|
expect(page.url()).toBe(initialUrl);
|
||||||
|
|
||||||
// Click on the first conversation
|
// Click on the first conversation
|
||||||
|
@ -166,7 +166,7 @@ test.describe('Messaging suite', () => {
|
||||||
const currentUrl = page.url();
|
const currentUrl = page.url();
|
||||||
const conversationId = currentUrl.split(basePath).pop() ?? '';
|
const conversationId = currentUrl.split(basePath).pop() ?? '';
|
||||||
expect(isUUID(conversationId)).toBeTruthy();
|
expect(isUUID(conversationId)).toBeTruthy();
|
||||||
await page.getByText('New chat', { exact: true }).click();
|
await page.getByTestId('new-chat-button').click();
|
||||||
expect(page.url()).toBe(initialUrl);
|
expect(page.url()).toBe(initialUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@ export const getAIEndpoints = () => {
|
||||||
return request.get(endpoints.aiEndpoints());
|
return request.get(endpoints.aiEndpoints());
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getModels = () => {
|
export const getModels = async (): Promise<t.TModelsConfig> => {
|
||||||
return request.get(endpoints.models());
|
return request.get(endpoints.models());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -238,11 +238,14 @@ export const useGetEndpointsQuery = (): QueryObserverResult<t.TEndpointsConfig>
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetModelsQuery = (): QueryObserverResult<t.TModelsConfig> => {
|
export const useGetModelsQuery = (
|
||||||
return useQuery([QueryKeys.models], () => dataService.getModels(), {
|
config?: UseQueryOptions<t.TModelsConfig>,
|
||||||
|
): QueryObserverResult<t.TModelsConfig> => {
|
||||||
|
return useQuery<t.TModelsConfig>([QueryKeys.models], () => dataService.getModels(), {
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue