mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
🛂 feat: OpenID Logout Redirect to end_session_endpoint (#5626)
* WIP: end session endpoint * refactor: move useGetBannerQuery outside of package * refactor: add queriesEnabled and move useGetEndpointsConfigQuery to data-provider (local) * refactor: move useGetEndpointsQuery import to data-provider * refactor: relocate useGetEndpointsQuery import to improve module organization * refactor: move `useGetStartupConfig` from package to `~/data-provider` * refactor: move useGetUserBalance to data-provider and update imports * refactor: update query enabled conditions to include config check * refactor: remove unused useConfigOverride import from useAppStartup * refactor: integrate queriesEnabled state into file and search queries and move useGetSearchEnabledQuery to data-provider (local) * refactor: move useGetUserQuery to data-provider and update imports * refactor: enhance loginUser mutation with success and error handling as pass in options to hook * refactor: update enabled condition in queries to handle undefined config * refactor: enhance authentication mutations with queriesEnabled state management * refactor: improve conditional rendering for error messages and feature flags in Login component * refactor: remove unused queriesEnabled state from AuthContextProvider * refactor: implement queriesEnabled state management in LoginLayout with timeout handling * refactor: add conditional check for end session endpoint in OpenID strategy * ci: fix tests after changes * refactor: remove endSessionEndpoint from user schema and update logoutController to use OpenID issuer's end_session_endpoint * refactor: update logoutController to use end_session_endpoint from issuer metadata
This commit is contained in:
parent
d93f5c9061
commit
45dd2b262f
73 changed files with 385 additions and 270 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
const cookies = require('cookie');
|
const cookies = require('cookie');
|
||||||
|
const { Issuer } = require('openid-client');
|
||||||
const { logoutUser } = require('~/server/services/AuthService');
|
const { logoutUser } = require('~/server/services/AuthService');
|
||||||
|
const { isEnabled } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
|
|
||||||
const logoutController = async (req, res) => {
|
const logoutController = async (req, res) => {
|
||||||
|
|
@ -8,7 +10,23 @@ const logoutController = async (req, res) => {
|
||||||
const logout = await logoutUser(req, refreshToken);
|
const logout = await logoutUser(req, refreshToken);
|
||||||
const { status, message } = logout;
|
const { status, message } = logout;
|
||||||
res.clearCookie('refreshToken');
|
res.clearCookie('refreshToken');
|
||||||
return res.status(status).send({ message });
|
const response = { message };
|
||||||
|
if (
|
||||||
|
req.user.openidId != null &&
|
||||||
|
isEnabled(process.env.OPENID_USE_END_SESSION_ENDPOINT) &&
|
||||||
|
process.env.OPENID_ISSUER
|
||||||
|
) {
|
||||||
|
const issuer = await Issuer.discover(process.env.OPENID_ISSUER);
|
||||||
|
const redirect = issuer.metadata.end_session_endpoint;
|
||||||
|
if (!redirect) {
|
||||||
|
logger.warn(
|
||||||
|
'[logoutController] end_session_endpoint not found in OpenID issuer metadata. Please verify that the issuer is correct.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
response.redirect = redirect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.status(status).send(response);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('[logoutController]', err);
|
logger.error('[logoutController]', err);
|
||||||
return res.status(500).json({ message: err.message });
|
return res.status(500).json({ message: err.message });
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,8 @@ async function setupOpenId() {
|
||||||
redirect_uris: [process.env.DOMAIN_SERVER + process.env.OPENID_CALLBACK_URL],
|
redirect_uris: [process.env.DOMAIN_SERVER + process.env.OPENID_CALLBACK_URL],
|
||||||
};
|
};
|
||||||
if (isEnabled(process.env.OPENID_SET_FIRST_SUPPORTED_ALGORITHM)) {
|
if (isEnabled(process.env.OPENID_SET_FIRST_SUPPORTED_ALGORITHM)) {
|
||||||
clientMetadata.id_token_signed_response_alg = issuer.id_token_signing_alg_values_supported?.[0] || 'RS256';
|
clientMetadata.id_token_signed_response_alg =
|
||||||
|
issuer.id_token_signing_alg_values_supported?.[0] || 'RS256';
|
||||||
}
|
}
|
||||||
const client = new issuer.Client(clientMetadata);
|
const client = new issuer.Client(clientMetadata);
|
||||||
const requiredRole = process.env.OPENID_REQUIRED_ROLE;
|
const requiredRole = process.env.OPENID_REQUIRED_ROLE;
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,7 @@ export type TAuthConfig = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IconProps = Pick<t.TMessage, 'isCreatedByUser' | 'model'> &
|
export type IconProps = Pick<t.TMessage, 'isCreatedByUser' | 'model'> &
|
||||||
Pick<t.TConversation, 'chatGptLabel' | 'modelLabel' | 'jailbreak'> & {
|
Pick<t.TConversation, 'chatGptLabel' | 'modelLabel'> & {
|
||||||
size?: number;
|
size?: number;
|
||||||
button?: boolean;
|
button?: boolean;
|
||||||
iconURL?: string;
|
iconURL?: string;
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ function Login() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{error && <ErrorMessage>{localize(getLoginError(error))}</ErrorMessage>}
|
{error != null && <ErrorMessage>{localize(getLoginError(error))}</ErrorMessage>}
|
||||||
{startupConfig?.emailLoginEnabled && (
|
{startupConfig?.emailLoginEnabled === true && (
|
||||||
<LoginForm
|
<LoginForm
|
||||||
onSubmit={login}
|
onSubmit={login}
|
||||||
startupConfig={startupConfig}
|
startupConfig={startupConfig}
|
||||||
|
|
@ -22,7 +22,7 @@ function Login() {
|
||||||
setError={setError}
|
setError={setError}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{startupConfig?.registrationEnabled && (
|
{startupConfig?.registrationEnabled === true && (
|
||||||
<p className="my-4 text-center text-sm font-light text-gray-700 dark:text-white">
|
<p className="my-4 text-center text-sm font-light text-gray-700 dark:text-white">
|
||||||
{' '}
|
{' '}
|
||||||
{localize('com_auth_no_account')}{' '}
|
{localize('com_auth_no_account')}{' '}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TLoginUser, TStartupConfig } from 'librechat-data-provider';
|
import type { TLoginUser, TStartupConfig } from 'librechat-data-provider';
|
||||||
import type { TAuthContext } from '~/common';
|
import type { TAuthContext } from '~/common';
|
||||||
import { useResendVerificationEmail } from '~/data-provider';
|
import { useResendVerificationEmail, useGetStartupConfig } from '~/data-provider';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
type TLoginFormProps = {
|
type TLoginFormProps = {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import reactRouter from 'react-router-dom';
|
import reactRouter from 'react-router-dom';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { getByTestId, render, waitFor } from 'test/layout-test-utils';
|
import { getByTestId, render, waitFor } from 'test/layout-test-utils';
|
||||||
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
|
||||||
import type { TStartupConfig } from 'librechat-data-provider';
|
import type { TStartupConfig } from 'librechat-data-provider';
|
||||||
import * as authDataProvider from '~/data-provider/Auth/mutations';
|
import * as endpointQueries from '~/data-provider/Endpoints/queries';
|
||||||
|
import * as miscDataProvider from '~/data-provider/Misc/queries';
|
||||||
|
import * as authMutations from '~/data-provider/Auth/mutations';
|
||||||
|
import * as authQueries from '~/data-provider/Auth/queries';
|
||||||
import AuthLayout from '~/components/Auth/AuthLayout';
|
import AuthLayout from '~/components/Auth/AuthLayout';
|
||||||
import Login from '~/components/Auth/Login';
|
import Login from '~/components/Auth/Login';
|
||||||
|
|
||||||
|
|
@ -62,23 +64,23 @@ const setup = ({
|
||||||
},
|
},
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
const mockUseLoginUser = jest
|
const mockUseLoginUser = jest
|
||||||
.spyOn(authDataProvider, 'useLoginUserMutation')
|
.spyOn(authMutations, 'useLoginUserMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useLoginUserReturnValue);
|
.mockReturnValue(useLoginUserReturnValue);
|
||||||
const mockUseGetUserQuery = jest
|
const mockUseGetUserQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetUserQuery')
|
.spyOn(authQueries, 'useGetUserQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetUserQueryReturnValue);
|
.mockReturnValue(useGetUserQueryReturnValue);
|
||||||
const mockUseGetStartupConfig = jest
|
const mockUseGetStartupConfig = jest
|
||||||
.spyOn(mockDataProvider, 'useGetStartupConfig')
|
.spyOn(endpointQueries, 'useGetStartupConfig')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetStartupConfigReturnValue);
|
.mockReturnValue(useGetStartupConfigReturnValue);
|
||||||
const mockUseRefreshTokenMutation = jest
|
const mockUseRefreshTokenMutation = jest
|
||||||
.spyOn(mockDataProvider, 'useRefreshTokenMutation')
|
.spyOn(authMutations, 'useRefreshTokenMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
||||||
const mockUseGetBannerQuery = jest
|
const mockUseGetBannerQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetBannerQuery')
|
.spyOn(miscDataProvider, 'useGetBannerQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetBannerQueryReturnValue);
|
.mockReturnValue(useGetBannerQueryReturnValue);
|
||||||
const mockUseOutletContext = jest.spyOn(reactRouter, 'useOutletContext').mockReturnValue({
|
const mockUseOutletContext = jest.spyOn(reactRouter, 'useOutletContext').mockReturnValue({
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import { render, getByTestId } from 'test/layout-test-utils';
|
import { render, getByTestId } from 'test/layout-test-utils';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
|
||||||
import type { TStartupConfig } from 'librechat-data-provider';
|
import type { TStartupConfig } from 'librechat-data-provider';
|
||||||
import * as authDataProvider from '~/data-provider/Auth/mutations';
|
import * as endpointQueries from '~/data-provider/Endpoints/queries';
|
||||||
|
import * as miscDataProvider from '~/data-provider/Misc/queries';
|
||||||
|
import * as authMutations from '~/data-provider/Auth/mutations';
|
||||||
|
import * as authQueries from '~/data-provider/Auth/queries';
|
||||||
import Login from '../LoginForm';
|
import Login from '../LoginForm';
|
||||||
|
|
||||||
jest.mock('librechat-data-provider/react-query');
|
jest.mock('librechat-data-provider/react-query');
|
||||||
|
|
@ -67,23 +69,23 @@ const setup = ({
|
||||||
},
|
},
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
const mockUseLoginUser = jest
|
const mockUseLoginUser = jest
|
||||||
.spyOn(authDataProvider, 'useLoginUserMutation')
|
.spyOn(authMutations, 'useLoginUserMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useLoginUserReturnValue);
|
.mockReturnValue(useLoginUserReturnValue);
|
||||||
const mockUseGetUserQuery = jest
|
const mockUseGetUserQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetUserQuery')
|
.spyOn(authQueries, 'useGetUserQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetUserQueryReturnValue);
|
.mockReturnValue(useGetUserQueryReturnValue);
|
||||||
const mockUseGetStartupConfig = jest
|
const mockUseGetStartupConfig = jest
|
||||||
.spyOn(mockDataProvider, 'useGetStartupConfig')
|
.spyOn(endpointQueries, 'useGetStartupConfig')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetStartupConfigReturnValue);
|
.mockReturnValue(useGetStartupConfigReturnValue);
|
||||||
const mockUseRefreshTokenMutation = jest
|
const mockUseRefreshTokenMutation = jest
|
||||||
.spyOn(mockDataProvider, 'useRefreshTokenMutation')
|
.spyOn(authMutations, 'useRefreshTokenMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
||||||
const mockUseGetBannerQuery = jest
|
const mockUseGetBannerQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetBannerQuery')
|
.spyOn(miscDataProvider, 'useGetBannerQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetBannerQueryReturnValue);
|
.mockReturnValue(useGetBannerQueryReturnValue);
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import userEvent from '@testing-library/user-event';
|
||||||
import { render, waitFor, screen } from 'test/layout-test-utils';
|
import { render, waitFor, screen } from 'test/layout-test-utils';
|
||||||
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
||||||
import type { TStartupConfig } from 'librechat-data-provider';
|
import type { TStartupConfig } from 'librechat-data-provider';
|
||||||
|
import * as miscDataProvider from '~/data-provider/Misc/queries';
|
||||||
|
import * as endpointQueries from '~/data-provider/Endpoints/queries';
|
||||||
|
import * as authMutations from '~/data-provider/Auth/mutations';
|
||||||
|
import * as authQueries from '~/data-provider/Auth/queries';
|
||||||
import Registration from '~/components/Auth/Registration';
|
import Registration from '~/components/Auth/Registration';
|
||||||
import AuthLayout from '~/components/Auth/AuthLayout';
|
import AuthLayout from '~/components/Auth/AuthLayout';
|
||||||
|
|
||||||
|
|
@ -62,22 +66,22 @@ const setup = ({
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useRegisterUserMutationReturnValue);
|
.mockReturnValue(useRegisterUserMutationReturnValue);
|
||||||
const mockUseGetUserQuery = jest
|
const mockUseGetUserQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetUserQuery')
|
.spyOn(authQueries, 'useGetUserQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetUserQueryReturnValue);
|
.mockReturnValue(useGetUserQueryReturnValue);
|
||||||
const mockUseGetStartupConfig = jest
|
const mockUseGetStartupConfig = jest
|
||||||
.spyOn(mockDataProvider, 'useGetStartupConfig')
|
.spyOn(endpointQueries, 'useGetStartupConfig')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetStartupConfigReturnValue);
|
.mockReturnValue(useGetStartupConfigReturnValue);
|
||||||
const mockUseRefreshTokenMutation = jest
|
const mockUseRefreshTokenMutation = jest
|
||||||
.spyOn(mockDataProvider, 'useRefreshTokenMutation')
|
.spyOn(authMutations, 'useRefreshTokenMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
||||||
const mockUseOutletContext = jest.spyOn(reactRouter, 'useOutletContext').mockReturnValue({
|
const mockUseOutletContext = jest.spyOn(reactRouter, 'useOutletContext').mockReturnValue({
|
||||||
startupConfig: useGetStartupConfigReturnValue.data,
|
startupConfig: useGetStartupConfigReturnValue.data,
|
||||||
});
|
});
|
||||||
const mockUseGetBannerQuery = jest
|
const mockUseGetBannerQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetBannerQuery')
|
.spyOn(miscDataProvider, 'useGetBannerQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetBannerQueryReturnValue);
|
.mockReturnValue(useGetBannerQueryReturnValue);
|
||||||
const renderResult = render(
|
const renderResult = render(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
import { XIcon } from 'lucide-react';
|
import { XIcon } from 'lucide-react';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import { useGetBannerQuery } from 'librechat-data-provider/react-query';
|
import { useGetBannerQuery } from '~/data-provider';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
|
|
||||||
export const Banner = ({ onHeightChange }: { onHeightChange?: (height: number) => void }) => {
|
export const Banner = ({ onHeightChange }: { onHeightChange?: (height: number) => void }) => {
|
||||||
const { data: banner } = useGetBannerQuery();
|
const { data: banner } = useGetBannerQuery();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import TagManager from 'react-gtm-module';
|
import TagManager from 'react-gtm-module';
|
||||||
import { Constants } from 'librechat-data-provider';
|
import { Constants } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
import { useGetStartupConfig } from '~/data-provider';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
export default function Footer({ className }: { className?: string }) {
|
export default function Footer({ className }: { className?: string }) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useOutletContext } from 'react-router-dom';
|
import { useOutletContext } from 'react-router-dom';
|
||||||
import { getConfigDefaults, PermissionTypes, Permissions } from 'librechat-data-provider';
|
import { getConfigDefaults, PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { ContextType } from '~/common';
|
import type { ContextType } from '~/common';
|
||||||
import { EndpointsMenu, ModelSpecsMenu, PresetsMenu, HeaderNewChat } from './Menus';
|
import { EndpointsMenu, ModelSpecsMenu, PresetsMenu, HeaderNewChat } from './Menus';
|
||||||
|
import { useGetStartupConfig } from '~/data-provider';
|
||||||
import ExportAndShareMenu from './ExportAndShareMenu';
|
import ExportAndShareMenu from './ExportAndShareMenu';
|
||||||
import { useMediaQuery, useHasAccess } from '~/hooks';
|
import { useMediaQuery, useHasAccess } from '~/hooks';
|
||||||
import HeaderOptions from './Input/HeaderOptions';
|
import HeaderOptions from './Input/HeaderOptions';
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TConversation, TEndpointOption, TPreset } from 'librechat-data-provider';
|
import type { TConversation, TEndpointOption, TPreset } from 'librechat-data-provider';
|
||||||
import type { SetterOrUpdater } from 'recoil';
|
import type { SetterOrUpdater } from 'recoil';
|
||||||
import useGetSender from '~/hooks/Conversations/useGetSender';
|
import useGetSender from '~/hooks/Conversations/useGetSender';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { EndpointIcon } from '~/components/Endpoints';
|
import { EndpointIcon } from '~/components/Endpoints';
|
||||||
import { getPresetTitle } from '~/utils';
|
import { getPresetTitle } from '~/utils';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import * as Ariakit from '@ariakit/react';
|
||||||
import React, { useRef, useState, useMemo } from 'react';
|
import React, { useRef, useState, useMemo } from 'react';
|
||||||
import { FileSearch, ImageUpIcon, TerminalSquareIcon } from 'lucide-react';
|
import { FileSearch, ImageUpIcon, TerminalSquareIcon } from 'lucide-react';
|
||||||
import { EToolResources, EModelEndpoint } from 'librechat-data-provider';
|
import { EToolResources, EModelEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { FileUpload, TooltipAnchor, DropdownPopup } from '~/components/ui';
|
import { FileUpload, TooltipAnchor, DropdownPopup } from '~/components/ui';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { AttachmentIcon } from '~/components/svg';
|
import { AttachmentIcon } from '~/components/svg';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { EModelEndpoint, EToolResources } from 'librechat-data-provider';
|
import { EModelEndpoint, EToolResources } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { FileSearch, ImageUpIcon, TerminalSquareIcon } from 'lucide-react';
|
import { FileSearch, ImageUpIcon, TerminalSquareIcon } from 'lucide-react';
|
||||||
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
import { OGDialog } from '~/components/ui';
|
import { OGDialog } from '~/components/ui';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ import { useRecoilState } from 'recoil';
|
||||||
import { Settings2 } from 'lucide-react';
|
import { Settings2 } from 'lucide-react';
|
||||||
import { Root, Anchor } from '@radix-ui/react-popover';
|
import { Root, Anchor } from '@radix-ui/react-popover';
|
||||||
import { useState, useEffect, useMemo } from 'react';
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { tConvoUpdateSchema, EModelEndpoint, isParamEndpoint } from 'librechat-data-provider';
|
import { tConvoUpdateSchema, EModelEndpoint, isParamEndpoint } from 'librechat-data-provider';
|
||||||
import type { TPreset, TInterfaceConfig } from 'librechat-data-provider';
|
import type { TPreset, TInterfaceConfig } from 'librechat-data-provider';
|
||||||
import { EndpointSettings, SaveAsPresetDialog, AlternativeSettings } from '~/components/Endpoints';
|
import { EndpointSettings, SaveAsPresetDialog, AlternativeSettings } from '~/components/Endpoints';
|
||||||
import { PluginStoreDialog, TooltipAnchor } from '~/components';
|
import { PluginStoreDialog, TooltipAnchor } from '~/components';
|
||||||
import { ModelSelect } from '~/components/Input/ModelSelect';
|
import { ModelSelect } from '~/components/Input/ModelSelect';
|
||||||
import { useSetIndexOptions, useLocalize } from '~/hooks';
|
import { useSetIndexOptions, useLocalize } from '~/hooks';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import OptionsPopover from './OptionsPopover';
|
import OptionsPopover from './OptionsPopover';
|
||||||
import PopoverButtons from './PopoverButtons';
|
import PopoverButtons from './PopoverButtons';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { EModelEndpoint, Constants } from 'librechat-data-provider';
|
import { EModelEndpoint, Constants } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery, useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type * as t from 'librechat-data-provider';
|
import type * as t from 'librechat-data-provider';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { useChatContext, useAgentsMapContext, useAssistantsMapContext } from '~/Providers';
|
import { useChatContext, useAgentsMapContext, useAssistantsMapContext } from '~/Providers';
|
||||||
import { useGetAssistantDocsQuery } from '~/data-provider';
|
import {
|
||||||
|
useGetAssistantDocsQuery,
|
||||||
|
useGetEndpointsQuery,
|
||||||
|
useGetStartupConfig,
|
||||||
|
} from '~/data-provider';
|
||||||
import ConvoIcon from '~/components/Endpoints/ConvoIcon';
|
import ConvoIcon from '~/components/Endpoints/ConvoIcon';
|
||||||
import { getIconEndpoint, getEntity, cn } from '~/utils';
|
import { getIconEndpoint, getEntity, cn } from '~/utils';
|
||||||
import { useLocalize, useSubmitMessage } from '~/hooks';
|
import { useLocalize, useSubmitMessage } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ import { useState } from 'react';
|
||||||
import { Settings } from 'lucide-react';
|
import { Settings } from 'lucide-react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { EModelEndpoint } from 'librechat-data-provider';
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TConversation } from 'librechat-data-provider';
|
import type { TConversation } from 'librechat-data-provider';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { cn, getConvoSwitchLogic, getEndpointField, getIconKey } from '~/utils';
|
import { cn, getConvoSwitchLogic, getEndpointField, getIconKey } from '~/utils';
|
||||||
import { useLocalize, useUserKey, useDefaultConvo } from '~/hooks';
|
import { useLocalize, useUserKey, useDefaultConvo } from '~/hooks';
|
||||||
import { SetKeyDialog } from '~/components/Input/SetKeyDialog';
|
import { SetKeyDialog } from '~/components/Input/SetKeyDialog';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import { icons } from './Icons';
|
import { icons } from './Icons';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {
|
||||||
PermissionTypes,
|
PermissionTypes,
|
||||||
Permissions,
|
Permissions,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import MenuSeparator from '../UI/MenuSeparator';
|
import MenuSeparator from '../UI/MenuSeparator';
|
||||||
import { getEndpointField } from '~/utils';
|
import { getEndpointField } from '~/utils';
|
||||||
import { useHasAccess } from '~/hooks';
|
import { useHasAccess } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { alternateName } from 'librechat-data-provider';
|
import { alternateName } from 'librechat-data-provider';
|
||||||
import { Content, Portal, Root } from '@radix-ui/react-popover';
|
import { Content, Portal, Root } from '@radix-ui/react-popover';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { FC, KeyboardEvent } from 'react';
|
import type { FC, KeyboardEvent } from 'react';
|
||||||
import { useChatContext, useAgentsMapContext, useAssistantsMapContext } from '~/Providers';
|
import { useChatContext, useAgentsMapContext, useAssistantsMapContext } from '~/Providers';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { mapEndpoints, getEntity } from '~/utils';
|
import { mapEndpoints, getEntity } from '~/utils';
|
||||||
import EndpointItems from './Endpoints/MenuItems';
|
import EndpointItems from './Endpoints/MenuItems';
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useMemo, useCallback, useRef } from 'react';
|
import { useMemo, useCallback, useRef } from 'react';
|
||||||
import { Content, Portal, Root } from '@radix-ui/react-popover';
|
import { Content, Portal, Root } from '@radix-ui/react-popover';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { EModelEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { EModelEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import type { TModelSpec, TConversation, TEndpointsConfig } from 'librechat-data-provider';
|
import type { TModelSpec, TConversation, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import type { KeyboardEvent } from 'react';
|
import type { KeyboardEvent } from 'react';
|
||||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
||||||
import { useDefaultConvo, useNewConvo, useLocalize } from '~/hooks';
|
import { useDefaultConvo, useNewConvo, useLocalize } from '~/hooks';
|
||||||
import { getConvoSwitchLogic, getModelSpecIconURL } from '~/utils';
|
import { getConvoSwitchLogic, getModelSpecIconURL } from '~/utils';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import MenuButton from './MenuButton';
|
import MenuButton from './MenuButton';
|
||||||
import ModelSpecs from './ModelSpecs';
|
import ModelSpecs from './ModelSpecs';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { useRecoilState } from 'recoil';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { QueryKeys, isAgentsEndpoint } from 'librechat-data-provider';
|
import { QueryKeys, isAgentsEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TModelsConfig, TEndpointsConfig } from 'librechat-data-provider';
|
import type { TModelsConfig, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import {
|
import {
|
||||||
cn,
|
cn,
|
||||||
|
|
@ -16,6 +15,7 @@ import { useSetIndexOptions, useLocalize, useDebouncedInput } from '~/hooks';
|
||||||
import PopoverButtons from '~/components/Chat/Input/PopoverButtons';
|
import PopoverButtons from '~/components/Chat/Input/PopoverButtons';
|
||||||
import DialogTemplate from '~/components/ui/DialogTemplate';
|
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||||
import { EndpointSettings } from '~/components/Endpoints';
|
import { EndpointSettings } from '~/components/Endpoints';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { Close } from '@radix-ui/react-popover';
|
import { Close } from '@radix-ui/react-popover';
|
||||||
import { Flipper, Flipped } from 'react-flip-toolkit';
|
import { Flipper, Flipped } from 'react-flip-toolkit';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import type { TPreset } from 'librechat-data-provider';
|
import type { TPreset } from 'librechat-data-provider';
|
||||||
import { getPresetTitle, getEndpointField, getIconKey } from '~/utils';
|
import { getPresetTitle, getEndpointField, getIconKey } from '~/utils';
|
||||||
|
|
@ -9,6 +8,7 @@ import FileUpload from '~/components/Chat/Input/Files/FileUpload';
|
||||||
import { PinIcon, EditIcon, TrashIcon } from '~/components/svg';
|
import { PinIcon, EditIcon, TrashIcon } from '~/components/svg';
|
||||||
import { Dialog, DialogTrigger, Label } from '~/components/ui';
|
import { Dialog, DialogTrigger, Label } from '~/components/ui';
|
||||||
import DialogTemplate from '~/components/ui/DialogTemplate';
|
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { MenuSeparator, MenuItem } from '../UI';
|
import { MenuSeparator, MenuItem } from '../UI';
|
||||||
import { icons } from '../Endpoints/Icons';
|
import { icons } from '../Endpoints/Icons';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useMemo, memo } from 'react';
|
import React, { useMemo, memo } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { Assistant, Agent } from 'librechat-data-provider';
|
import type { Assistant, Agent } from 'librechat-data-provider';
|
||||||
import type { TMessageIcon } from '~/common';
|
import type { TMessageIcon } from '~/common';
|
||||||
import { getEndpointField, getIconEndpoint, logger } from '~/utils';
|
import { getEndpointField, getIconEndpoint, logger } from '~/utils';
|
||||||
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import Icon from '~/components/Endpoints/Icon';
|
import Icon from '~/components/Endpoints/Icon';
|
||||||
|
|
||||||
const MessageIcon = memo(
|
const MessageIcon = memo(
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import { FileSources, LocalStorageKeys, getConfigDefaults } from 'librechat-data-provider';
|
import { FileSources, LocalStorageKeys, getConfigDefaults } from 'librechat-data-provider';
|
||||||
import type { ExtendedFile } from '~/common';
|
import type { ExtendedFile } from '~/common';
|
||||||
|
import { useDeleteFilesMutation, useGetStartupConfig } from '~/data-provider';
|
||||||
import DragDropWrapper from '~/components/Chat/Input/Files/DragDropWrapper';
|
import DragDropWrapper from '~/components/Chat/Input/Files/DragDropWrapper';
|
||||||
import { useDeleteFilesMutation } from '~/data-provider';
|
|
||||||
import Artifacts from '~/components/Artifacts/Artifacts';
|
import Artifacts from '~/components/Artifacts/Artifacts';
|
||||||
import { SidePanel } from '~/components/SidePanel';
|
import { SidePanel } from '~/components/SidePanel';
|
||||||
import { useSetFilesToDelete } from '~/hooks';
|
import { useSetFilesToDelete } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ import { useRecoilValue } from 'recoil';
|
||||||
import { Check, X } from 'lucide-react';
|
import { Check, X } from 'lucide-react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { Constants } from 'librechat-data-provider';
|
import { Constants } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
|
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
|
||||||
import type { TConversation } from 'librechat-data-provider';
|
import type { TConversation } from 'librechat-data-provider';
|
||||||
import { useNavigateToConvo, useMediaQuery, useLocalize } from '~/hooks';
|
import { useNavigateToConvo, useMediaQuery, useLocalize } from '~/hooks';
|
||||||
import { useUpdateConversationMutation } from '~/data-provider';
|
import { useUpdateConversationMutation } from '~/data-provider';
|
||||||
import EndpointIcon from '~/components/Endpoints/EndpointIcon';
|
import EndpointIcon from '~/components/Endpoints/EndpointIcon';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { NotificationSeverity } from '~/common';
|
import { NotificationSeverity } from '~/common';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import { ConvoOptions } from './ConvoOptions';
|
import { ConvoOptions } from './ConvoOptions';
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { useState, useId, useRef, memo } from 'react';
|
import { useState, useId, useRef, memo } from 'react';
|
||||||
import * as Menu from '@ariakit/react/menu';
|
import * as Menu from '@ariakit/react/menu';
|
||||||
import { Ellipsis, Share2, Copy, Archive, Pen, Trash } from 'lucide-react';
|
import { Ellipsis, Share2, Copy, Archive, Pen, Trash } from 'lucide-react';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import type * as t from '~/common';
|
import type * as t from '~/common';
|
||||||
|
import { useDuplicateConversationMutation, useGetStartupConfig } from '~/data-provider';
|
||||||
import { useLocalize, useArchiveHandler, useNavigateToConvo } from '~/hooks';
|
import { useLocalize, useArchiveHandler, useNavigateToConvo } from '~/hooks';
|
||||||
import { useToastContext, useChatContext } from '~/Providers';
|
import { useToastContext, useChatContext } from '~/Providers';
|
||||||
import { useDuplicateConversationMutation } from '~/data-provider';
|
|
||||||
import { DropdownPopup } from '~/components/ui';
|
import { DropdownPopup } from '~/components/ui';
|
||||||
import DeleteButton from './DeleteButton';
|
import DeleteButton from './DeleteButton';
|
||||||
import ShareButton from './ShareButton';
|
import ShareButton from './ShareButton';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { SettingsViews, TConversation } from 'librechat-data-provider';
|
import { SettingsViews, TConversation } from 'librechat-data-provider';
|
||||||
import { useGetModelsQuery, useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { TSettingsProps } from '~/common';
|
import type { TSettingsProps } from '~/common';
|
||||||
import { getSettings } from './Settings';
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { cn, getEndpointField } from '~/utils';
|
import { cn, getEndpointField } from '~/utils';
|
||||||
|
import { getSettings } from './Settings';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
export default function Settings({
|
export default function Settings({
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useForm, FormProvider } from 'react-hook-form';
|
import { useForm, FormProvider } from 'react-hook-form';
|
||||||
import { EModelEndpoint, alternateName, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { EModelEndpoint, alternateName, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TDialogProps } from '~/common';
|
import type { TDialogProps } from '~/common';
|
||||||
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
||||||
import { RevokeKeysButton } from '~/components/Nav';
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { OGDialog, Dropdown } from '~/components/ui';
|
import { OGDialog, Dropdown } from '~/components/ui';
|
||||||
|
import { RevokeKeysButton } from '~/components/Nav';
|
||||||
import { useUserKey, useLocalize } from '~/hooks';
|
import { useUserKey, useLocalize } from '~/hooks';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import CustomConfig from './CustomEndpoint';
|
import CustomConfig from './CustomEndpoint';
|
||||||
|
|
@ -118,7 +118,7 @@ const SetKeyDialog = ({
|
||||||
if (isOpenAIBase && key === 'baseURL') {
|
if (isOpenAIBase && key === 'baseURL') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (key === 'baseURL' && !userProvideURL) {
|
if (key === 'baseURL' && !(userProvideURL ?? false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return data[key] === '';
|
return data[key] === '';
|
||||||
|
|
@ -205,7 +205,7 @@ const SetKeyDialog = ({
|
||||||
leftButtons={
|
leftButtons={
|
||||||
<RevokeKeysButton
|
<RevokeKeysButton
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
disabled={!expiryTime}
|
disabled={!(expiryTime ?? '')}
|
||||||
setDialogOpen={onOpenChange}
|
setDialogOpen={onOpenChange}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/react';
|
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/react';
|
||||||
import { useCallback, memo, ReactNode } from 'react';
|
import { useCallback, memo, ReactNode } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TResPlugin, TInput } from 'librechat-data-provider';
|
|
||||||
import { ChevronDownIcon, LucideProps } from 'lucide-react';
|
import { ChevronDownIcon, LucideProps } from 'lucide-react';
|
||||||
|
import type { TResPlugin, TInput } from 'librechat-data-provider';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useShareContext } from '~/Providers';
|
import { useShareContext } from '~/Providers';
|
||||||
import { cn, formatJSON } from '~/utils';
|
import { cn, formatJSON } from '~/utils';
|
||||||
import { Spinner } from '~/components';
|
import { Spinner } from '~/components';
|
||||||
|
|
@ -47,7 +47,7 @@ const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
||||||
if (pluginKey === 'n/a' || pluginKey === 'self reflection') {
|
if (pluginKey === 'n/a' || pluginKey === 'self reflection') {
|
||||||
return pluginKey;
|
return pluginKey;
|
||||||
}
|
}
|
||||||
return plugins?.[pluginKey] ?? 'self reflection';
|
return plugins[pluginKey] ?? 'self reflection';
|
||||||
},
|
},
|
||||||
[plugins],
|
[plugins],
|
||||||
);
|
);
|
||||||
|
|
@ -105,7 +105,7 @@ const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
||||||
|
|
||||||
<DisclosurePanel className="mt-3 flex max-w-full flex-col gap-3">
|
<DisclosurePanel className="mt-3 flex max-w-full flex-col gap-3">
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
lang={latestPlugin ? `REQUEST TO ${latestPlugin?.toUpperCase()}` : 'REQUEST'}
|
lang={latestPlugin ? `REQUEST TO ${latestPlugin.toUpperCase()}` : 'REQUEST'}
|
||||||
codeChildren={formatInputs(plugin.inputs ?? [])}
|
codeChildren={formatInputs(plugin.inputs ?? [])}
|
||||||
plugin={true}
|
plugin={true}
|
||||||
classProp="max-h-[450px]"
|
classProp="max-h-[450px]"
|
||||||
|
|
@ -113,7 +113,7 @@ const Plugin: React.FC<PluginProps> = ({ plugin }) => {
|
||||||
{plugin.outputs && plugin.outputs.length > 0 && (
|
{plugin.outputs && plugin.outputs.length > 0 && (
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
lang={
|
lang={
|
||||||
latestPlugin ? `RESPONSE FROM ${latestPlugin?.toUpperCase()}` : 'RESPONSE'
|
latestPlugin ? `RESPONSE FROM ${latestPlugin.toUpperCase()}` : 'RESPONSE'
|
||||||
}
|
}
|
||||||
codeChildren={formatJSON(plugin.outputs ?? '')}
|
codeChildren={formatJSON(plugin.outputs ?? '')}
|
||||||
plugin={true}
|
plugin={true}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { useRecoilState } from 'recoil';
|
||||||
import * as Select from '@ariakit/react/select';
|
import * as Select from '@ariakit/react/select';
|
||||||
import { Fragment, useState, memo } from 'react';
|
import { Fragment, useState, memo } from 'react';
|
||||||
import { FileText, LogOut } from 'lucide-react';
|
import { FileText, LogOut } from 'lucide-react';
|
||||||
import { useGetUserBalance, useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import { LinkIcon, GearIcon, DropdownMenuSeparator } from '~/components';
|
import { LinkIcon, GearIcon, DropdownMenuSeparator } from '~/components';
|
||||||
|
import { useGetStartupConfig, useGetUserBalance } from '~/data-provider';
|
||||||
import FilesView from '~/components/Chat/Input/Files/FilesView';
|
import FilesView from '~/components/Chat/Input/Files/FilesView';
|
||||||
import { useAuthContext } from '~/hooks/AuthContext';
|
import { useAuthContext } from '~/hooks/AuthContext';
|
||||||
import useAvatar from '~/hooks/Messages/useAvatar';
|
import useAvatar from '~/hooks/Messages/useAvatar';
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ import { useRecoilValue } from 'recoil';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { QueryKeys, Constants } from 'librechat-data-provider';
|
import { QueryKeys, Constants } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TConversation, TMessage } from 'librechat-data-provider';
|
import type { TConversation, TMessage } from 'librechat-data-provider';
|
||||||
import { getEndpointField, getIconEndpoint, getIconKey } from '~/utils';
|
import { getEndpointField, getIconEndpoint, getIconKey } from '~/utils';
|
||||||
import { icons } from '~/components/Chat/Menus/Endpoints/Icons';
|
import { icons } from '~/components/Chat/Menus/Endpoints/Icons';
|
||||||
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useLocalize, useNewConvo } from '~/hooks';
|
import { useLocalize, useNewConvo } from '~/hooks';
|
||||||
import { NewChatIcon } from '~/components/svg';
|
import { NewChatIcon } from '~/components/svg';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import { render, screen, fireEvent } from 'test/layout-test-utils';
|
||||||
import PluginStoreDialog from '../PluginStoreDialog';
|
import PluginStoreDialog from '../PluginStoreDialog';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
import * as mockDataProvider from 'librechat-data-provider/react-query';
|
||||||
|
import * as authMutations from '~/data-provider/Auth/mutations';
|
||||||
|
import * as authQueries from '~/data-provider/Auth/queries';
|
||||||
|
|
||||||
jest.mock('librechat-data-provider/react-query');
|
jest.mock('librechat-data-provider/react-query');
|
||||||
|
|
||||||
|
|
@ -143,11 +145,11 @@ const setup = ({
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useUpdateUserPluginsMutationReturnValue);
|
.mockReturnValue(useUpdateUserPluginsMutationReturnValue);
|
||||||
const mockUseGetUserQuery = jest
|
const mockUseGetUserQuery = jest
|
||||||
.spyOn(mockDataProvider, 'useGetUserQuery')
|
.spyOn(authQueries, 'useGetUserQuery')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useGetUserQueryReturnValue);
|
.mockReturnValue(useGetUserQueryReturnValue);
|
||||||
const mockUseRefreshTokenMutation = jest
|
const mockUseRefreshTokenMutation = jest
|
||||||
.spyOn(mockDataProvider, 'useRefreshTokenMutation')
|
.spyOn(authMutations, 'useRefreshTokenMutation')
|
||||||
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
//@ts-ignore - we don't need all parameters of the QueryObserverSuccessResult
|
||||||
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
.mockReturnValue(useRefreshTokenMutationReturnValue);
|
||||||
const mockSetIsOpen = jest.fn();
|
const mockSetIsOpen = jest.fn();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TPromptGroup, TStartupConfig } from 'librechat-data-provider';
|
import type { TPromptGroup, TStartupConfig } from 'librechat-data-provider';
|
||||||
import DashGroupItem from '~/components/Prompts/Groups/DashGroupItem';
|
import DashGroupItem from '~/components/Prompts/Groups/DashGroupItem';
|
||||||
import ChatGroupItem from '~/components/Prompts/Groups/ChatGroupItem';
|
import ChatGroupItem from '~/components/Prompts/Groups/ChatGroupItem';
|
||||||
|
import { useGetStartupConfig } from '~/data-provider';
|
||||||
import { useLocalize, useHasAccess } from '~/hooks';
|
import { useLocalize, useHasAccess } from '~/hooks';
|
||||||
import { Button, Skeleton } from '~/components/ui';
|
import { Button, Skeleton } from '~/components/ui';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import React, { useEffect, useMemo } from 'react';
|
||||||
import { Share2Icon } from 'lucide-react';
|
import { Share2Icon } from 'lucide-react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { Permissions } from 'librechat-data-provider';
|
import { Permissions } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type {
|
import type {
|
||||||
TPromptGroup,
|
TPromptGroup,
|
||||||
TStartupConfig,
|
TStartupConfig,
|
||||||
|
|
@ -15,7 +14,7 @@ import {
|
||||||
OGDialogTrigger,
|
OGDialogTrigger,
|
||||||
OGDialogClose,
|
OGDialogClose,
|
||||||
} from '~/components/ui';
|
} from '~/components/ui';
|
||||||
import { useUpdatePromptGroup } from '~/data-provider';
|
import { useUpdatePromptGroup, useGetStartupConfig } from '~/data-provider';
|
||||||
import { Button, Switch } from '~/components/ui';
|
import { Button, Switch } from '~/components/ui';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useGetSharedMessages, useGetStartupConfig } from 'librechat-data-provider/react-query';
|
import { useGetSharedMessages } from 'librechat-data-provider/react-query';
|
||||||
import { useLocalize, useDocumentTitle } from '~/hooks';
|
import { useLocalize, useDocumentTitle } from '~/hooks';
|
||||||
|
import { useGetStartupConfig } from '~/data-provider';
|
||||||
import { ShareContext } from '~/Providers';
|
import { ShareContext } from '~/Providers';
|
||||||
import { Spinner } from '~/components/svg';
|
import { Spinner } from '~/components/svg';
|
||||||
import MessagesView from './MessagesView';
|
import MessagesView from './MessagesView';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { useState, useEffect, useMemo } from 'react';
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
import { EModelEndpoint } from 'librechat-data-provider';
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { ActionsEndpoint } from '~/common';
|
import type { ActionsEndpoint } from '~/common';
|
||||||
import type { Action, TConfig, TEndpointsConfig } from 'librechat-data-provider';
|
import type { Action, TConfig, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import { useGetActionsQuery } from '~/data-provider';
|
import { useGetActionsQuery, useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import ActionsPanel from './ActionsPanel';
|
import ActionsPanel from './ActionsPanel';
|
||||||
import AgentPanel from './AgentPanel';
|
import AgentPanel from './AgentPanel';
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
import { Plus, EarthIcon } from 'lucide-react';
|
import { Plus, EarthIcon } from 'lucide-react';
|
||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
|
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
|
||||||
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
|
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
|
||||||
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
|
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
|
||||||
import type { UseFormReset } from 'react-hook-form';
|
import type { UseFormReset } from 'react-hook-form';
|
||||||
import type { TAgentCapabilities, AgentForm, TAgentOption } from '~/common';
|
import type { TAgentCapabilities, AgentForm, TAgentOption } from '~/common';
|
||||||
import { cn, createDropdownSetter, createProviderOption, processAgentOption } from '~/utils';
|
import { cn, createDropdownSetter, createProviderOption, processAgentOption } from '~/utils';
|
||||||
|
import { useListAgentsQuery, useGetStartupConfig } from '~/data-provider';
|
||||||
import SelectDropDown from '~/components/ui/SelectDropDown';
|
import SelectDropDown from '~/components/ui/SelectDropDown';
|
||||||
import { useListAgentsQuery } from '~/data-provider';
|
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
const keys = new Set(Object.keys(defaultAgentFormValues));
|
const keys = new Set(Object.keys(defaultAgentFormValues));
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ import React, { useMemo, useEffect } from 'react';
|
||||||
import { ChevronLeft, RotateCcw } from 'lucide-react';
|
import { ChevronLeft, RotateCcw } from 'lucide-react';
|
||||||
import { getSettingsKeys } from 'librechat-data-provider';
|
import { getSettingsKeys } from 'librechat-data-provider';
|
||||||
import { useFormContext, useWatch, Controller } from 'react-hook-form';
|
import { useFormContext, useWatch, Controller } from 'react-hook-form';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type * as t from 'librechat-data-provider';
|
import type * as t from 'librechat-data-provider';
|
||||||
import type { AgentForm, AgentModelPanelProps, StringOption } from '~/common';
|
import type { AgentForm, AgentModelPanelProps, StringOption } from '~/common';
|
||||||
import { componentMapping } from '~/components/SidePanel/Parameters/components';
|
import { componentMapping } from '~/components/SidePanel/Parameters/components';
|
||||||
import { agentSettings } from '~/components/SidePanel/Parameters/settings';
|
import { agentSettings } from '~/components/SidePanel/Parameters/settings';
|
||||||
import { getEndpointField, cn, cardStyle } from '~/utils';
|
import { getEndpointField, cn, cardStyle } from '~/utils';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { SelectDropDown } from '~/components/ui';
|
import { SelectDropDown } from '~/components/ui';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
import { Panel } from '~/common';
|
import { Panel } from '~/common';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import React, { useEffect, useMemo } from 'react';
|
||||||
import { Share2Icon } from 'lucide-react';
|
import { Share2Icon } from 'lucide-react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { Permissions } from 'librechat-data-provider';
|
import { Permissions } from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TStartupConfig, AgentUpdateParams } from 'librechat-data-provider';
|
import type { TStartupConfig, AgentUpdateParams } from 'librechat-data-provider';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
|
@ -13,7 +12,7 @@ import {
|
||||||
OGDialogContent,
|
OGDialogContent,
|
||||||
OGDialogTrigger,
|
OGDialogTrigger,
|
||||||
} from '~/components/ui';
|
} from '~/components/ui';
|
||||||
import { useUpdateAgentMutation } from '~/data-provider';
|
import { useUpdateAgentMutation, useGetStartupConfig } from '~/data-provider';
|
||||||
import { cn, removeFocusOutlines } from '~/utils';
|
import { cn, removeFocusOutlines } from '~/utils';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import { useState, useEffect, useMemo } from 'react';
|
import { useState, useEffect, useMemo } from 'react';
|
||||||
import { defaultAssistantsVersion } from 'librechat-data-provider';
|
import { defaultAssistantsVersion } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { Action, TEndpointsConfig, AssistantsEndpoint } from 'librechat-data-provider';
|
import type { Action, TEndpointsConfig, AssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import type { ActionsEndpoint } from '~/common';
|
import type { ActionsEndpoint } from '~/common';
|
||||||
import { useGetActionsQuery, useGetAssistantDocsQuery } from '~/data-provider';
|
import {
|
||||||
|
useGetActionsQuery,
|
||||||
|
useGetEndpointsQuery,
|
||||||
|
useGetAssistantDocsQuery,
|
||||||
|
} from '~/data-provider';
|
||||||
import AssistantPanel from './AssistantPanel';
|
import AssistantPanel from './AssistantPanel';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import ActionsPanel from './ActionsPanel';
|
import ActionsPanel from './ActionsPanel';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useMemo, useState, useEffect, useCallback } from 'react';
|
import React, { useMemo, useState, useEffect, useCallback } from 'react';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { getSettingsKeys, tConvoUpdateSchema } from 'librechat-data-provider';
|
import { getSettingsKeys, tConvoUpdateSchema } from 'librechat-data-provider';
|
||||||
import type { TPreset } from 'librechat-data-provider';
|
import type { TPreset } from 'librechat-data-provider';
|
||||||
import { SaveAsPresetDialog } from '~/components/Endpoints';
|
import { SaveAsPresetDialog } from '~/components/Endpoints';
|
||||||
import { useSetIndexOptions, useLocalize } from '~/hooks';
|
import { useSetIndexOptions, useLocalize } from '~/hooks';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { getEndpointField, logger } from '~/utils';
|
import { getEndpointField, logger } from '~/utils';
|
||||||
import { componentMapping } from './components';
|
import { componentMapping } from './components';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
import { getConfigDefaults } from 'librechat-data-provider';
|
import { getConfigDefaults } from 'librechat-data-provider';
|
||||||
|
import { useUserKeyQuery } from 'librechat-data-provider/react-query';
|
||||||
import { useState, useRef, useCallback, useEffect, useMemo, memo } from 'react';
|
import { useState, useRef, useCallback, useEffect, useMemo, memo } from 'react';
|
||||||
import {
|
|
||||||
useGetEndpointsQuery,
|
|
||||||
useGetStartupConfig,
|
|
||||||
useUserKeyQuery,
|
|
||||||
} from 'librechat-data-provider/react-query';
|
|
||||||
import type { TEndpointsConfig, TInterfaceConfig } from 'librechat-data-provider';
|
import type { TEndpointsConfig, TInterfaceConfig } from 'librechat-data-provider';
|
||||||
import type { ImperativePanelHandle } from 'react-resizable-panels';
|
import type { ImperativePanelHandle } from 'react-resizable-panels';
|
||||||
import { ResizableHandleAlt, ResizablePanel, ResizablePanelGroup } from '~/components/ui/Resizable';
|
import { ResizableHandleAlt, ResizablePanel, ResizablePanelGroup } from '~/components/ui/Resizable';
|
||||||
|
import { useGetEndpointsQuery, useGetStartupConfig } from '~/data-provider';
|
||||||
import { useMediaQuery, useLocalStorage, useLocalize } from '~/hooks';
|
import { useMediaQuery, useLocalStorage, useLocalize } from '~/hooks';
|
||||||
import useSideNavLinks from '~/hooks/Nav/useSideNavLinks';
|
import useSideNavLinks from '~/hooks/Nav/useSideNavLinks';
|
||||||
import NavToggle from '~/components/Nav/NavToggle';
|
import NavToggle from '~/components/Nav/NavToggle';
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
export * from './queries';
|
||||||
export * from './mutations';
|
export * from './mutations';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useResetRecoilState } from 'recoil';
|
import { useResetRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { MutationKeys, dataService } from 'librechat-data-provider';
|
import { MutationKeys, dataService, request } from 'librechat-data-provider';
|
||||||
import type { UseMutationResult } from '@tanstack/react-query';
|
import type { UseMutationResult } from '@tanstack/react-query';
|
||||||
import type * as t from 'librechat-data-provider';
|
import type * as t from 'librechat-data-provider';
|
||||||
import useClearStates from '~/hooks/Config/useClearStates';
|
import useClearStates from '~/hooks/Config/useClearStates';
|
||||||
|
|
@ -9,15 +9,17 @@ import store from '~/store';
|
||||||
/* login/logout */
|
/* login/logout */
|
||||||
export const useLogoutUserMutation = (
|
export const useLogoutUserMutation = (
|
||||||
options?: t.LogoutOptions,
|
options?: t.LogoutOptions,
|
||||||
): UseMutationResult<unknown, unknown, undefined, unknown> => {
|
): UseMutationResult<t.TLogoutResponse, unknown, undefined, unknown> => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const clearStates = useClearStates();
|
const clearStates = useClearStates();
|
||||||
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
|
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
|
||||||
|
const setQueriesEnabled = useSetRecoilState<boolean>(store.queriesEnabled);
|
||||||
|
|
||||||
return useMutation([MutationKeys.logoutUser], {
|
return useMutation([MutationKeys.logoutUser], {
|
||||||
mutationFn: () => dataService.logout(),
|
mutationFn: () => dataService.logout(),
|
||||||
...(options || {}),
|
...(options || {}),
|
||||||
onSuccess: (...args) => {
|
onSuccess: (...args) => {
|
||||||
|
setQueriesEnabled(false);
|
||||||
resetDefaultPreset();
|
resetDefaultPreset();
|
||||||
clearStates();
|
clearStates();
|
||||||
queryClient.removeQueries();
|
queryClient.removeQueries();
|
||||||
|
|
@ -26,20 +28,39 @@ export const useLogoutUserMutation = (
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useLoginUserMutation = (): UseMutationResult<
|
export const useLoginUserMutation = (
|
||||||
t.TLoginResponse,
|
options?: t.MutationOptions<t.TLoginResponse, t.TLoginUser, unknown, unknown>,
|
||||||
unknown,
|
): UseMutationResult<t.TLoginResponse, unknown, t.TLoginUser, unknown> => {
|
||||||
t.TLoginUser,
|
|
||||||
unknown
|
|
||||||
> => {
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const clearStates = useClearStates();
|
const clearStates = useClearStates();
|
||||||
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
|
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
|
||||||
return useMutation((payload: t.TLoginUser) => dataService.login(payload), {
|
const setQueriesEnabled = useSetRecoilState<boolean>(store.queriesEnabled);
|
||||||
onMutate: () => {
|
return useMutation([MutationKeys.loginUser], {
|
||||||
|
mutationFn: (payload: t.TLoginUser) => dataService.login(payload),
|
||||||
|
...(options || {}),
|
||||||
|
onMutate: (vars) => {
|
||||||
resetDefaultPreset();
|
resetDefaultPreset();
|
||||||
clearStates();
|
clearStates();
|
||||||
queryClient.removeQueries();
|
queryClient.removeQueries();
|
||||||
|
options?.onMutate?.(vars);
|
||||||
|
},
|
||||||
|
onSuccess: (...args) => {
|
||||||
|
setQueriesEnabled(true);
|
||||||
|
options?.onSuccess?.(...args);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useRefreshTokenMutation = (
|
||||||
|
options?: t.MutationOptions<t.TRefreshTokenResponse | undefined, undefined, unknown, unknown>,
|
||||||
|
): UseMutationResult<t.TRefreshTokenResponse | undefined, unknown, undefined, unknown> => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation([MutationKeys.refreshToken], {
|
||||||
|
mutationFn: () => request.refreshToken(),
|
||||||
|
...(options || {}),
|
||||||
|
onMutate: (vars) => {
|
||||||
|
queryClient.removeQueries();
|
||||||
|
options?.onMutate?.(vars);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
20
client/src/data-provider/Auth/queries.ts
Normal file
20
client/src/data-provider/Auth/queries.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { QueryKeys, dataService } from 'librechat-data-provider';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query';
|
||||||
|
import type t from 'librechat-data-provider';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export const useGetUserQuery = (
|
||||||
|
config?: UseQueryOptions<t.TUser>,
|
||||||
|
): QueryObserverResult<t.TUser> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<t.TUser>([QueryKeys.user], () => dataService.getUser(), {
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
retry: false,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
1
client/src/data-provider/Endpoints/index.ts
Normal file
1
client/src/data-provider/Endpoints/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './queries';
|
||||||
41
client/src/data-provider/Endpoints/queries.ts
Normal file
41
client/src/data-provider/Endpoints/queries.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { QueryKeys, dataService } from 'librechat-data-provider';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query';
|
||||||
|
import type t from 'librechat-data-provider';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export const useGetEndpointsQuery = <TData = t.TEndpointsConfig>(
|
||||||
|
config?: UseQueryOptions<t.TEndpointsConfig, unknown, TData>,
|
||||||
|
): QueryObserverResult<TData> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<t.TEndpointsConfig, unknown, TData>(
|
||||||
|
[QueryKeys.endpoints],
|
||||||
|
() => dataService.getAIEndpoints(),
|
||||||
|
{
|
||||||
|
staleTime: Infinity,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetStartupConfig = (
|
||||||
|
config?: UseQueryOptions<t.TStartupConfig>,
|
||||||
|
): QueryObserverResult<t.TStartupConfig> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<t.TStartupConfig>(
|
||||||
|
[QueryKeys.startupConfig],
|
||||||
|
() => dataService.getStartupConfig(),
|
||||||
|
{
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { QueryKeys, dataService } from 'librechat-data-provider';
|
import { QueryKeys, dataService } from 'librechat-data-provider';
|
||||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query';
|
import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query';
|
||||||
import type t from 'librechat-data-provider';
|
import type t from 'librechat-data-provider';
|
||||||
import { addFileToCache } from '~/utils';
|
import { addFileToCache } from '~/utils';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
export const useGetFiles = <TData = t.TFile[] | boolean>(
|
export const useGetFiles = <TData = t.TFile[] | boolean>(
|
||||||
config?: UseQueryOptions<t.TFile[], unknown, TData>,
|
config?: UseQueryOptions<t.TFile[], unknown, TData>,
|
||||||
): QueryObserverResult<TData, unknown> => {
|
): QueryObserverResult<TData, unknown> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
return useQuery<t.TFile[], unknown, TData>([QueryKeys.files], () => dataService.getFiles(), {
|
return useQuery<t.TFile[], unknown, TData>([QueryKeys.files], () => dataService.getFiles(), {
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
...config,
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
1
client/src/data-provider/Misc/index.ts
Normal file
1
client/src/data-provider/Misc/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './queries';
|
||||||
45
client/src/data-provider/Misc/queries.ts
Normal file
45
client/src/data-provider/Misc/queries.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { QueryKeys, dataService } from 'librechat-data-provider';
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import type { QueryObserverResult, UseQueryOptions } from '@tanstack/react-query';
|
||||||
|
import type t from 'librechat-data-provider';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export const useGetBannerQuery = (
|
||||||
|
config?: UseQueryOptions<t.TBannerResponse>,
|
||||||
|
): QueryObserverResult<t.TBannerResponse> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<t.TBannerResponse>([QueryKeys.banner], () => dataService.getBanner(), {
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetUserBalance = (
|
||||||
|
config?: UseQueryOptions<string>,
|
||||||
|
): QueryObserverResult<string> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<string>([QueryKeys.balance], () => dataService.getUserBalance(), {
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
|
refetchOnReconnect: true,
|
||||||
|
refetchOnMount: true,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetSearchEnabledQuery = (
|
||||||
|
config?: UseQueryOptions<boolean>,
|
||||||
|
): QueryObserverResult<boolean> => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
|
return useQuery<boolean>([QueryKeys.searchEnabled], () => dataService.getSearchEnabled(), {
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
export * from './Auth';
|
export * from './Auth';
|
||||||
export * from './Agents';
|
export * from './Agents';
|
||||||
|
export * from './Endpoints';
|
||||||
export * from './Files';
|
export * from './Files';
|
||||||
export * from './Messages';
|
export * from './Messages';
|
||||||
|
export * from './Misc';
|
||||||
export * from './Tools';
|
export * from './Tools';
|
||||||
export * from './connection';
|
export * from './connection';
|
||||||
export * from './mutations';
|
export * from './mutations';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import {
|
||||||
defaultOrderQuery,
|
defaultOrderQuery,
|
||||||
defaultAssistantsVersion,
|
defaultAssistantsVersion,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import type {
|
import type {
|
||||||
UseInfiniteQueryOptions,
|
UseInfiniteQueryOptions,
|
||||||
|
|
@ -28,6 +29,7 @@ import type {
|
||||||
SharedLinksResponse,
|
SharedLinksResponse,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { findPageForConversation } from '~/utils';
|
import { findPageForConversation } from '~/utils';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
export const useGetPresetsQuery = (
|
export const useGetPresetsQuery = (
|
||||||
config?: UseQueryOptions<TPreset[]>,
|
config?: UseQueryOptions<TPreset[]>,
|
||||||
|
|
@ -115,6 +117,7 @@ export const useConversationsInfiniteQuery = (
|
||||||
params?: ConversationListParams,
|
params?: ConversationListParams,
|
||||||
config?: UseInfiniteQueryOptions<ConversationListResponse, unknown>,
|
config?: UseInfiniteQueryOptions<ConversationListResponse, unknown>,
|
||||||
) => {
|
) => {
|
||||||
|
const queriesEnabled = useRecoilValue<boolean>(store.queriesEnabled);
|
||||||
return useInfiniteQuery<ConversationListResponse, unknown>(
|
return useInfiniteQuery<ConversationListResponse, unknown>(
|
||||||
params?.isArchived === true ? [QueryKeys.archivedConversations] : [QueryKeys.allConversations],
|
params?.isArchived === true ? [QueryKeys.archivedConversations] : [QueryKeys.allConversations],
|
||||||
({ pageParam = '' }) =>
|
({ pageParam = '' }) =>
|
||||||
|
|
@ -135,6 +138,7 @@ export const useConversationsInfiniteQuery = (
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
...config,
|
...config,
|
||||||
|
enabled: (config?.enabled ?? true) === true && queriesEnabled,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -156,7 +160,7 @@ export const useSharedLinksQuery = (
|
||||||
sortBy,
|
sortBy,
|
||||||
sortDirection,
|
sortDirection,
|
||||||
}),
|
}),
|
||||||
getNextPageParam: (lastPage) => lastPage?.nextCursor ?? undefined,
|
getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
|
||||||
keepPreviousData: true,
|
keepPreviousData: true,
|
||||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||||
cacheTime: 30 * 60 * 1000, // 30 minutes
|
cacheTime: 30 * 60 * 1000, // 30 minutes
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,17 @@ import {
|
||||||
useCallback,
|
useCallback,
|
||||||
createContext,
|
createContext,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useRecoilState } from 'recoil';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
import { setTokenHeader, SystemRoles } from 'librechat-data-provider';
|
import { setTokenHeader, SystemRoles } from 'librechat-data-provider';
|
||||||
import { useGetUserQuery, useRefreshTokenMutation } from 'librechat-data-provider/react-query';
|
import type * as t from 'librechat-data-provider';
|
||||||
import type { TLoginResponse, TLoginUser } from 'librechat-data-provider';
|
import {
|
||||||
import { useLoginUserMutation, useLogoutUserMutation, useGetRole } from '~/data-provider';
|
useGetRole,
|
||||||
|
useGetUserQuery,
|
||||||
|
useLoginUserMutation,
|
||||||
|
useLogoutUserMutation,
|
||||||
|
useRefreshTokenMutation,
|
||||||
|
} from '~/data-provider';
|
||||||
import { TAuthConfig, TUserContext, TAuthContext, TResError } from '~/common';
|
import { TAuthConfig, TUserContext, TAuthContext, TResError } from '~/common';
|
||||||
import useTimeout from './useTimeout';
|
import useTimeout from './useTimeout';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
@ -42,14 +47,20 @@ const AuthContextProvider = ({
|
||||||
const setUserContext = useCallback(
|
const setUserContext = useCallback(
|
||||||
(userContext: TUserContext) => {
|
(userContext: TUserContext) => {
|
||||||
const { token, isAuthenticated, user, redirect } = userContext;
|
const { token, isAuthenticated, user, redirect } = userContext;
|
||||||
if (user) {
|
setUser(user);
|
||||||
setUser(user);
|
|
||||||
}
|
|
||||||
setToken(token);
|
setToken(token);
|
||||||
//@ts-ignore - ok for token to be undefined initially
|
//@ts-ignore - ok for token to be undefined initially
|
||||||
setTokenHeader(token);
|
setTokenHeader(token);
|
||||||
setIsAuthenticated(isAuthenticated);
|
setIsAuthenticated(isAuthenticated);
|
||||||
if (redirect != null && redirect) {
|
if (redirect == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (redirect.startsWith('http://') || redirect.startsWith('https://')) {
|
||||||
|
// For external links, use window.location
|
||||||
|
window.location.href = redirect;
|
||||||
|
// Or if you want to open in a new tab:
|
||||||
|
// window.open(redirect, '_blank');
|
||||||
|
} else {
|
||||||
navigate(redirect, { replace: true });
|
navigate(redirect, { replace: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -57,14 +68,25 @@ const AuthContextProvider = ({
|
||||||
);
|
);
|
||||||
const doSetError = useTimeout({ callback: (error) => setError(error as string | undefined) });
|
const doSetError = useTimeout({ callback: (error) => setError(error as string | undefined) });
|
||||||
|
|
||||||
const loginUser = useLoginUserMutation();
|
const loginUser = useLoginUserMutation({
|
||||||
|
onSuccess: (data: t.TLoginResponse) => {
|
||||||
|
const { user, token } = data;
|
||||||
|
setError(undefined);
|
||||||
|
setUserContext({ token, isAuthenticated: true, user, redirect: '/c/new' });
|
||||||
|
},
|
||||||
|
onError: (error: TResError | unknown) => {
|
||||||
|
const resError = error as TResError;
|
||||||
|
doSetError(resError.message);
|
||||||
|
navigate('/login', { replace: true });
|
||||||
|
},
|
||||||
|
});
|
||||||
const logoutUser = useLogoutUserMutation({
|
const logoutUser = useLogoutUserMutation({
|
||||||
onSuccess: () => {
|
onSuccess: (data) => {
|
||||||
setUserContext({
|
setUserContext({
|
||||||
token: undefined,
|
token: undefined,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
user: undefined,
|
user: undefined,
|
||||||
redirect: '/login',
|
redirect: data.redirect ?? '/login',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|
@ -77,24 +99,13 @@ const AuthContextProvider = ({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const refreshToken = useRefreshTokenMutation();
|
||||||
|
|
||||||
const logout = useCallback(() => logoutUser.mutate(undefined), [logoutUser]);
|
const logout = useCallback(() => logoutUser.mutate(undefined), [logoutUser]);
|
||||||
const userQuery = useGetUserQuery({ enabled: !!(token ?? '') });
|
const userQuery = useGetUserQuery({ enabled: !!(token ?? '') });
|
||||||
const refreshToken = useRefreshTokenMutation();
|
|
||||||
|
|
||||||
const login = (data: TLoginUser) => {
|
const login = (data: t.TLoginUser) => {
|
||||||
loginUser.mutate(data, {
|
loginUser.mutate(data);
|
||||||
onSuccess: (data: TLoginResponse) => {
|
|
||||||
const { user, token } = data;
|
|
||||||
setError(undefined);
|
|
||||||
setUserContext({ token, isAuthenticated: true, user, redirect: '/c/new' });
|
|
||||||
},
|
|
||||||
onError: (error: TResError | unknown) => {
|
|
||||||
const resError = error as TResError;
|
|
||||||
doSetError(resError.message);
|
|
||||||
navigate('/login', { replace: true });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const silentRefresh = useCallback(() => {
|
const silentRefresh = useCallback(() => {
|
||||||
|
|
@ -103,7 +114,7 @@ const AuthContextProvider = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
refreshToken.mutate(undefined, {
|
refreshToken.mutate(undefined, {
|
||||||
onSuccess: (data: TLoginResponse | undefined) => {
|
onSuccess: (data: t.TRefreshTokenResponse | undefined) => {
|
||||||
const { user, token = '' } = data ?? {};
|
const { user, token = '' } = data ?? {};
|
||||||
if (token) {
|
if (token) {
|
||||||
setUserContext({ token, isAuthenticated: true, user });
|
setUserContext({ token, isAuthenticated: true, user });
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import { LocalStorageKeys } from 'librechat-data-provider';
|
||||||
import { useAvailablePluginsQuery } from 'librechat-data-provider/react-query';
|
import { useAvailablePluginsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { TStartupConfig, TPlugin, TUser } from 'librechat-data-provider';
|
import type { TStartupConfig, TPlugin, TUser } from 'librechat-data-provider';
|
||||||
import { mapPlugins, selectPlugins, processPlugins } from '~/utils';
|
import { mapPlugins, selectPlugins, processPlugins } from '~/utils';
|
||||||
import useConfigOverride from './useConfigOverride';
|
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
const pluginStore: TPlugin = {
|
const pluginStore: TPlugin = {
|
||||||
|
|
@ -25,7 +24,6 @@ export default function useAppStartup({
|
||||||
startupConfig?: TStartupConfig;
|
startupConfig?: TStartupConfig;
|
||||||
user?: TUser;
|
user?: TUser;
|
||||||
}) {
|
}) {
|
||||||
useConfigOverride();
|
|
||||||
const setAvailableTools = useSetRecoilState(store.availableTools);
|
const setAvailableTools = useSetRecoilState(store.availableTools);
|
||||||
const [defaultPreset, setDefaultPreset] = useRecoilState(store.defaultPreset);
|
const [defaultPreset, setDefaultPreset] = useRecoilState(store.defaultPreset);
|
||||||
const { data: allPlugins } = useAvailablePluginsQuery({
|
const { data: allPlugins } = useAvailablePluginsQuery({
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { useGetEndpointsQuery, useGetModelsQuery } from 'librechat-data-provider/react-query';
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type {
|
import type {
|
||||||
TConversation,
|
|
||||||
TPreset,
|
|
||||||
TEndpointsConfig,
|
TEndpointsConfig,
|
||||||
TModelsConfig,
|
TModelsConfig,
|
||||||
|
TConversation,
|
||||||
|
TPreset,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { getDefaultEndpoint, buildDefaultConvo } from '~/utils';
|
import { getDefaultEndpoint, buildDefaultConvo } from '~/utils';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
|
|
||||||
type TDefaultConvo = { conversation: Partial<TConversation>; preset?: Partial<TPreset> | null };
|
type TDefaultConvo = { conversation: Partial<TConversation>; preset?: Partial<TPreset> | null };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useCallback, useRef, useEffect } from 'react';
|
import { useCallback, useRef, useEffect } from 'react';
|
||||||
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
import { LocalStorageKeys, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { LocalStorageKeys, isAssistantsEndpoint } from 'librechat-data-provider';
|
||||||
import { useGetModelsQuery, useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type {
|
import type {
|
||||||
TPreset,
|
TPreset,
|
||||||
TModelsConfig,
|
TModelsConfig,
|
||||||
TConversation,
|
TConversation,
|
||||||
TEndpointsConfig,
|
TEndpointsConfig,
|
||||||
|
EModelEndpoint,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { SetterOrUpdater } from 'recoil';
|
import type { SetterOrUpdater } from 'recoil';
|
||||||
import type { AssistantListItem } from '~/common';
|
import type { AssistantListItem } from '~/common';
|
||||||
import { getEndpointField, buildDefaultConvo, getDefaultEndpoint } from '~/utils';
|
import { getEndpointField, buildDefaultConvo, getDefaultEndpoint } from '~/utils';
|
||||||
import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap';
|
import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { mainTextareaId } from '~/common';
|
import { mainTextareaId } from '~/common';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
|
|
@ -32,7 +34,7 @@ const useGenerateConvo = ({
|
||||||
const rootConvo = useRecoilValue(store.conversationByKeySelector(rootIndex));
|
const rootConvo = useRecoilValue(store.conversationByKeySelector(rootIndex));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rootConvo?.conversationId && setConversation) {
|
if (rootConvo?.conversationId != null && setConversation) {
|
||||||
setConversation((prevState) => {
|
setConversation((prevState) => {
|
||||||
if (!prevState) {
|
if (!prevState) {
|
||||||
return prevState;
|
return prevState;
|
||||||
|
|
@ -85,11 +87,11 @@ const useGenerateConvo = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const isAssistantEndpoint = isAssistantsEndpoint(defaultEndpoint);
|
const isAssistantEndpoint = isAssistantsEndpoint(defaultEndpoint);
|
||||||
const assistants: AssistantListItem[] = assistantsListMap[defaultEndpoint] ?? [];
|
const assistants: AssistantListItem[] = assistantsListMap[defaultEndpoint ?? ''] ?? [];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
conversation.assistant_id &&
|
conversation.assistant_id &&
|
||||||
!assistantsListMap[defaultEndpoint]?.[conversation.assistant_id]
|
!assistantsListMap[defaultEndpoint ?? '']?.[conversation.assistant_id]
|
||||||
) {
|
) {
|
||||||
conversation.assistant_id = undefined;
|
conversation.assistant_id = undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +103,7 @@ const useGenerateConvo = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
conversation.assistant_id &&
|
conversation.assistant_id != null &&
|
||||||
isAssistantEndpoint &&
|
isAssistantEndpoint &&
|
||||||
conversation.conversationId === 'new'
|
conversation.conversationId === 'new'
|
||||||
) {
|
) {
|
||||||
|
|
@ -109,19 +111,19 @@ const useGenerateConvo = ({
|
||||||
conversation.model = assistant?.model;
|
conversation.model = assistant?.model;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.assistant_id && !isAssistantEndpoint) {
|
if (conversation.assistant_id != null && !isAssistantEndpoint) {
|
||||||
conversation.assistant_id = undefined;
|
conversation.assistant_id = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const models = modelsConfig?.[defaultEndpoint] ?? [];
|
const models = modelsConfig?.[defaultEndpoint ?? ''] ?? [];
|
||||||
conversation = buildDefaultConvo({
|
conversation = buildDefaultConvo({
|
||||||
conversation,
|
conversation,
|
||||||
lastConversationSetup: preset as TConversation,
|
lastConversationSetup: preset as TConversation,
|
||||||
endpoint: defaultEndpoint,
|
endpoint: defaultEndpoint ?? ('' as EModelEndpoint),
|
||||||
models,
|
models,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (preset?.title) {
|
if (preset?.title != null && preset.title !== '') {
|
||||||
conversation.title = preset.title;
|
conversation.title = preset.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { getResponseSender } from 'librechat-data-provider';
|
import { getResponseSender } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TEndpointOption, TEndpointsConfig } from 'librechat-data-provider';
|
import type { TEndpointOption, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
|
|
||||||
export default function useGetSender() {
|
export default function useGetSender() {
|
||||||
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
|
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { useGetSearchEnabledQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { UseInfiniteQueryResult } from '@tanstack/react-query';
|
import type { UseInfiniteQueryResult } from '@tanstack/react-query';
|
||||||
import type { ConversationListResponse } from 'librechat-data-provider';
|
import type { ConversationListResponse } from 'librechat-data-provider';
|
||||||
import { useSearchInfiniteQuery } from '~/data-provider';
|
import { useSearchInfiniteQuery, useGetSearchEnabledQuery } from '~/data-provider';
|
||||||
import useNewConvo from '~/hooks/useNewConvo';
|
import useNewConvo from '~/hooks/useNewConvo';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import {
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
useGetModelsQuery,
|
|
||||||
useGetStartupConfig,
|
|
||||||
useGetEndpointsQuery,
|
|
||||||
} from 'librechat-data-provider/react-query';
|
|
||||||
import {
|
import {
|
||||||
alternateName,
|
alternateName,
|
||||||
EModelEndpoint,
|
EModelEndpoint,
|
||||||
|
|
@ -13,8 +9,13 @@ import {
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { TAssistantsMap, TEndpointsConfig } from 'librechat-data-provider';
|
import type { TAssistantsMap, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import type { MentionOption } from '~/common';
|
import type { MentionOption } from '~/common';
|
||||||
|
import {
|
||||||
|
useGetPresetsQuery,
|
||||||
|
useGetEndpointsQuery,
|
||||||
|
useListAgentsQuery,
|
||||||
|
useGetStartupConfig,
|
||||||
|
} from '~/data-provider';
|
||||||
import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap';
|
import useAssistantListMap from '~/hooks/Assistants/useAssistantListMap';
|
||||||
import { useGetPresetsQuery, useListAgentsQuery } from '~/data-provider';
|
|
||||||
import { mapEndpoints, getPresetTitle } from '~/utils';
|
import { mapEndpoints, getPresetTitle } from '~/utils';
|
||||||
import { EndpointIcon } from '~/components/Endpoints';
|
import { EndpointIcon } from '~/components/Endpoints';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { useChatContext } from '~/Providers/ChatContext';
|
import { useChatContext } from '~/Providers/ChatContext';
|
||||||
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
import { getEndpointField } from '~/utils';
|
import { getEndpointField } from '~/utils';
|
||||||
import useUserKey from './useUserKey';
|
import useUserKey from './useUserKey';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import { useMemo, useCallback } from 'react';
|
import { useMemo, useCallback } from 'react';
|
||||||
import { EModelEndpoint } from 'librechat-data-provider';
|
import { EModelEndpoint } from 'librechat-data-provider';
|
||||||
import {
|
import { useUserKeyQuery, useUpdateUserKeysMutation } from 'librechat-data-provider/react-query';
|
||||||
useUserKeyQuery,
|
import { useGetEndpointsQuery } from '~/data-provider';
|
||||||
useGetEndpointsQuery,
|
|
||||||
useUpdateUserKeysMutation,
|
|
||||||
} from 'librechat-data-provider/react-query';
|
|
||||||
|
|
||||||
const useUserKey = (endpoint: string) => {
|
const useUserKey = (endpoint: string) => {
|
||||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
const { data: endpointsConfig } = useGetEndpointsQuery();
|
||||||
|
|
@ -24,7 +21,7 @@ const useUserKey = (endpoint: string) => {
|
||||||
|
|
||||||
const getExpiry = useCallback(() => {
|
const getExpiry = useCallback(() => {
|
||||||
if (checkUserKey.data) {
|
if (checkUserKey.data) {
|
||||||
return checkUserKey.data?.expiresAt || 'never';
|
return checkUserKey.data.expiresAt || 'never';
|
||||||
}
|
}
|
||||||
}, [checkUserKey.data]);
|
}, [checkUserKey.data]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,22 @@
|
||||||
import type { EventSubmission, TMessage, TPayload, TSubmission } from 'librechat-data-provider';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
import { SSE } from 'sse.js';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
import {
|
import {
|
||||||
|
request,
|
||||||
/* @ts-ignore */
|
/* @ts-ignore */
|
||||||
createPayload,
|
createPayload,
|
||||||
isAgentsEndpoint,
|
isAgentsEndpoint,
|
||||||
isAssistantsEndpoint,
|
|
||||||
removeNullishValues,
|
removeNullishValues,
|
||||||
request,
|
isAssistantsEndpoint,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { useGetStartupConfig, useGetUserBalance } from 'librechat-data-provider/react-query';
|
import type { EventSubmission, TMessage, TPayload, TSubmission } from 'librechat-data-provider';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
import { SSE } from 'sse.js';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
import type { TResData } from '~/common';
|
|
||||||
import { useGenTitleMutation } from '~/data-provider';
|
|
||||||
import { useAuthContext } from '~/hooks/AuthContext';
|
|
||||||
import store from '~/store';
|
|
||||||
import type { EventHandlerParams } from './useEventHandlers';
|
import type { EventHandlerParams } from './useEventHandlers';
|
||||||
|
import type { TResData } from '~/common';
|
||||||
|
import { useGenTitleMutation, useGetStartupConfig, useGetUserBalance } from '~/data-provider';
|
||||||
|
import { useAuthContext } from '~/hooks/AuthContext';
|
||||||
import useEventHandlers from './useEventHandlers';
|
import useEventHandlers from './useEventHandlers';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
type ChatHelpers = Pick<
|
type ChatHelpers = Pick<
|
||||||
EventHandlerParams,
|
EventHandlerParams,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import {
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
useGetModelsQuery,
|
|
||||||
useGetStartupConfig,
|
|
||||||
useGetEndpointsQuery,
|
|
||||||
} from 'librechat-data-provider/react-query';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Constants,
|
Constants,
|
||||||
|
|
@ -30,8 +26,8 @@ import {
|
||||||
getModelSpecIconURL,
|
getModelSpecIconURL,
|
||||||
updateLastSelectedModel,
|
updateLastSelectedModel,
|
||||||
} from '~/utils';
|
} from '~/utils';
|
||||||
|
import { useDeleteFilesMutation, useGetEndpointsQuery, useGetStartupConfig } from '~/data-provider';
|
||||||
import useAssistantListMap from './Assistants/useAssistantListMap';
|
import useAssistantListMap from './Assistants/useAssistantListMap';
|
||||||
import { useDeleteFilesMutation } from '~/data-provider';
|
|
||||||
import { usePauseGlobalAudio } from './Audio';
|
import { usePauseGlobalAudio } from './Audio';
|
||||||
import { mainTextareaId } from '~/common';
|
import { mainTextareaId } from '~/common';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { Constants, EModelEndpoint } from 'librechat-data-provider';
|
import { Constants, EModelEndpoint } from 'librechat-data-provider';
|
||||||
import {
|
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||||
useGetModelsQuery,
|
|
||||||
useGetStartupConfig,
|
|
||||||
useGetEndpointsQuery,
|
|
||||||
} from 'librechat-data-provider/react-query';
|
|
||||||
import type { TPreset } from 'librechat-data-provider';
|
import type { TPreset } from 'librechat-data-provider';
|
||||||
|
import {
|
||||||
|
useGetConvoIdQuery,
|
||||||
|
useHealthCheck,
|
||||||
|
useGetEndpointsQuery,
|
||||||
|
useGetStartupConfig,
|
||||||
|
} from '~/data-provider';
|
||||||
import { useNewConvo, useAppStartup, useAssistantListMap } from '~/hooks';
|
import { useNewConvo, useAppStartup, useAssistantListMap } from '~/hooks';
|
||||||
import { useGetConvoIdQuery, useHealthCheck } from '~/data-provider';
|
|
||||||
import { getDefaultModelSpec, getModelSpecIconURL } from '~/utils';
|
import { getDefaultModelSpec, getModelSpecIconURL } from '~/utils';
|
||||||
import { ToolCallsMapProvider } from '~/Providers';
|
import { ToolCallsMapProvider } from '~/Providers';
|
||||||
import ChatView from '~/components/Chat/ChatView';
|
import ChatView from '~/components/Chat/ChatView';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,23 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
import { useAuthContext } from '~/hooks/AuthContext';
|
import { useAuthContext } from '~/hooks/AuthContext';
|
||||||
import StartupLayout from './Startup';
|
import StartupLayout from './Startup';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
export default function LoginLayout() {
|
export default function LoginLayout() {
|
||||||
const { isAuthenticated } = useAuthContext();
|
const { isAuthenticated } = useAuthContext();
|
||||||
|
const [queriesEnabled, setQueriesEnabled] = useRecoilState<boolean>(store.queriesEnabled);
|
||||||
|
useEffect(() => {
|
||||||
|
if (queriesEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const timeout: NodeJS.Timeout = setTimeout(() => {
|
||||||
|
setQueriesEnabled(true);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
};
|
||||||
|
}, [queriesEnabled, setQueriesEnabled]);
|
||||||
return <StartupLayout isAuthenticated={isAuthenticated} />;
|
return <StartupLayout isAuthenticated={isAuthenticated} />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
|
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { TStartupConfig } from 'librechat-data-provider';
|
import type { TStartupConfig } from 'librechat-data-provider';
|
||||||
|
import { useGetStartupConfig } from '~/data-provider';
|
||||||
import AuthLayout from '~/components/Auth/AuthLayout';
|
import AuthLayout from '~/components/Auth/AuthLayout';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Outlet, useNavigate } from 'react-router-dom';
|
import { Outlet, useNavigate } from 'react-router-dom';
|
||||||
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
|
|
||||||
import type { ContextType } from '~/common';
|
import type { ContextType } from '~/common';
|
||||||
import {
|
import {
|
||||||
AgentsMapContext,
|
AgentsMapContext,
|
||||||
|
|
@ -11,7 +10,7 @@ import {
|
||||||
} from '~/Providers';
|
} from '~/Providers';
|
||||||
import { useAuthContext, useAssistantsMap, useAgentsMap, useFileMap, useSearch } from '~/hooks';
|
import { useAuthContext, useAssistantsMap, useAgentsMap, useFileMap, useSearch } from '~/hooks';
|
||||||
import TermsAndConditionsModal from '~/components/ui/TermsAndConditionsModal';
|
import TermsAndConditionsModal from '~/components/ui/TermsAndConditionsModal';
|
||||||
import { useUserTermsQuery } from '~/data-provider';
|
import { useUserTermsQuery, useGetStartupConfig } from '~/data-provider';
|
||||||
import { Nav, MobileNav } from '~/components/Nav';
|
import { Nav, MobileNav } from '~/components/Nav';
|
||||||
import { Banner } from '~/components/Banners';
|
import { Banner } from '~/components/Banners';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,9 @@ const messageAttachmentsMap = atom<Record<string, TAttachment[] | undefined>>({
|
||||||
default: {},
|
default: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default { hideBannerHint, messageAttachmentsMap };
|
const queriesEnabled = atom<boolean>({
|
||||||
|
key: 'queriesEnabled',
|
||||||
|
default: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default { hideBannerHint, messageAttachmentsMap, queriesEnabled };
|
||||||
|
|
|
||||||
|
|
@ -133,11 +133,11 @@ export const updateTokenCount = (text: string) => {
|
||||||
return request.post(endpoints.tokenizer(), { arg: text });
|
return request.post(endpoints.tokenizer(), { arg: text });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const login = (payload: t.TLoginUser) => {
|
export const login = (payload: t.TLoginUser): Promise<t.TLoginResponse> => {
|
||||||
return request.post(endpoints.login(), payload);
|
return request.post(endpoints.login(), payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const logout = () => {
|
export const logout = (): Promise<m.TLogoutResponse> => {
|
||||||
return request.post(endpoints.logout());
|
return request.post(endpoints.logout());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,9 @@ export enum MutationKeys {
|
||||||
fileDelete = 'fileDelete',
|
fileDelete = 'fileDelete',
|
||||||
updatePreset = 'updatePreset',
|
updatePreset = 'updatePreset',
|
||||||
deletePreset = 'deletePreset',
|
deletePreset = 'deletePreset',
|
||||||
|
loginUser = 'loginUser',
|
||||||
logoutUser = 'logoutUser',
|
logoutUser = 'logoutUser',
|
||||||
|
refreshToken = 'refreshToken',
|
||||||
avatarUpload = 'avatarUpload',
|
avatarUpload = 'avatarUpload',
|
||||||
speechToText = 'speechToText',
|
speechToText = 'speechToText',
|
||||||
textToSpeech = 'textToSpeech',
|
textToSpeech = 'textToSpeech',
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,10 @@ import type {
|
||||||
QueryObserverResult,
|
QueryObserverResult,
|
||||||
} from '@tanstack/react-query';
|
} from '@tanstack/react-query';
|
||||||
import { initialModelsConfig } from '../config';
|
import { initialModelsConfig } from '../config';
|
||||||
import type { TStartupConfig } from '../config';
|
|
||||||
import { defaultOrderQuery } from '../types/assistants';
|
import { defaultOrderQuery } from '../types/assistants';
|
||||||
import * as dataService from '../data-service';
|
import * as dataService from '../data-service';
|
||||||
import * as m from '../types/mutations';
|
import * as m from '../types/mutations';
|
||||||
import { QueryKeys } from '../keys';
|
import { QueryKeys } from '../keys';
|
||||||
import request from '../request';
|
|
||||||
import * as s from '../schemas';
|
import * as s from '../schemas';
|
||||||
import * as t from '../types';
|
import * as t from '../types';
|
||||||
|
|
||||||
|
|
@ -31,18 +29,6 @@ export const useAbortRequestWithMessage = (): UseMutationResult<
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetUserQuery = (
|
|
||||||
config?: UseQueryOptions<t.TUser>,
|
|
||||||
): QueryObserverResult<t.TUser> => {
|
|
||||||
return useQuery<t.TUser>([QueryKeys.user], () => dataService.getUser(), {
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
retry: false,
|
|
||||||
...config,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetMessagesByConvoId = <TData = s.TMessage[]>(
|
export const useGetMessagesByConvoId = <TData = s.TMessage[]>(
|
||||||
id: string,
|
id: string,
|
||||||
config?: UseQueryOptions<s.TMessage[], unknown, TData>,
|
config?: UseQueryOptions<s.TMessage[], unknown, TData>,
|
||||||
|
|
@ -98,17 +84,6 @@ export const useGetSharedLinkQuery = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetUserBalance = (
|
|
||||||
config?: UseQueryOptions<string>,
|
|
||||||
): QueryObserverResult<string> => {
|
|
||||||
return useQuery<string>([QueryKeys.balance], () => dataService.getUserBalance(), {
|
|
||||||
refetchOnWindowFocus: true,
|
|
||||||
refetchOnReconnect: true,
|
|
||||||
refetchOnMount: true,
|
|
||||||
...config,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetConversationByIdQuery = (
|
export const useGetConversationByIdQuery = (
|
||||||
id: string,
|
id: string,
|
||||||
config?: UseQueryOptions<s.TConversation>,
|
config?: UseQueryOptions<s.TConversation>,
|
||||||
|
|
@ -226,33 +201,6 @@ export const useRevokeAllUserKeysMutation = (): UseMutationResult<unknown> => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetSearchEnabledQuery = (
|
|
||||||
config?: UseQueryOptions<boolean>,
|
|
||||||
): QueryObserverResult<boolean> => {
|
|
||||||
return useQuery<boolean>([QueryKeys.searchEnabled], () => dataService.getSearchEnabled(), {
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
...config,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetEndpointsQuery = <TData = t.TEndpointsConfig>(
|
|
||||||
config?: UseQueryOptions<t.TEndpointsConfig, unknown, TData>,
|
|
||||||
): QueryObserverResult<TData> => {
|
|
||||||
return useQuery<t.TEndpointsConfig, unknown, TData>(
|
|
||||||
[QueryKeys.endpoints],
|
|
||||||
() => dataService.getAIEndpoints(),
|
|
||||||
{
|
|
||||||
staleTime: Infinity,
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
...config,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetModelsQuery = (
|
export const useGetModelsQuery = (
|
||||||
config?: UseQueryOptions<t.TModelsConfig>,
|
config?: UseQueryOptions<t.TModelsConfig>,
|
||||||
): QueryObserverResult<t.TModelsConfig> => {
|
): QueryObserverResult<t.TModelsConfig> => {
|
||||||
|
|
@ -343,20 +291,6 @@ export const useRegisterUserMutation = (
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRefreshTokenMutation = (): UseMutationResult<
|
|
||||||
t.TRefreshTokenResponse | undefined,
|
|
||||||
unknown,
|
|
||||||
unknown,
|
|
||||||
unknown
|
|
||||||
> => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation(() => request.refreshToken(), {
|
|
||||||
onMutate: () => {
|
|
||||||
queryClient.removeQueries();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUserKeyQuery = (
|
export const useUserKeyQuery = (
|
||||||
name: string,
|
name: string,
|
||||||
config?: UseQueryOptions<t.TCheckUserKeyResponse>,
|
config?: UseQueryOptions<t.TCheckUserKeyResponse>,
|
||||||
|
|
@ -428,17 +362,6 @@ export const useUpdateUserPluginsMutation = (
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetStartupConfig = (
|
|
||||||
config?: UseQueryOptions<TStartupConfig>,
|
|
||||||
): QueryObserverResult<TStartupConfig> => {
|
|
||||||
return useQuery<TStartupConfig>([QueryKeys.startupConfig], () => dataService.getStartupConfig(), {
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
...config,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetCustomConfigSpeechQuery = (
|
export const useGetCustomConfigSpeechQuery = (
|
||||||
config?: UseQueryOptions<t.TCustomConfigSpeechResponse>,
|
config?: UseQueryOptions<t.TCustomConfigSpeechResponse>,
|
||||||
): QueryObserverResult<t.TCustomConfigSpeechResponse> => {
|
): QueryObserverResult<t.TCustomConfigSpeechResponse> => {
|
||||||
|
|
@ -453,14 +376,3 @@ export const useGetCustomConfigSpeechQuery = (
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetBannerQuery = (
|
|
||||||
config?: UseQueryOptions<t.TBannerResponse>,
|
|
||||||
): QueryObserverResult<t.TBannerResponse> => {
|
|
||||||
return useQuery<t.TBannerResponse>([QueryKeys.banner], () => dataService.getBanner(), {
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
...config,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ axios.interceptors.response.use(
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (originalRequest.url?.includes('/api/auth/logout') === true) {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
if (error.response.status === 401 && !originalRequest._retry) {
|
if (error.response.status === 401 && !originalRequest._retry) {
|
||||||
console.warn('401 error, refreshing token');
|
console.warn('401 error, refreshing token');
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,6 @@ export type UpdatePresetOptions = MutationOptions<types.TPreset, types.TPreset>;
|
||||||
|
|
||||||
export type DeletePresetOptions = MutationOptions<PresetDeleteResponse, types.TPreset | undefined>;
|
export type DeletePresetOptions = MutationOptions<PresetDeleteResponse, types.TPreset | undefined>;
|
||||||
|
|
||||||
export type LogoutOptions = MutationOptions<unknown, undefined>;
|
|
||||||
|
|
||||||
/* Assistant mutations */
|
/* Assistant mutations */
|
||||||
|
|
||||||
export type AssistantAvatarVariables = {
|
export type AssistantAvatarVariables = {
|
||||||
|
|
@ -331,3 +329,10 @@ export type EditArtifactOptions = MutationOptions<
|
||||||
unknown,
|
unknown,
|
||||||
Error
|
Error
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export type TLogoutResponse = {
|
||||||
|
message: string;
|
||||||
|
redirect?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LogoutOptions = MutationOptions<TLogoutResponse, undefined>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue