Merge branch 'main' into feat/E2EE

This commit is contained in:
Ruben Talstra 2025-03-05 10:50:49 +01:00 committed by GitHub
commit 40e59bc55c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
206 changed files with 14792 additions and 3465 deletions

View file

@ -6,6 +6,7 @@
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="description" content="LibreChat - An open source chat application with support for multiple AI models" />
<title>LibreChat</title>
<link rel="shortcut icon" href="#" />
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png" />
@ -53,6 +54,5 @@
<div id="root">
<div id="loading-container"></div>
</div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

View file

@ -44,6 +44,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.0",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.1.2",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
@ -65,6 +66,7 @@
"html-to-image": "^1.11.11",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.3",
"input-otp": "^1.4.2",
"js-cookie": "^3.0.5",
"librechat-data-provider": "*",
"lodash": "^4.17.21",
@ -84,7 +86,7 @@
"react-i18next": "^15.4.0",
"react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^2.1.1",
"react-resizable-panels": "^2.1.7",
"react-router-dom": "^6.11.2",
"react-speech-recognition": "^3.10.0",
"react-textarea-autosize": "^8.4.0",
@ -140,6 +142,7 @@
"typescript": "^5.3.3",
"vite": "^6.1.0",
"vite-plugin-node-polyfills": "^0.17.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.21.1"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

3
client/public/robots.txt Normal file
View file

@ -0,0 +1,3 @@
User-agent: *
Disallow: /api/
Allow: /

View file

@ -85,7 +85,8 @@ function AuthLayout({
</h1>
)}
{children}
{(pathname.includes('login') || pathname.includes('register')) && (
{!pathname.includes('2fa') &&
(pathname.includes('login') || pathname.includes('register')) && (
<SocialLoginRender startupConfig={startupConfig} />
)}
</div>

View file

@ -166,9 +166,7 @@ const LoginForm: React.FC<TLoginFormProps> = ({ onSubmit, startupConfig, error,
type="submit"
className="
w-full rounded-2xl bg-green-600 px-4 py-3 text-sm font-medium text-white
transition-colors hover:bg-green-700 focus:outline-none focus:ring-2
focus:ring-green-500 focus:ring-offset-2 disabled:opacity-50
disabled:hover:bg-green-600 dark:bg-green-600 dark:hover:bg-green-700
transition-colors hover:bg-green-700 dark:bg-green-600 dark:hover:bg-green-700
"
>
{localize('com_auth_continue')}

View file

@ -0,0 +1,176 @@
import React, { useState, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label } from '~/components';
import { useVerifyTwoFactorTempMutation } from '~/data-provider';
import { useToastContext } from '~/Providers';
import { useLocalize } from '~/hooks';
interface VerifyPayload {
tempToken: string;
token?: string;
backupCode?: string;
}
type TwoFactorFormInputs = {
token?: string;
backupCode?: string;
};
const TwoFactorScreen: React.FC = React.memo(() => {
const [searchParams] = useSearchParams();
const tempTokenRaw = searchParams.get('tempToken');
const tempToken = tempTokenRaw !== null && tempTokenRaw !== '' ? tempTokenRaw : '';
const {
control,
handleSubmit,
formState: { errors },
} = useForm<TwoFactorFormInputs>();
const localize = useLocalize();
const { showToast } = useToastContext();
const [useBackup, setUseBackup] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const { mutate: verifyTempMutate } = useVerifyTwoFactorTempMutation({
onSuccess: (result) => {
if (result.token != null && result.token !== '') {
window.location.href = '/';
}
},
onMutate: () => {
setIsLoading(true);
},
onError: (error: unknown) => {
setIsLoading(false);
const err = error as { response?: { data?: { message?: unknown } } };
const errorMsg =
typeof err.response?.data?.message === 'string'
? err.response.data.message
: 'Error verifying 2FA';
showToast({ message: errorMsg, status: 'error' });
},
});
const onSubmit = useCallback(
(data: TwoFactorFormInputs) => {
const payload: VerifyPayload = { tempToken };
if (useBackup && data.backupCode != null && data.backupCode !== '') {
payload.backupCode = data.backupCode;
} else if (data.token != null && data.token !== '') {
payload.token = data.token;
}
verifyTempMutate(payload);
},
[tempToken, useBackup, verifyTempMutate],
);
const toggleBackupOn = useCallback(() => {
setUseBackup(true);
}, []);
const toggleBackupOff = useCallback(() => {
setUseBackup(false);
}, []);
return (
<div className="mt-4">
<form onSubmit={handleSubmit(onSubmit)}>
<Label className="flex justify-center break-keep text-center text-sm text-text-primary">
{localize('com_auth_two_factor')}
</Label>
{!useBackup && (
<div className="my-4 flex justify-center text-text-primary">
<Controller
name="token"
control={control}
render={({ field: { onChange, value } }) => (
<InputOTP
maxLength={6}
value={value != null ? value : ''}
onChange={onChange}
pattern={REGEXP_ONLY_DIGITS}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
)}
/>
{errors.token && <span className="text-sm text-red-500">{errors.token.message}</span>}
</div>
)}
{useBackup && (
<div className="my-4 flex justify-center text-text-primary">
<Controller
name="backupCode"
control={control}
render={({ field: { onChange, value } }) => (
<InputOTP
maxLength={8}
value={value != null ? value : ''}
onChange={onChange}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
<InputOTPSlot index={6} />
<InputOTPSlot index={7} />
</InputOTPGroup>
</InputOTP>
)}
/>
{errors.backupCode && (
<span className="text-sm text-red-500">{errors.backupCode.message}</span>
)}
</div>
)}
<div className="flex items-center justify-between">
<button
type="submit"
aria-label={localize('com_auth_continue')}
data-testid="login-button"
disabled={isLoading}
className="w-full rounded-2xl bg-green-600 px-4 py-3 text-sm font-medium text-white transition-colors hover:bg-green-700 disabled:opacity-80 dark:bg-green-600 dark:hover:bg-green-700"
>
{isLoading ? localize('com_auth_email_verifying_ellipsis') : localize('com_ui_verify')}
</button>
</div>
<div className="mt-4 flex justify-center">
{!useBackup ? (
<button
type="button"
onClick={toggleBackupOn}
className="inline-flex p-1 text-sm font-medium text-green-600 transition-colors hover:text-green-700 dark:text-green-400 dark:hover:text-green-300"
>
{localize('com_ui_use_backup_code')}
</button>
) : (
<button
type="button"
onClick={toggleBackupOff}
className="inline-flex p-1 text-sm font-medium text-green-600 transition-colors hover:text-green-700 dark:text-green-400 dark:hover:text-green-300"
>
{localize('com_ui_use_2fa_code')}
</button>
)}
</div>
</form>
</div>
);
});
export default TwoFactorScreen;

View file

@ -4,3 +4,4 @@ export { default as ResetPassword } from './ResetPassword';
export { default as VerifyEmail } from './VerifyEmail';
export { default as ApiErrorWatcher } from './ApiErrorWatcher';
export { default as RequestPasswordReset } from './RequestPasswordReset';
export { default as TwoFactorScreen } from './TwoFactorScreen';

View file

@ -81,17 +81,25 @@ export default function AudioRecorder({
return (
<TooltipAnchor
id="audio-recorder"
aria-label={localize('com_ui_use_micrphone')}
onClick={isListening === true ? handleStopRecording : handleStartRecording}
disabled={disabled}
className={cn(
'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover',
isRTL ? 'bottom-2 left-2' : 'bottom-2 right-2',
)}
description={localize('com_ui_use_micrphone')}
>
{renderIcon()}
</TooltipAnchor>
render={
<button
id="audio-recorder"
type="button"
aria-label={localize('com_ui_use_micrphone')}
onClick={isListening === true ? handleStopRecording : handleStartRecording}
disabled={disabled}
className={cn(
'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover',
isRTL ? 'bottom-2 left-2' : 'bottom-2 right-2',
disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',
)}
title={localize('com_ui_use_micrphone')}
aria-pressed={isListening}
>
{renderIcon()}
</button>
}
/>
);
}

View file

@ -55,7 +55,7 @@ const FileUpload: React.FC<FileUploadProps> = ({
let statusText: string;
if (!status) {
statusText = text ?? localize('com_endpoint_import');
statusText = text ?? localize('com_ui_import');
} else if (status === 'success') {
statusText = successText ?? localize('com_ui_upload_success');
} else {
@ -72,12 +72,12 @@ const FileUpload: React.FC<FileUploadProps> = ({
)}
>
<FileUp className="mr-1 flex w-[22px] items-center stroke-1" />
<span className="flex text-xs ">{statusText}</span>
<span className="flex text-xs">{statusText}</span>
<input
id={`file-upload-${id}`}
value=""
type="file"
className={cn('hidden ', className)}
className={cn('hidden', className)}
accept=".json"
onChange={handleFileChange}
/>

View file

@ -1,8 +1,13 @@
import { useRecoilState } from 'recoil';
import { Settings2 } from 'lucide-react';
import { Root, Anchor } from '@radix-ui/react-popover';
import { useState, useEffect, useMemo } from 'react';
import { tConvoUpdateSchema, EModelEndpoint, isParamEndpoint } from 'librechat-data-provider';
import { Root, Anchor } from '@radix-ui/react-popover';
import {
EModelEndpoint,
isParamEndpoint,
isAgentsEndpoint,
tConvoUpdateSchema,
} from 'librechat-data-provider';
import type { TPreset, TInterfaceConfig } from 'librechat-data-provider';
import { EndpointSettings, SaveAsPresetDialog, AlternativeSettings } from '~/components/Endpoints';
import { PluginStoreDialog, TooltipAnchor } from '~/components';
@ -42,7 +47,6 @@ export default function HeaderOptions({
if (endpoint && noSettings[endpoint]) {
setShowPopover(false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [endpoint, noSettings]);
const saveAsPreset = () => {
@ -67,7 +71,7 @@ export default function HeaderOptions({
<div className="my-auto lg:max-w-2xl xl:max-w-3xl">
<span className="flex w-full flex-col items-center justify-center gap-0 md:order-none md:m-auto md:gap-2">
<div className="z-[61] flex w-full items-center justify-center gap-2">
{interfaceConfig?.modelSelect === true && (
{interfaceConfig?.modelSelect === true && !isAgentsEndpoint(endpoint) && (
<ModelSelect
conversation={conversation}
setOption={setOption}

View file

@ -87,7 +87,9 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
return localize('com_nav_welcome_agent');
}
return localize('com_nav_welcome_message');
return typeof startupConfig?.interface?.customWelcome === 'string'
? startupConfig?.interface?.customWelcome
: localize('com_nav_welcome_message');
};
return (
@ -118,10 +120,13 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
<div className="flex flex-col items-center gap-0 p-2">
<div className="text-center text-2xl font-medium dark:text-white">{name}</div>
<div className="max-w-md text-center text-sm font-normal text-text-primary ">
{description ? description : localize('com_nav_welcome_message')}
{description ||
(typeof startupConfig?.interface?.customWelcome === 'string'
? startupConfig?.interface?.customWelcome
: localize('com_nav_welcome_message'))}
</div>
{/* <div className="mt-1 flex items-center gap-1 text-token-text-tertiary">
<div className="text-sm text-token-text-tertiary">By Daniel Avila</div>
<div className="text-sm text-token-text-tertiary">By Daniel Avila</div>
</div> */}
</div>
) : (

View file

@ -109,7 +109,9 @@ const ContentParts = memo(
return val;
})
}
label={isSubmitting ? localize('com_ui_thinking') : localize('com_ui_thoughts')}
label={
isSubmitting && isLast ? localize('com_ui_thinking') : localize('com_ui_thoughts')
}
/>
</div>
)}

View file

@ -29,6 +29,7 @@ const Image = ({
height,
width,
placeholderDimensions,
className,
}: {
imagePath: string;
altText: string;
@ -38,6 +39,7 @@ const Image = ({
height?: string;
width?: string;
};
className?: string;
}) => {
const [isLoaded, setIsLoaded] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
@ -57,7 +59,12 @@ const Image = ({
return (
<Dialog.Root>
<div ref={containerRef}>
<div className="relative mt-1 flex h-auto w-full max-w-lg items-center justify-center overflow-hidden bg-gray-200 text-gray-500 dark:bg-gray-700 dark:text-gray-400">
<div
className={cn(
'relative mt-1 flex h-auto w-full max-w-lg items-center justify-center overflow-hidden bg-surface-active-alt text-text-secondary-alt',
className,
)}
>
<Dialog.Trigger asChild>
<button type="button" aria-haspopup="dialog" aria-expanded="false">
<LazyLoadImage

View file

@ -7,6 +7,7 @@ import { useRecoilValue } from 'recoil';
import ReactMarkdown from 'react-markdown';
import rehypeHighlight from 'rehype-highlight';
import remarkDirective from 'remark-directive';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
import type { Pluggable } from 'unified';
import {
useToastContext,
@ -17,6 +18,7 @@ import {
import { Artifact, artifactPlugin } from '~/components/Artifacts/Artifact';
import { langSubset, preprocessLaTeX, handleDoubleClick } from '~/utils';
import CodeBlock from '~/components/Messages/Content/CodeBlock';
import useHasAccess from '~/hooks/Roles/useHasAccess';
import { useFileDownload } from '~/data-provider';
import useLocalize from '~/hooks/useLocalize';
import store from '~/store';
@ -28,6 +30,10 @@ type TCodeProps = {
};
export const code: React.ElementType = memo(({ className, children }: TCodeProps) => {
const canRunCode = useHasAccess({
permissionType: PermissionTypes.RUN_CODE,
permission: Permissions.USE,
});
const match = /language-(\w+)/.exec(className ?? '');
const lang = match && match[1];
const isMath = lang === 'math';
@ -49,7 +55,14 @@ export const code: React.ElementType = memo(({ className, children }: TCodeProps
</code>
);
} else {
return <CodeBlock lang={lang ?? 'text'} codeChildren={children} blockIndex={blockIndex} />;
return (
<CodeBlock
lang={lang ?? 'text'}
codeChildren={children}
blockIndex={blockIndex}
allowExecution={canRunCode}
/>
);
}
});

View file

@ -12,7 +12,13 @@ export default function Attachment({ attachment }: { attachment?: TAttachment })
if (isImage) {
return (
<Image altText={attachment.filename} imagePath={filepath} height={height} width={width} />
<Image
altText={attachment.filename}
imagePath={filepath}
height={height}
width={width}
className="mb-4"
/>
);
}
return null;

View file

@ -121,7 +121,7 @@ function ConvoOptions({
setIsOpen={setIsPopoverActive}
trigger={
<Menu.MenuButton
id="conversation-menu-button"
id={`conversation-menu-${conversationId}`}
aria-label={localize('com_nav_convo_menu_options')}
className={cn(
'z-30 inline-flex h-7 w-7 items-center justify-center gap-2 rounded-md border-none p-0 text-sm font-medium ring-ring-primary transition-all duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',

View file

@ -80,7 +80,7 @@ function AccountSettings() {
!isNaN(parseFloat(balanceQuery.data)) && (
<>
<div className="text-token-text-secondary ml-3 mr-2 py-2 text-sm" role="note">
{localize('com_nav_balance')}: ${parseFloat(balanceQuery.data).toFixed(2)}
{localize('com_nav_balance')}: {parseFloat(balanceQuery.data).toFixed(2)}
</div>
<DropdownMenuSeparator />
</>

View file

@ -2,19 +2,36 @@ import React from 'react';
import DisplayUsernameMessages from './DisplayUsernameMessages';
import DeleteAccount from './DeleteAccount';
import Avatar from './Avatar';
import EnableTwoFactorItem from './TwoFactorAuthentication';
import BackupCodesItem from './BackupCodesItem';
import { useAuthContext } from '~/hooks';
function Account() {
const user = useAuthContext();
return (
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
<div className="pb-3">
<DisplayUsernameMessages />
</div>
<div className="pb-3">
<Avatar />
</div>
{user?.user?.provider === 'local' && (
<>
<div className="pb-3">
<EnableTwoFactorItem />
</div>
{Array.isArray(user.user?.backupCodes) && user.user?.backupCodes.length > 0 && (
<div className="pb-3">
<BackupCodesItem />
</div>
)}
</>
)}
<div className="pb-3">
<DeleteAccount />
</div>
<div className="pb-3">
<DisplayUsernameMessages />
</div>
</div>
);
}

View file

@ -47,7 +47,7 @@ function Avatar() {
const { mutate: uploadAvatar, isLoading: isUploading } = useUploadAvatarMutation({
onSuccess: (data) => {
showToast({ message: localize('com_ui_upload_success') });
setUser((prev) => ({ ...prev, avatar: data.url } as TUser));
setUser((prev) => ({ ...prev, avatar: data.url }) as TUser);
openButtonRef.current?.click();
},
onError: (error) => {
@ -133,9 +133,11 @@ function Avatar() {
>
<div className="flex items-center justify-between">
<span>{localize('com_nav_profile_picture')}</span>
<OGDialogTrigger ref={openButtonRef} className="btn btn-neutral relative">
<FileImage className="mr-2 flex w-[22px] items-center stroke-1" />
<span>{localize('com_nav_change_picture')}</span>
<OGDialogTrigger ref={openButtonRef}>
<Button variant="outline">
<FileImage className="mr-2 flex w-[22px] items-center stroke-1" />
<span>{localize('com_nav_change_picture')}</span>
</Button>
</OGDialogTrigger>
</div>

View file

@ -0,0 +1,194 @@
import React, { useState } from 'react';
import { RefreshCcw, ShieldX } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { TBackupCode, TRegenerateBackupCodesResponse, type TUser } from 'librechat-data-provider';
import {
OGDialog,
OGDialogContent,
OGDialogTitle,
OGDialogTrigger,
Button,
Label,
Spinner,
TooltipAnchor,
} from '~/components';
import { useRegenerateBackupCodesMutation } from '~/data-provider';
import { useAuthContext, useLocalize } from '~/hooks';
import { useToastContext } from '~/Providers';
import { useSetRecoilState } from 'recoil';
import store from '~/store';
const BackupCodesItem: React.FC = () => {
const localize = useLocalize();
const { user } = useAuthContext();
const { showToast } = useToastContext();
const setUser = useSetRecoilState(store.user);
const [isDialogOpen, setDialogOpen] = useState<boolean>(false);
const { mutate: regenerateBackupCodes, isLoading } = useRegenerateBackupCodesMutation();
const fetchBackupCodes = (auto: boolean = false) => {
regenerateBackupCodes(undefined, {
onSuccess: (data: TRegenerateBackupCodesResponse) => {
const newBackupCodes: TBackupCode[] = data.backupCodesHash.map((codeHash) => ({
codeHash,
used: false,
usedAt: null,
}));
setUser((prev) => ({ ...prev, backupCodes: newBackupCodes }) as TUser);
showToast({
message: localize('com_ui_backup_codes_regenerated'),
status: 'success',
});
// Trigger file download only when user explicitly clicks the button.
if (!auto && newBackupCodes.length) {
const codesString = data.backupCodes.join('\n');
const blob = new Blob([codesString], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'backup-codes.txt';
a.click();
URL.revokeObjectURL(url);
}
},
onError: () =>
showToast({
message: localize('com_ui_backup_codes_regenerate_error'),
status: 'error',
}),
});
};
const handleRegenerate = () => {
fetchBackupCodes(false);
};
return (
<OGDialog open={isDialogOpen} onOpenChange={setDialogOpen}>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<Label className="font-light">{localize('com_ui_backup_codes')}</Label>
</div>
<OGDialogTrigger asChild>
<Button aria-label="Show Backup Codes" variant="outline">
{localize('com_ui_show')}
</Button>
</OGDialogTrigger>
</div>
<OGDialogContent className="w-11/12 max-w-lg">
<OGDialogTitle className="mb-6 text-2xl font-semibold">
{localize('com_ui_backup_codes')}
</OGDialogTitle>
<AnimatePresence>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="mt-4"
>
{Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 ? (
<>
<div className="grid grid-cols-2 gap-4">
{user?.backupCodes.map((code, index) => {
const isUsed = code.used;
const description = `Backup code number ${index + 1}, ${
isUsed
? `used on ${code.usedAt ? new Date(code.usedAt).toLocaleDateString() : 'an unknown date'}`
: 'not used yet'
}`;
return (
<motion.div
key={code.codeHash}
role="listitem"
tabIndex={0}
aria-label={description}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.1 }}
onFocus={() => {
const announcement = new CustomEvent('announce', {
detail: { message: description },
});
document.dispatchEvent(announcement);
}}
className={`flex flex-col rounded-xl border p-4 backdrop-blur-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary ${
isUsed
? 'border-red-200 bg-red-50/80 dark:border-red-800 dark:bg-red-900/20'
: 'border-green-200 bg-green-50/80 dark:border-green-800 dark:bg-green-900/20'
} `}
>
<div className="flex items-center justify-between" aria-hidden="true">
<span className="text-sm font-medium text-text-secondary">
#{index + 1}
</span>
<TooltipAnchor
description={
code.usedAt ? new Date(code.usedAt).toLocaleDateString() : ''
}
disabled={!isUsed}
focusable={false}
className={isUsed ? 'cursor-pointer' : 'cursor-default'}
render={
<span
className={`rounded-full px-3 py-1 text-sm font-medium ${
isUsed
? 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300'
: 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300'
}`}
>
{isUsed ? localize('com_ui_used') : localize('com_ui_not_used')}
</span>
}
/>
</div>
</motion.div>
);
})}
</div>
<div className="mt-12 flex justify-center">
<Button
onClick={handleRegenerate}
disabled={isLoading}
variant="default"
className="px-8 py-3 transition-all disabled:opacity-50"
>
{isLoading ? (
<Spinner className="mr-2" />
) : (
<RefreshCcw className="mr-2 h-4 w-4" />
)}
{isLoading
? localize('com_ui_regenerating')
: localize('com_ui_regenerate_backup')}
</Button>
</div>
</>
) : (
<div className="flex flex-col items-center gap-4 p-6 text-center">
<ShieldX className="h-12 w-12 text-text-primary" />
<p className="text-lg text-text-secondary">{localize('com_ui_no_backup_codes')}</p>
<Button
onClick={handleRegenerate}
disabled={isLoading}
variant="default"
className="px-8 py-3 transition-all disabled:opacity-50"
>
{isLoading && <Spinner className="mr-2" />}
{localize('com_ui_generate_backup')}
</Button>
</div>
)}
</motion.div>
</AnimatePresence>
</OGDialogContent>
</OGDialog>
);
};
export default React.memo(BackupCodesItem);

View file

@ -57,7 +57,7 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
</Button>
</OGDialogTrigger>
</div>
<OGDialogContent className="w-11/12 max-w-2xl">
<OGDialogContent className="w-11/12 max-w-md">
<OGDialogHeader>
<OGDialogTitle className="text-lg font-medium leading-6">
{localize('com_nav_delete_account_confirm')}

View file

@ -0,0 +1,36 @@
import React from 'react';
import { motion } from 'framer-motion';
import { LockIcon, UnlockIcon } from 'lucide-react';
import { Label, Button } from '~/components';
import { useLocalize } from '~/hooks';
interface DisableTwoFactorToggleProps {
enabled: boolean;
onChange: () => void;
disabled?: boolean;
}
export const DisableTwoFactorToggle: React.FC<DisableTwoFactorToggleProps> = ({
enabled,
onChange,
disabled,
}) => {
const localize = useLocalize();
return (
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<Label className="font-light"> {localize('com_nav_2fa')}</Label>
</div>
<div className="flex items-center gap-3">
<Button
variant={enabled ? 'destructive' : 'outline'}
onClick={onChange}
disabled={disabled}
>
{enabled ? localize('com_ui_2fa_disable') : localize('com_ui_2fa_enable')}
</Button>
</div>
</div>
);
};

View file

@ -0,0 +1,298 @@
import React, { useCallback, useState } from 'react';
import { useSetRecoilState } from 'recoil';
import { SmartphoneIcon } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import type { TUser, TVerify2FARequest } from 'librechat-data-provider';
import { OGDialog, OGDialogContent, OGDialogHeader, OGDialogTitle, Progress } from '~/components';
import { SetupPhase, QRPhase, VerifyPhase, BackupPhase, DisablePhase } from './TwoFactorPhases';
import { DisableTwoFactorToggle } from './DisableTwoFactorToggle';
import { useAuthContext, useLocalize } from '~/hooks';
import { useToastContext } from '~/Providers';
import store from '~/store';
import {
useConfirmTwoFactorMutation,
useDisableTwoFactorMutation,
useEnableTwoFactorMutation,
useVerifyTwoFactorMutation,
} from '~/data-provider';
export type Phase = 'setup' | 'qr' | 'verify' | 'backup' | 'disable';
const phaseVariants = {
initial: { opacity: 0, scale: 0.95 },
animate: { opacity: 1, scale: 1, transition: { duration: 0.3, ease: 'easeOut' } },
exit: { opacity: 0, scale: 0.95, transition: { duration: 0.3, ease: 'easeIn' } },
};
const TwoFactorAuthentication: React.FC = () => {
const localize = useLocalize();
const { user } = useAuthContext();
const setUser = useSetRecoilState(store.user);
const { showToast } = useToastContext();
const [secret, setSecret] = useState<string>('');
const [otpauthUrl, setOtpauthUrl] = useState<string>('');
const [downloaded, setDownloaded] = useState<boolean>(false);
const [disableToken, setDisableToken] = useState<string>('');
const [backupCodes, setBackupCodes] = useState<string[]>([]);
const [isDialogOpen, setDialogOpen] = useState<boolean>(false);
const [verificationToken, setVerificationToken] = useState<string>('');
const [phase, setPhase] = useState<Phase>(Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 ? 'disable' : 'setup');
const { mutate: confirm2FAMutate } = useConfirmTwoFactorMutation();
const { mutate: enable2FAMutate, isLoading: isGenerating } = useEnableTwoFactorMutation();
const { mutate: verify2FAMutate, isLoading: isVerifying } = useVerifyTwoFactorMutation();
const { mutate: disable2FAMutate, isLoading: isDisabling } = useDisableTwoFactorMutation();
const steps = ['Setup', 'Scan QR', 'Verify', 'Backup'];
const phasesLabel: Record<Phase, string> = {
setup: 'Setup',
qr: 'Scan QR',
verify: 'Verify',
backup: 'Backup',
disable: '',
};
const currentStep = steps.indexOf(phasesLabel[phase]);
const resetState = useCallback(() => {
if (Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 && otpauthUrl) {
disable2FAMutate(undefined, {
onError: () =>
showToast({ message: localize('com_ui_2fa_disable_error'), status: 'error' }),
});
}
setOtpauthUrl('');
setSecret('');
setBackupCodes([]);
setVerificationToken('');
setDisableToken('');
setPhase(Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 ? 'disable' : 'setup');
setDownloaded(false);
}, [user, otpauthUrl, disable2FAMutate, localize, showToast]);
const handleGenerateQRCode = useCallback(() => {
enable2FAMutate(undefined, {
onSuccess: ({ otpauthUrl, backupCodes }) => {
setOtpauthUrl(otpauthUrl);
setSecret(otpauthUrl.split('secret=')[1].split('&')[0]);
setBackupCodes(backupCodes);
setPhase('qr');
},
onError: () => showToast({ message: localize('com_ui_2fa_generate_error'), status: 'error' }),
});
}, [enable2FAMutate, localize, showToast]);
const handleVerify = useCallback(() => {
if (!verificationToken) {
return;
}
verify2FAMutate(
{ token: verificationToken },
{
onSuccess: () => {
showToast({ message: localize('com_ui_2fa_verified') });
confirm2FAMutate(
{ token: verificationToken },
{
onSuccess: () => setPhase('backup'),
onError: () =>
showToast({ message: localize('com_ui_2fa_invalid'), status: 'error' }),
},
);
},
onError: () => showToast({ message: localize('com_ui_2fa_invalid'), status: 'error' }),
},
);
}, [verificationToken, verify2FAMutate, confirm2FAMutate, localize, showToast]);
const handleDownload = useCallback(() => {
if (!backupCodes.length) {
return;
}
const blob = new Blob([backupCodes.join('\n')], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'backup-codes.txt';
a.click();
URL.revokeObjectURL(url);
setDownloaded(true);
}, [backupCodes]);
const handleConfirm = useCallback(() => {
setDialogOpen(false);
setPhase('disable');
showToast({ message: localize('com_ui_2fa_enabled') });
setUser(
(prev) =>
({
...prev,
backupCodes: backupCodes.map((code) => ({
code,
codeHash: code,
used: false,
usedAt: null,
})),
}) as TUser,
);
}, [setUser, localize, showToast, backupCodes]);
const handleDisableVerify = useCallback(
(token: string, useBackup: boolean) => {
// Validate: if not using backup, ensure token has at least 6 digits;
// if using backup, ensure backup code has at least 8 characters.
if (!useBackup && token.trim().length < 6) {
return;
}
if (useBackup && token.trim().length < 8) {
return;
}
const payload: TVerify2FARequest = {};
if (useBackup) {
payload.backupCode = token.trim();
} else {
payload.token = token.trim();
}
verify2FAMutate(payload, {
onSuccess: () => {
disable2FAMutate(undefined, {
onSuccess: () => {
showToast({ message: localize('com_ui_2fa_disabled') });
setDialogOpen(false);
setUser(
(prev) =>
({
...prev,
totpSecret: '',
backupCodes: [],
}) as TUser,
);
setPhase('setup');
setOtpauthUrl('');
},
onError: () =>
showToast({ message: localize('com_ui_2fa_disable_error'), status: 'error' }),
});
},
onError: () => showToast({ message: localize('com_ui_2fa_invalid'), status: 'error' }),
});
},
[disableToken, verify2FAMutate, disable2FAMutate, showToast, localize, setUser],
);
return (
<OGDialog
open={isDialogOpen}
onOpenChange={(open) => {
setDialogOpen(open);
if (!open) {
resetState();
}
}}
>
<DisableTwoFactorToggle
enabled={Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0}
onChange={() => setDialogOpen(true)}
disabled={isVerifying || isDisabling || isGenerating}
/>
<OGDialogContent className="w-11/12 max-w-lg p-6">
<AnimatePresence mode="wait">
<motion.div
key={phase}
variants={phaseVariants}
initial="initial"
animate="animate"
exit="exit"
className="space-y-6"
>
<OGDialogHeader>
<OGDialogTitle className="mb-2 flex items-center gap-3 text-2xl font-bold">
<SmartphoneIcon className="h-6 w-6 text-primary" />
{Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 ? localize('com_ui_2fa_disable') : localize('com_ui_2fa_setup')}
</OGDialogTitle>
{Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0 && phase !== 'disable' && (
<div className="mt-4 space-y-3">
<Progress
value={(steps.indexOf(phasesLabel[phase]) / (steps.length - 1)) * 100}
className="h-2 rounded-full"
/>
<div className="flex justify-between text-sm">
{steps.map((step, index) => (
<motion.span
key={step}
animate={{
color:
currentStep >= index ? 'var(--text-primary)' : 'var(--text-tertiary)',
}}
className="font-medium"
>
{step}
</motion.span>
))}
</div>
</div>
)}
</OGDialogHeader>
<AnimatePresence mode="wait">
{phase === 'setup' && (
<SetupPhase
isGenerating={isGenerating}
onGenerate={handleGenerateQRCode}
onNext={() => setPhase('qr')}
onError={(error) => showToast({ message: error.message, status: 'error' })}
/>
)}
{phase === 'qr' && (
<QRPhase
secret={secret}
otpauthUrl={otpauthUrl}
onNext={() => setPhase('verify')}
onError={(error) => showToast({ message: error.message, status: 'error' })}
/>
)}
{phase === 'verify' && (
<VerifyPhase
token={verificationToken}
onTokenChange={setVerificationToken}
isVerifying={isVerifying}
onNext={handleVerify}
onError={(error) => showToast({ message: error.message, status: 'error' })}
/>
)}
{phase === 'backup' && (
<BackupPhase
backupCodes={backupCodes}
onDownload={handleDownload}
downloaded={downloaded}
onNext={handleConfirm}
onError={(error) => showToast({ message: error.message, status: 'error' })}
/>
)}
{phase === 'disable' && (
<DisablePhase
onDisable={handleDisableVerify}
isDisabling={isDisabling}
onError={(error) => showToast({ message: error.message, status: 'error' })}
/>
)}
</AnimatePresence>
</motion.div>
</AnimatePresence>
</OGDialogContent>
</OGDialog>
);
};
export default React.memo(TwoFactorAuthentication);

View file

@ -0,0 +1,60 @@
import React from 'react';
import { motion } from 'framer-motion';
import { Download } from 'lucide-react';
import { Button, Label } from '~/components';
import { useLocalize } from '~/hooks';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface BackupPhaseProps {
onNext: () => void;
onError: (error: Error) => void;
backupCodes: string[];
onDownload: () => void;
downloaded: boolean;
}
export const BackupPhase: React.FC<BackupPhaseProps> = ({
backupCodes,
onDownload,
downloaded,
onNext,
}) => {
const localize = useLocalize();
return (
<motion.div {...fadeAnimation} className="space-y-6">
<Label className="break-keep text-sm">{localize('com_ui_download_backup_tooltip')}</Label>
<div className="grid grid-cols-2 gap-4 rounded-xl bg-surface-secondary p-6">
{backupCodes.map((code, index) => (
<motion.div
key={code}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.1 }}
className="rounded-lg bg-surface-tertiary p-3"
>
<div className="flex items-center justify-between">
<span className="hidden text-sm text-text-secondary sm:inline">#{index + 1}</span>
<span className="font-mono text-lg">{code}</span>
</div>
</motion.div>
))}
</div>
<div className="flex gap-4">
<Button variant="outline" onClick={onDownload} className="flex-1 gap-2">
<Download className="h-4 w-4" />
<span className="hidden sm:inline">{localize('com_ui_download_backup')}</span>
</Button>
<Button onClick={onNext} disabled={!downloaded} className="flex-1">
{localize('com_ui_complete_setup')}
</Button>
</div>
</motion.div>
);
};

View file

@ -0,0 +1,88 @@
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
import {
Button,
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator,
Spinner,
} from '~/components';
import { useLocalize } from '~/hooks';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface DisablePhaseProps {
onSuccess?: () => void;
onError?: (error: Error) => void;
onDisable: (token: string, useBackup: boolean) => void;
isDisabling: boolean;
}
export const DisablePhase: React.FC<DisablePhaseProps> = ({ onDisable, isDisabling }) => {
const localize = useLocalize();
const [token, setToken] = useState('');
const [useBackup, setUseBackup] = useState(false);
return (
<motion.div {...fadeAnimation} className="space-y-8">
<div className="flex justify-center">
<InputOTP
value={token}
onChange={setToken}
maxLength={useBackup ? 8 : 6}
pattern={useBackup ? REGEXP_ONLY_DIGITS_AND_CHARS : REGEXP_ONLY_DIGITS}
className="gap-2"
>
{useBackup ? (
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
<InputOTPSlot index={6} />
<InputOTPSlot index={7} />
</InputOTPGroup>
) : (
<>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</>
)}
</InputOTP>
</div>
<Button
variant="destructive"
onClick={() => onDisable(token, useBackup)}
disabled={isDisabling || token.length !== (useBackup ? 8 : 6)}
className="w-full rounded-xl px-6 py-3 transition-all disabled:opacity-50"
>
{isDisabling === true && <Spinner className="mr-2" />}
{isDisabling ? localize('com_ui_disabling') : localize('com_ui_2fa_disable')}
</Button>
<button
onClick={() => setUseBackup(!useBackup)}
className="text-sm text-primary hover:underline"
>
{useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
</button>
</motion.div>
);
};

View file

@ -0,0 +1,66 @@
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { QRCodeSVG } from 'qrcode.react';
import { Copy, Check } from 'lucide-react';
import { Input, Button, Label } from '~/components';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface QRPhaseProps {
secret: string;
otpauthUrl: string;
onNext: () => void;
onSuccess?: () => void;
onError?: (error: Error) => void;
}
export const QRPhase: React.FC<QRPhaseProps> = ({ secret, otpauthUrl, onNext }) => {
const localize = useLocalize();
const [isCopying, setIsCopying] = useState(false);
const handleCopy = async () => {
await navigator.clipboard.writeText(secret);
setIsCopying(true);
setTimeout(() => setIsCopying(false), 2000);
};
return (
<motion.div {...fadeAnimation} className="space-y-6">
<div className="flex flex-col items-center space-y-6">
<motion.div
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
className="rounded-2xl bg-white p-4 shadow-lg"
>
<QRCodeSVG value={otpauthUrl} size={240} />
</motion.div>
<div className="w-full space-y-3">
<Label className="text-sm font-medium text-text-secondary">
{localize('com_ui_secret_key')}
</Label>
<div className="flex gap-2">
<Input value={secret} readOnly className="font-mono text-lg tracking-wider" />
<Button
size="sm"
variant="outline"
onClick={handleCopy}
className={cn('h-auto shrink-0', isCopying ? 'cursor-default' : '')}
>
{isCopying ? <Check className="size-4" /> : <Copy className="size-4" />}
</Button>
</div>
</div>
</div>
<Button onClick={onNext} className="w-full">
{localize('com_ui_continue')}
</Button>
</motion.div>
);
};

View file

@ -0,0 +1,42 @@
import React from 'react';
import { QrCode } from 'lucide-react';
import { motion } from 'framer-motion';
import { Button, Spinner } from '~/components';
import { useLocalize } from '~/hooks';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface SetupPhaseProps {
onNext: () => void;
onError: (error: Error) => void;
isGenerating: boolean;
onGenerate: () => void;
}
export const SetupPhase: React.FC<SetupPhaseProps> = ({ isGenerating, onGenerate, onNext }) => {
const localize = useLocalize();
return (
<motion.div {...fadeAnimation} className="space-y-6">
<div className="rounded-xl bg-surface-secondary p-6">
<h3 className="mb-4 flex justify-center text-lg font-medium">
{localize('com_ui_2fa_account_security')}
</h3>
<Button
variant="default"
onClick={onGenerate}
className="flex w-full"
disabled={isGenerating}
>
{isGenerating ? <Spinner className="size-5" /> : <QrCode className="size-5" />}
{isGenerating ? localize('com_ui_generating') : localize('com_ui_generate_qrcode')}
</Button>
</div>
</motion.div>
);
};

View file

@ -0,0 +1,58 @@
import React from 'react';
import { motion } from 'framer-motion';
import { Button, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from '~/components';
import { REGEXP_ONLY_DIGITS } from 'input-otp';
import { useLocalize } from '~/hooks';
const fadeAnimation = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
transition: { duration: 0.2 },
};
interface VerifyPhaseProps {
token: string;
onTokenChange: (value: string) => void;
isVerifying: boolean;
onNext: () => void;
onError: (error: Error) => void;
}
export const VerifyPhase: React.FC<VerifyPhaseProps> = ({
token,
onTokenChange,
isVerifying,
onNext,
}) => {
const localize = useLocalize();
return (
<motion.div {...fadeAnimation} className="space-y-8">
<div className="flex justify-center">
<InputOTP
value={token}
onChange={onTokenChange}
maxLength={6}
pattern={REGEXP_ONLY_DIGITS}
className="gap-2"
>
<InputOTPGroup>
{Array.from({ length: 3 }).map((_, i) => (
<InputOTPSlot key={i} index={i} />
))}
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
{Array.from({ length: 3 }).map((_, i) => (
<InputOTPSlot key={i + 3} index={i + 3} />
))}
</InputOTPGroup>
</InputOTP>
</div>
<Button onClick={onNext} disabled={isVerifying || token.length !== 6} className="w-full">
{localize('com_ui_verify')}
</Button>
</motion.div>
);
};

View file

@ -0,0 +1,5 @@
export * from './BackupPhase';
export * from './QRPhase';
export * from './VerifyPhase';
export * from './SetupPhase';
export * from './DisablePhase';

View file

@ -82,7 +82,7 @@ function ImportConversations() {
onClick={handleImportClick}
onKeyDown={handleKeyDown}
disabled={!allowImport}
aria-label={localize('com_ui_import_conversation')}
aria-label={localize('com_ui_import')}
className="btn btn-neutral relative"
>
{allowImport ? (
@ -90,7 +90,7 @@ function ImportConversations() {
) : (
<Spinner className="mr-1 w-4" />
)}
<span>{localize('com_ui_import_conversation')}</span>
<span>{localize('com_ui_import')}</span>
</button>
<input
ref={fileInputRef}

View file

@ -270,9 +270,7 @@ export default function SharedLinks() {
<OGDialog open={isOpen} onOpenChange={setIsOpen}>
<OGDialogTrigger asChild onClick={() => setIsOpen(true)}>
<button className="btn btn-neutral relative">
{localize('com_nav_shared_links_manage')}
</button>
<Button variant="outline">{localize('com_ui_manage')}</Button>
</OGDialogTrigger>
<OGDialogContent

View file

@ -12,7 +12,7 @@ export default function ArchivedChats() {
<OGDialog>
<OGDialogTrigger asChild>
<Button variant="outline" aria-label="Archived chats">
{localize('com_nav_archived_chats_manage')}
{localize('com_ui_manage')}
</Button>
</OGDialogTrigger>
<OGDialogTemplate

View file

@ -64,6 +64,7 @@ export const LangSelector = ({
{ value: 'pt-PT', label: localize('com_nav_lang_portuguese') },
{ value: 'ru-RU', label: localize('com_nav_lang_russian') },
{ value: 'ja-JP', label: localize('com_nav_lang_japanese') },
{ value: 'ka-GE', label: localize('com_nav_lang_georgian') },
{ value: 'sv-SE', label: localize('com_nav_lang_swedish') },
{ value: 'ko-KR', label: localize('com_nav_lang_korean') },
{ value: 'vi-VN', label: localize('com_nav_lang_vietnamese') },

View file

@ -44,7 +44,7 @@ const Command = ({
}
return (
<div className="rounded-xl border border-border-light">
<div className="rounded-xl border border-border-light shadow-md">
<h3 className="flex h-10 items-center gap-1 pl-4 text-sm text-text-secondary">
<SquareSlash className="icon-sm" aria-hidden="true" />
<Input

View file

@ -41,7 +41,7 @@ const Description = ({
}
return (
<div className="rounded-xl border border-border-light">
<div className="rounded-xl border border-border-light shadow-md">
<h3 className="flex h-10 items-center gap-1 pl-4 text-sm text-text-secondary">
<Info className="icon-sm" aria-hidden="true" />
<Input

View file

@ -32,7 +32,7 @@ export default function List({
<div className="flex w-full justify-end">
<Button
variant="outline"
className="w-full bg-transparent px-3"
className={`w-full bg-transparent ${isChatRoute ? '' : 'mx-2'}`}
onClick={() => navigate('/d/prompts/new')}
>
<Plus className="size-4" aria-hidden />

View file

@ -81,7 +81,7 @@ const PromptEditor: React.FC<Props> = ({ name, isEditing, setIsEditing }) => {
<div
role="button"
className={cn(
'w-full flex-1 overflow-auto rounded-b-xl border border-border-light p-2 transition-all duration-150 sm:p-4',
'w-full flex-1 overflow-auto rounded-b-xl border border-border-light p-2 shadow-md transition-all duration-150 sm:p-4',
{
'cursor-pointer bg-surface-primary hover:bg-surface-secondary active:bg-surface-tertiary':
!isEditing,
@ -105,6 +105,7 @@ const PromptEditor: React.FC<Props> = ({ name, isEditing, setIsEditing }) => {
isEditing ? (
<TextareaAutosize
{...field}
autoFocus
className="w-full resize-none overflow-y-auto rounded bg-transparent text-sm text-text-primary focus:outline-none sm:text-base"
minRows={3}
maxRows={14}

View file

@ -237,7 +237,6 @@ const PromptForm = () => {
payload: { name: groupName, category: value },
})
}
className="w-full"
/>
<div className="mt-2 flex flex-row items-center justify-center gap-x-2 lg:mt-0">
{hasShareAccess && <SharePrompt group={group} disabled={isLoadingGroup} />}
@ -349,7 +348,7 @@ const PromptForm = () => {
{isLoadingPrompts ? (
<Skeleton className="h-96" aria-live="polite" />
) : (
<div className="flex h-full flex-col gap-4">
<div className="mb-2 flex h-full flex-col gap-4">
<PromptEditor name="prompt" isEditing={isEditing} setIsEditing={setIsEditing} />
<PromptVariables promptText={promptText} />
<Description

View file

@ -28,7 +28,7 @@ const PromptVariables = ({
}, [promptText]);
return (
<div className="rounded-xl border border-border-light bg-transparent p-4 shadow-md ">
<div className="rounded-xl border border-border-light bg-transparent p-4 shadow-md">
<h3 className="flex items-center gap-2 py-2 text-lg font-semibold text-text-primary">
<Variable className="icon-sm" aria-hidden="true" />
{localize('com_ui_variables')}
@ -71,7 +71,7 @@ const PromptVariables = ({
</span>
</div>
<div>
<span className="text-text-text-primary text-sm font-medium">
<span className="text-sm font-medium text-text-primary">
{localize('com_ui_dropdown_variables')}
</span>
<span className="text-sm text-text-secondary">

View file

@ -74,6 +74,7 @@ export default function AgentSwitcher({ isCollapsed }: SwitcherProps) {
ariaLabel={'agent'}
setValue={onSelect}
items={agentOptions}
iconClassName="assistant-item"
SelectIcon={
<Icon
isCreatedByUser={false}

View file

@ -1,6 +1,7 @@
import { Plus } from 'lucide-react';
import React, { useMemo, useCallback } from 'react';
import { useWatch, useForm, FormProvider } from 'react-hook-form';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import { Controller, useWatch, useForm, FormProvider } from 'react-hook-form';
import {
Tools,
SystemRoles,
@ -200,10 +201,6 @@ export default function AgentPanel({
user?.role,
]);
if (agentQuery.isInitialLoading) {
return <AgentPanelSkeleton />;
}
return (
<FormProvider {...methods}>
<form
@ -211,37 +208,53 @@ export default function AgentPanel({
className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden"
aria-label="Agent configuration form"
>
<div className="mt-2 flex w-full flex-wrap gap-2">
<Controller
name="agent"
control={control}
render={({ field }) => (
<AgentSelect
reset={reset}
value={field.value}
agentQuery={agentQuery}
setCurrentAgentId={setCurrentAgentId}
selectedAgentId={current_agent_id ?? null}
createMutation={create}
/>
)}
/>
{/* Select Button */}
<div className="mx-1 mt-2 flex w-full flex-wrap gap-2">
<div className="w-full">
<AgentSelect
createMutation={create}
agentQuery={agentQuery}
setCurrentAgentId={setCurrentAgentId}
// The following is required to force re-render the component when the form's agent ID changes
// Also maintains ComboBox Focus for Accessibility
selectedAgentId={agentQuery.isInitialLoading ? null : (current_agent_id ?? null)}
/>
</div>
{/* Create + Select Button */}
{agent_id && (
<Button
variant="submit"
disabled={!agent_id}
onClick={(e) => {
e.preventDefault();
handleSelectAgent();
}}
aria-label="Select agent"
>
{localize('com_ui_select')}
</Button>
<div className="flex w-full gap-2">
<Button
type="button"
variant="outline"
className="w-full justify-center"
onClick={() => {
reset(defaultAgentFormValues);
setCurrentAgentId(undefined);
}}
disabled={agentQuery.isInitialLoading}
>
<Plus className="mr-1 h-4 w-4" />
{localize('com_ui_create') +
' ' +
localize('com_ui_new') +
' ' +
localize('com_ui_agent')}
</Button>
<Button
variant="submit"
disabled={!agent_id || agentQuery.isInitialLoading}
onClick={(e) => {
e.preventDefault();
handleSelectAgent();
}}
aria-label={localize('com_ui_select') + ' ' + localize('com_ui_agent')}
>
{localize('com_ui_select')}
</Button>
</div>
)}
</div>
{!canEditAgent && (
{agentQuery.isInitialLoading && <AgentPanelSkeleton />}
{!canEditAgent && !agentQuery.isInitialLoading && (
<div className="flex h-[30vh] w-full items-center justify-center">
<div className="text-center">
<h2 className="text-token-text-primary m-2 text-xl font-semibold">
@ -251,7 +264,7 @@ export default function AgentPanel({
</div>
</div>
)}
{canEditAgent && activePanel === Panel.model && (
{canEditAgent && !agentQuery.isInitialLoading && activePanel === Panel.model && (
<ModelPanel
setActivePanel={setActivePanel}
agent_id={agent_id}
@ -259,7 +272,7 @@ export default function AgentPanel({
models={models}
/>
)}
{canEditAgent && activePanel === Panel.builder && (
{canEditAgent && !agentQuery.isInitialLoading && activePanel === Panel.builder && (
<AgentConfig
actions={actions}
setAction={setAction}

View file

@ -3,75 +3,67 @@ import { Skeleton } from '~/components/ui';
export default function AgentPanelSkeleton() {
return (
<div className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden">
{/* Agent Select and Button */}
<div className="mt-1 flex w-full gap-2">
<Skeleton className="h-[40px] w-4/5 rounded-lg" />
<Skeleton className="h-[40px] w-1/5 rounded-lg" />
<div className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent">
{/* Avatar */}
<div className="mb-4">
<div className="flex w-full items-center justify-center gap-4">
<Skeleton className="relative h-20 w-20 rounded-full" />
</div>
{/* Name */}
<Skeleton className="mb-2 h-5 w-1/5 rounded-lg" />
<Skeleton className="mb-1 h-[40px] w-full rounded-lg" />
<Skeleton className="h-3 w-1/4 rounded-lg" />
</div>
<div className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent">
{/* Avatar */}
<div className="mb-4">
<div className="flex w-full items-center justify-center gap-4">
<Skeleton className="relative h-20 w-20 rounded-full" />
</div>
{/* Name */}
<Skeleton className="mb-2 h-5 w-1/5 rounded-lg" />
<Skeleton className="mb-1 h-[40px] w-full rounded-lg" />
<Skeleton className="h-3 w-1/4 rounded-lg" />
</div>
{/* Description */}
<div className="mb-4">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[40px] w-full rounded-lg" />
</div>
{/* Description */}
<div className="mb-4">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[40px] w-full rounded-lg" />
</div>
{/* Instructions */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[100px] w-full rounded-lg" />
</div>
{/* Instructions */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[100px] w-full rounded-lg" />
</div>
{/* Model and Provider */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[40px] w-full rounded-lg" />
</div>
{/* Model and Provider */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="h-[40px] w-full rounded-lg" />
</div>
{/* Capabilities */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="mb-2 h-5 w-36 rounded-lg" />
<Skeleton className="mb-4 h-[35px] w-full rounded-lg" />
<Skeleton className="mb-2 h-5 w-24 rounded-lg" />
<Skeleton className="h-[35px] w-full rounded-lg" />
</div>
{/* Capabilities */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="mb-2 h-5 w-36 rounded-lg" />
<Skeleton className="mb-4 h-[35px] w-full rounded-lg" />
<Skeleton className="mb-2 h-5 w-24 rounded-lg" />
<Skeleton className="h-[35px] w-full rounded-lg" />
{/* Tools & Actions */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="mb-2 h-[35px] w-full rounded-lg" />
<Skeleton className="mb-2 h-[35px] w-full rounded-lg" />
<div className="flex space-x-2">
<Skeleton className="h-8 w-1/2 rounded-lg" />
<Skeleton className="h-8 w-1/2 rounded-lg" />
</div>
</div>
{/* Tools & Actions */}
<div className="mb-6">
<Skeleton className="mb-2 h-5 w-1/4 rounded-lg" />
<Skeleton className="mb-2 h-[35px] w-full rounded-lg" />
<Skeleton className="mb-2 h-[35px] w-full rounded-lg" />
<div className="flex space-x-2">
<Skeleton className="h-8 w-1/2 rounded-lg" />
<Skeleton className="h-8 w-1/2 rounded-lg" />
</div>
</div>
{/* Admin Settings */}
<div className="mb-6">
<Skeleton className="h-[35px] w-full rounded-lg" />
</div>
{/* Admin Settings */}
<div className="mb-6">
<Skeleton className="h-[35px] w-full rounded-lg" />
</div>
{/* Bottom Buttons */}
<div className="flex items-center justify-end gap-2">
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-full rounded-lg" />
</div>
{/* Bottom Buttons */}
<div className="flex items-center justify-end gap-2">
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-16 rounded-lg" />
<Skeleton className="h-[35px] w-full rounded-lg" />
</div>
</div>
);

View file

@ -1,27 +1,23 @@
import { Plus, EarthIcon } from 'lucide-react';
import { EarthIcon } from 'lucide-react';
import { useCallback, useEffect, useRef } from 'react';
import { useFormContext, Controller } from 'react-hook-form';
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
import type { UseFormReset } from 'react-hook-form';
import type { TAgentCapabilities, AgentForm, TAgentOption } from '~/common';
import { cn, createDropdownSetter, createProviderOption, processAgentOption } from '~/utils';
import type { TAgentCapabilities, AgentForm } from '~/common';
import { useListAgentsQuery, useGetStartupConfig } from '~/data-provider';
import SelectDropDown from '~/components/ui/SelectDropDown';
import { cn, createProviderOption, processAgentOption } from '~/utils';
import ControlCombobox from '~/components/ui/ControlCombobox';
import { useLocalize } from '~/hooks';
const keys = new Set(Object.keys(defaultAgentFormValues));
export default function AgentSelect({
reset,
agentQuery,
value: currentAgentValue,
selectedAgentId = null,
setCurrentAgentId,
createMutation,
}: {
reset: UseFormReset<AgentForm>;
value?: TAgentOption;
selectedAgentId: string | null;
agentQuery: QueryObserverResult<Agent>;
setCurrentAgentId: React.Dispatch<React.SetStateAction<string | undefined>>;
@ -29,6 +25,7 @@ export default function AgentSelect({
}) {
const localize = useLocalize();
const lastSelectedAgent = useRef<string | null>(null);
const { control, reset } = useFormContext();
const { data: startupConfig } = useGetStartupConfig();
const { data: agents = null } = useListAgentsQuery(undefined, {
@ -152,50 +149,40 @@ export default function AgentSelect({
}, [selectedAgentId, agents, onSelect]);
const createAgent = localize('com_ui_create') + ' ' + localize('com_ui_agent');
const hasAgentValue = !!(typeof currentAgentValue === 'object'
? currentAgentValue.value != null && currentAgentValue.value !== ''
: typeof currentAgentValue !== 'undefined');
return (
<SelectDropDown
value={!hasAgentValue ? createAgent : (currentAgentValue as TAgentOption)}
setValue={createDropdownSetter(onSelect)}
availableValues={
agents ?? [
{
label: 'Loading...',
value: '',
},
]
}
iconSide="left"
optionIconSide="right"
showAbove={false}
showLabel={false}
emptyTitle={true}
showOptionIcon={true}
containerClassName="flex-grow"
searchClassName="dark:from-gray-850"
searchPlaceholder={localize('com_agents_search_name')}
optionsClass="hover:bg-gray-20/50 dark:border-gray-700"
optionsListClass="rounded-lg shadow-lg dark:bg-gray-850 dark:border-gray-700 dark:last:border"
currentValueClass={cn(
'text-md font-semibold text-gray-900 dark:text-white',
hasAgentValue ? 'text-gray-500' : '',
)}
className={cn(
'rounded-md dark:border-gray-700 dark:bg-gray-850',
'z-50 flex h-[40px] w-full flex-none items-center justify-center truncate px-4 hover:cursor-pointer hover:border-green-500 focus:border-gray-400',
)}
renderOption={() => (
<span className="flex items-center gap-1.5 truncate">
<span className="absolute inset-y-0 left-0 flex items-center pl-2 text-gray-800 dark:text-gray-100">
<Plus className="w-[16px]" />
</span>
<span className={cn('ml-4 flex h-6 items-center gap-1 text-gray-800 dark:text-gray-100')}>
{createAgent}
</span>
</span>
<Controller
name="agent"
control={control}
render={({ field }) => (
<ControlCombobox
containerClassName="px-0"
selectedValue={(field?.value?.value ?? '') + ''}
displayValue={field?.value?.label ?? ''}
selectPlaceholder={createAgent}
iconSide="right"
searchPlaceholder={localize('com_agents_search_name')}
SelectIcon={field?.value?.icon}
setValue={onSelect}
items={
agents?.map((agent) => ({
label: agent.name ?? '',
value: agent.id ?? '',
icon: agent.icon,
})) ?? [
{
label: 'Loading...',
value: '',
},
]
}
className={cn(
'z-50 flex h-[40px] w-full flex-none items-center justify-center truncate rounded-md bg-transparent font-bold',
)}
ariaLabel={localize('com_ui_agent')}
isCollapsed={false}
showCarat={true}
/>
)}
/>
);

View file

@ -1,14 +1,14 @@
import React, { useMemo, useEffect } from 'react';
import { ChevronLeft, RotateCcw } from 'lucide-react';
import { getSettingsKeys } from 'librechat-data-provider';
import { useFormContext, useWatch, Controller } from 'react-hook-form';
import { getSettingsKeys, alternateName } from 'librechat-data-provider';
import type * as t from 'librechat-data-provider';
import type { AgentForm, AgentModelPanelProps, StringOption } from '~/common';
import { componentMapping } from '~/components/SidePanel/Parameters/components';
import { agentSettings } from '~/components/SidePanel/Parameters/settings';
import { getEndpointField, cn, cardStyle } from '~/utils';
import ControlCombobox from '~/components/ui/ControlCombobox';
import { useGetEndpointsQuery } from '~/data-provider';
import { SelectDropDown } from '~/components/ui';
import { getEndpointField, cn } from '~/utils';
import { useLocalize } from '~/hooks';
import { Panel } from '~/common';
@ -33,7 +33,7 @@ export default function Parameters({
return value ?? '';
}, [providerOption]);
const models = useMemo(
() => (provider ? modelsData[provider] ?? [] : []),
() => (provider ? (modelsData[provider] ?? []) : []),
[modelsData, provider],
);
@ -78,8 +78,8 @@ export default function Parameters({
return (
<div className="scrollbar-gutter-stable h-full min-h-[50vh] overflow-auto pb-12 text-sm">
<div className="model-panel relative flex flex-col items-center px-16 py-6 text-center">
<div className="absolute left-0 top-6">
<div className="model-panel relative flex flex-col items-center px-16 py-4 text-center">
<div className="absolute left-0 top-4">
<button
type="button"
className="btn btn-neutral relative"
@ -99,6 +99,7 @@ export default function Parameters({
{/* Endpoint aka Provider for Agents */}
<div className="mb-4">
<label
id="provider-label"
className="text-token-text-primary model-panel-label mb-2 block font-medium"
htmlFor="provider"
>
@ -108,38 +109,47 @@ export default function Parameters({
name="provider"
control={control}
rules={{ required: true, minLength: 1 }}
render={({ field, fieldState: { error } }) => (
<>
<SelectDropDown
emptyTitle={true}
value={field.value ?? ''}
title={localize('com_ui_provider')}
placeholder={localize('com_ui_select_provider')}
searchPlaceholder={localize('com_ui_select_search_provider')}
setValue={field.onChange}
availableValues={providers}
showAbove={false}
showLabel={false}
className={cn(
cardStyle,
'flex h-9 w-full flex-none items-center justify-center border-none px-4 hover:cursor-pointer',
(field.value === undefined || field.value === '') &&
'border-2 border-yellow-400',
render={({ field, fieldState: { error } }) => {
const value =
typeof field.value === 'string'
? field.value
: ((field.value as StringOption)?.value ?? '');
const display =
typeof field.value === 'string'
? field.value
: ((field.value as StringOption)?.label ?? '');
return (
<>
<ControlCombobox
selectedValue={value}
displayValue={alternateName[display] ?? display}
selectPlaceholder={localize('com_ui_select_provider')}
searchPlaceholder={localize('com_ui_select_search_provider')}
setValue={field.onChange}
items={providers.map((provider) => ({
label: typeof provider === 'string' ? provider : provider.label,
value: typeof provider === 'string' ? provider : provider.value,
}))}
className={cn(error ? 'border-2 border-red-500' : '')}
ariaLabel={localize('com_ui_provider')}
isCollapsed={false}
showCarat={true}
/>
{error && (
<span className="model-panel-error text-sm text-red-500 transition duration-300 ease-in-out">
{localize('com_ui_field_required')}
</span>
)}
containerClassName={cn('rounded-md', error ? 'border-red-500 border-2' : '')}
/>
{error && (
<span className="model-panel-error text-sm text-red-500 transition duration-300 ease-in-out">
{localize('com_ui_field_required')}
</span>
)}
</>
)}
</>
);
}}
/>
</div>
{/* Model */}
<div className="model-panel-section mb-4">
<label
id="model-label"
className={cn(
'text-token-text-primary model-panel-label mb-2 block font-medium',
!provider && 'text-gray-500 dark:text-gray-400',
@ -152,35 +162,36 @@ export default function Parameters({
name="model"
control={control}
rules={{ required: true, minLength: 1 }}
render={({ field, fieldState: { error } }) => (
<>
<SelectDropDown
emptyTitle={true}
placeholder={
provider
? localize('com_ui_select_model')
: localize('com_ui_select_provider_first')
}
value={field.value}
setValue={field.onChange}
availableValues={models}
showAbove={false}
showLabel={false}
disabled={!provider}
className={cn(
cardStyle,
'flex h-[40px] w-full flex-none items-center justify-center border-none px-4',
!provider ? 'cursor-not-allowed bg-gray-200' : 'hover:cursor-pointer',
render={({ field, fieldState: { error } }) => {
return (
<>
<ControlCombobox
selectedValue={field.value || ''}
selectPlaceholder={
provider
? localize('com_ui_select_model')
: localize('com_ui_select_provider_first')
}
searchPlaceholder={localize('com_ui_select_model')}
setValue={field.onChange}
items={models.map((model) => ({
label: model,
value: model,
}))}
disabled={!provider}
className={cn('disabled:opacity-50', error ? 'border-2 border-red-500' : '')}
ariaLabel={localize('com_ui_model')}
isCollapsed={false}
showCarat={true}
/>
{provider && error && (
<span className="text-sm text-red-500 transition duration-300 ease-in-out">
{localize('com_ui_field_required')}
</span>
)}
containerClassName={cn('rounded-md', error ? 'border-red-500 border-2' : '')}
/>
{provider && error && (
<span className="text-sm text-red-500 transition duration-300 ease-in-out">
{localize('com_ui_field_required')}
</span>
)}
</>
)}
</>
);
}}
/>
</div>
</div>
@ -188,7 +199,6 @@ export default function Parameters({
{parameters && (
<div className="h-auto max-w-full overflow-x-hidden p-2">
<div className="grid grid-cols-4 gap-6">
{' '}
{/* This is the parent element containing all settings */}
{/* Below is an example of an applied dynamic setting, each be contained by a div with the column span specified */}
{parameters.map((setting) => {

View file

@ -78,6 +78,7 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
ariaLabel={'assistant'}
setValue={onSelect}
items={assistantOptions}
iconClassName="assistant-item"
SelectIcon={
<Icon
isCreatedByUser={false}

View file

@ -27,12 +27,9 @@ function DynamicInput({
const localize = useLocalize();
const { preset } = useChatContext();
const [setInputValue, inputValue, setLocalValue] = useDebouncedInput<string | null>({
const [setInputValue, inputValue, setLocalValue] = useDebouncedInput<string | number>({
optionKey: optionType !== OptionTypes.Custom ? settingKey : undefined,
initialValue:
optionType !== OptionTypes.Custom
? (conversation?.[settingKey] as string)
: (defaultValue as string),
initialValue: optionType !== OptionTypes.Custom ? conversation?.[settingKey] : defaultValue,
setter: () => ({}),
setOption,
});
@ -88,9 +85,13 @@ function DynamicInput({
<Input
id={`${settingKey}-dynamic-input`}
disabled={readonly}
value={inputValue ?? ''}
value={inputValue ?? defaultValue ?? ''}
onChange={handleInputChange}
placeholder={placeholderCode ? localize(placeholder as TranslationKeys) || placeholder : placeholder}
placeholder={
placeholderCode
? localize(placeholder as TranslationKeys) || placeholder
: placeholder
}
className={cn(
'flex h-10 max-h-10 w-full resize-none border-none bg-surface-secondary px-3 py-2',
)}
@ -98,7 +99,11 @@ function DynamicInput({
</HoverCardTrigger>
{description && (
<OptionHover
description={descriptionCode ? localize(description as TranslationKeys) || description : description}
description={
descriptionCode
? localize(description as TranslationKeys) || description
: description
}
side={ESide.Left}
/>
)}

View file

@ -1,5 +1,6 @@
import { RotateCcw } from 'lucide-react';
import React, { useMemo, useState, useEffect, useCallback } from 'react';
import { getSettingsKeys, tConvoUpdateSchema } from 'librechat-data-provider';
import { excludedKeys, getSettingsKeys, tConvoUpdateSchema } from 'librechat-data-provider';
import type { TPreset } from 'librechat-data-provider';
import { SaveAsPresetDialog } from '~/components/Endpoints';
import { useSetIndexOptions, useLocalize } from '~/hooks';
@ -9,23 +10,6 @@ import { componentMapping } from './components';
import { useChatContext } from '~/Providers';
import { settings } from './settings';
const excludedKeys = new Set([
'conversationId',
'title',
'endpoint',
'endpointType',
'createdAt',
'updatedAt',
'messages',
'isArchived',
'tags',
'user',
'__v',
'_id',
'tools',
'model',
]);
export default function Parameters() {
const localize = useLocalize();
const { conversation, setConversation } = useChatContext();
@ -105,6 +89,31 @@ export default function Parameters() {
});
}, [parameters, setConversation]);
const resetParameters = useCallback(() => {
setConversation((prev) => {
if (!prev) {
return prev;
}
const updatedConversation = { ...prev };
const resetKeys: string[] = [];
Object.keys(updatedConversation).forEach((key) => {
if (excludedKeys.has(key)) {
return;
}
if (updatedConversation[key] !== undefined) {
resetKeys.push(key);
delete updatedConversation[key];
}
});
logger.log('parameters', 'parameters reset, affected keys:', resetKeys);
return updatedConversation;
});
}, [setConversation]);
const openDialog = useCallback(() => {
const newPreset = tConvoUpdateSchema.parse({
...conversation,
@ -146,7 +155,17 @@ export default function Parameters() {
);
})}
</div>
<div className="mt-6 flex justify-center">
<div className="mt-4 flex justify-center">
<button
type="button"
onClick={resetParameters}
className="btn btn-neutral flex w-full items-center justify-center gap-2 px-4 py-2 text-sm"
>
<RotateCcw className="h-4 w-4" aria-hidden="true" />
{localize('com_ui_reset_var', { 0: localize('com_ui_model_parameters') })}
</button>
</div>
<div className="mt-2 flex justify-center">
<button
onClick={openDialog}
className="btn btn-primary focus:shadow-outline flex w-full items-center justify-center px-4 py-2 font-semibold text-white hover:bg-green-600 focus:border-green-500"

View file

@ -278,12 +278,42 @@ const anthropic: Record<string, SettingDefinition> = {
description: 'com_endpoint_anthropic_prompt_cache',
descriptionCode: true,
type: 'boolean',
default: true,
default: anthropicSettings.promptCache.default,
component: 'switch',
optionType: 'conversation',
showDefault: false,
columnSpan: 2,
},
thinking: {
key: 'thinking',
label: 'com_endpoint_thinking',
labelCode: true,
description: 'com_endpoint_anthropic_thinking',
descriptionCode: true,
type: 'boolean',
default: anthropicSettings.thinking.default,
component: 'switch',
optionType: 'conversation',
showDefault: false,
columnSpan: 2,
},
thinkingBudget: {
key: 'thinkingBudget',
label: 'com_endpoint_thinking_budget',
labelCode: true,
description: 'com_endpoint_anthropic_thinking_budget',
descriptionCode: true,
type: 'number',
component: 'input',
default: anthropicSettings.thinkingBudget.default,
range: {
min: anthropicSettings.thinkingBudget.min,
max: anthropicSettings.thinkingBudget.max,
step: anthropicSettings.thinkingBudget.step,
},
optionType: 'conversation',
columnSpan: 2,
},
};
const bedrock: Record<string, SettingDefinition> = {
@ -492,6 +522,8 @@ const anthropicConfig: SettingsConfiguration = [
anthropic.topK,
librechat.resendFiles,
anthropic.promptCache,
anthropic.thinking,
anthropic.thinkingBudget,
];
const anthropicCol1: SettingsConfiguration = [
@ -508,6 +540,8 @@ const anthropicCol2: SettingsConfiguration = [
anthropic.topK,
librechat.resendFiles,
anthropic.promptCache,
anthropic.thinking,
anthropic.thinkingBudget,
];
const bedrockAnthropic: SettingsConfiguration = [
@ -519,8 +553,10 @@ const bedrockAnthropic: SettingsConfiguration = [
bedrock.topP,
bedrock.topK,
baseDefinitions.stop,
bedrock.region,
librechat.resendFiles,
bedrock.region,
anthropic.thinking,
anthropic.thinkingBudget,
];
const bedrockMistral: SettingsConfiguration = [
@ -530,8 +566,8 @@ const bedrockMistral: SettingsConfiguration = [
bedrock.maxTokens,
mistral.temperature,
mistral.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
const bedrockCohere: SettingsConfiguration = [
@ -541,8 +577,8 @@ const bedrockCohere: SettingsConfiguration = [
bedrock.maxTokens,
cohere.temperature,
cohere.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
const bedrockGeneral: SettingsConfiguration = [
@ -551,8 +587,8 @@ const bedrockGeneral: SettingsConfiguration = [
librechat.maxContextTokens,
meta.temperature,
meta.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
const bedrockAnthropicCol1: SettingsConfiguration = [
@ -568,8 +604,10 @@ const bedrockAnthropicCol2: SettingsConfiguration = [
bedrock.temperature,
bedrock.topP,
bedrock.topK,
bedrock.region,
librechat.resendFiles,
bedrock.region,
anthropic.thinking,
anthropic.thinkingBudget,
];
const bedrockMistralCol1: SettingsConfiguration = [
@ -583,8 +621,8 @@ const bedrockMistralCol2: SettingsConfiguration = [
bedrock.maxTokens,
mistral.temperature,
mistral.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
const bedrockCohereCol1: SettingsConfiguration = [
@ -598,8 +636,8 @@ const bedrockCohereCol2: SettingsConfiguration = [
bedrock.maxTokens,
cohere.temperature,
cohere.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
const bedrockGeneralCol1: SettingsConfiguration = [
@ -612,8 +650,8 @@ const bedrockGeneralCol2: SettingsConfiguration = [
librechat.maxContextTokens,
meta.temperature,
meta.topP,
bedrock.region,
librechat.resendFiles,
bedrock.region,
];
export const settings: Record<string, SettingsConfiguration | undefined> = {

View file

@ -143,7 +143,7 @@ const SidePanel = ({
id="controls-nav"
order={hasArtifacts != null ? 3 : 2}
aria-label={localize('com_ui_controls')}
role="region"
role="navigation"
collapsedSize={collapsedSize}
defaultSize={defaultSize}
collapsible={true}

View file

@ -1,6 +1,6 @@
import { Search } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
import { matchSorter } from 'match-sorter';
import { Search, ChevronDown } from 'lucide-react';
import { useMemo, useState, useRef, memo, useEffect } from 'react';
import { SelectRenderer } from '@ariakit/react-core/select/select-renderer';
import type { OptionWithIcon } from '~/common';
@ -16,6 +16,13 @@ interface ControlComboboxProps {
selectPlaceholder?: string;
isCollapsed: boolean;
SelectIcon?: React.ReactNode;
containerClassName?: string;
iconClassName?: string;
showCarat?: boolean;
className?: string;
disabled?: boolean;
iconSide?: 'left' | 'right';
selectId?: string;
}
const ROW_HEIGHT = 36;
@ -28,8 +35,15 @@ function ControlCombobox({
ariaLabel,
searchPlaceholder,
selectPlaceholder,
containerClassName,
isCollapsed,
SelectIcon,
showCarat,
className,
disabled,
iconClassName,
iconSide = 'left',
selectId,
}: ControlComboboxProps) {
const [searchValue, setSearchValue] = useState('');
const buttonRef = useRef<HTMLButtonElement>(null);
@ -70,28 +84,48 @@ function ControlCombobox({
}
}, [isCollapsed]);
const selectIconClassName = cn(
'flex h-5 w-5 items-center justify-center overflow-hidden rounded-full',
iconClassName,
);
const optionIconClassName = cn(
'mr-2 flex h-5 w-5 items-center justify-center overflow-hidden rounded-full',
iconClassName,
);
return (
<div className="flex w-full items-center justify-center px-1">
<div className={cn('flex w-full items-center justify-center px-1', containerClassName)}>
<Ariakit.SelectLabel store={select} className="sr-only">
{ariaLabel}
</Ariakit.SelectLabel>
<Ariakit.Select
ref={buttonRef}
store={select}
id={selectId}
disabled={disabled}
className={cn(
'flex items-center justify-center gap-2 rounded-full bg-surface-secondary',
'text-text-primary hover:bg-surface-tertiary',
'border border-border-light',
isCollapsed ? 'h-10 w-10' : 'h-10 w-full rounded-md px-3 py-2 text-sm',
className,
)}
>
{SelectIcon != null && (
<div className="assistant-item flex h-5 w-5 items-center justify-center overflow-hidden rounded-full">
{SelectIcon}
</div>
{SelectIcon != null && iconSide === 'left' && (
<div className={selectIconClassName}>{SelectIcon}</div>
)}
{!isCollapsed && (
<span className="flex-grow truncate text-left">{displayValue ?? selectPlaceholder}</span>
<>
<span className="flex-grow truncate text-left">
{displayValue != null
? displayValue || selectPlaceholder
: selectedValue || selectPlaceholder}
</span>
{SelectIcon != null && iconSide === 'right' && (
<div className={selectIconClassName}>{SelectIcon}</div>
)}
{showCarat && <ChevronDown className="h-4 w-4 text-text-secondary" />}
</>
)}
</Ariakit.Select>
<Ariakit.SelectPopover
@ -126,12 +160,13 @@ function ControlCombobox({
)}
render={<Ariakit.SelectItem value={value} />}
>
{icon != null && (
<div className="assistant-item mr-2 flex h-5 w-5 items-center justify-center overflow-hidden rounded-full">
{icon}
</div>
{icon != null && iconSide === 'left' && (
<div className={optionIconClassName}>{icon}</div>
)}
<span className="flex-grow truncate text-left">{label}</span>
{icon != null && iconSide === 'right' && (
<div className={optionIconClassName}>{icon}</div>
)}
</Ariakit.ComboboxItem>
)}
</SelectRenderer>

View file

@ -0,0 +1,68 @@
import * as React from 'react';
import { OTPInput, OTPInputContext } from 'input-otp';
import { Minus } from 'lucide-react';
import { cn } from '~/utils';
const InputOTP = React.forwardRef<
React.ElementRef<typeof OTPInput>,
React.ComponentPropsWithoutRef<typeof OTPInput>
>(({ className, containerClassName, ...props }, ref) => (
<OTPInput
ref={ref}
containerClassName={cn(
'flex items-center gap-2 has-[:disabled]:opacity-50',
containerClassName,
)}
className={cn('disabled:cursor-not-allowed', className)}
{...props}
/>
));
InputOTP.displayName = 'InputOTP';
const InputOTPGroup = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn('flex items-center', className)} {...props} />
));
InputOTPGroup.displayName = 'InputOTPGroup';
const InputOTPSlot = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'> & { index: number }
>(({ index, className, ...props }, ref) => {
const inputOTPContext = React.useContext(OTPInputContext);
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
return (
<div
ref={ref}
className={cn(
'text-md relative flex h-11 w-11 items-center justify-center border-y border-r border-input shadow-sm transition-all first:rounded-l-xl first:border-l last:rounded-r-xl',
isActive && 'z-10 ring-1 ring-ring',
className,
)}
{...props}
>
{char}
{hasFakeCaret && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<div className="animate-caret-blink h-4 w-px bg-foreground duration-1000" />
</div>
)}
</div>
);
});
InputOTPSlot.displayName = 'InputOTPSlot';
const InputOTPSeparator = React.forwardRef<
React.ElementRef<'div'>,
React.ComponentPropsWithoutRef<'div'>
>(({ ...props }, ref) => (
<div ref={ref} role="separator" {...props}>
<Minus />
</div>
));
InputOTPSeparator.displayName = 'InputOTPSeparator';
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };

View file

@ -0,0 +1,22 @@
import * as React from 'react';
import * as ProgressPrimitive from '@radix-ui/react-progress';
import { cn } from '~/utils';
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
));
Progress.displayName = ProgressPrimitive.Root.displayName;
export { Progress };

View file

@ -1,4 +1,4 @@
import React from 'react';
import React, { useRef } from 'react';
import {
Label,
Listbox,
@ -82,18 +82,14 @@ function SelectDropDown({
}
let title = _title;
if (emptyTitle) {
title = '';
} else if (!(title ?? '')) {
title = localize('com_ui_model');
}
const values = availableValues ?? [];
// Detemine if we should to convert this component into a searchable select. If we have enough elements, a search
// input will appear near the top of the menu, allowing correct filtering of different model menu items. This will
// reset once the component is unmounted (as per a normal search)
// Enable searchable select if enough items are provided.
const [filteredValues, searchRender] = useMultiSearch<string[] | Option[]>({
availableOptions: values,
placeholder: searchPlaceholder,
@ -103,26 +99,35 @@ function SelectDropDown({
});
const hasSearchRender = searchRender != null;
const options = hasSearchRender ? filteredValues : values;
const renderIcon = showOptionIcon && value != null && (value as OptionWithIcon).icon != null;
const buttonRef = useRef<HTMLButtonElement>(null);
return (
<div className={cn('flex items-center justify-center gap-2 ', containerClassName ?? '')}>
<div className={cn('flex items-center justify-center gap-2', containerClassName ?? '')}>
<div className={cn('relative w-full', subContainerClassName ?? '')}>
<Listbox value={value} onChange={setValue} disabled={disabled}>
{({ open }) => (
<>
<ListboxButton
ref={buttonRef}
data-testid="select-dropdown-button"
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
if (!open && buttonRef.current) {
buttonRef.current.click();
}
}
}}
className={cn(
'relative flex w-full cursor-default flex-col rounded-md border border-black/10 bg-white py-2 pl-3 pr-10 text-left disabled:bg-white dark:border-gray-600 dark:bg-gray-700 sm:text-sm',
'relative flex w-full cursor-default flex-col rounded-md border border-black/10 bg-white py-2 pl-3 pr-10 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:bg-white dark:border-gray-600 dark:bg-gray-700 sm:text-sm',
className ?? '',
)}
>
{' '}
{showLabel && (
<Label
className="block text-xs text-gray-700 dark:text-gray-500 "
className="block text-xs text-gray-700 dark:text-gray-500"
id="headlessui-listbox-label-:r1:"
data-headlessui-state=""
>
@ -154,11 +159,9 @@ function SelectDropDown({
if (!value) {
return <span className="text-text-secondary">{placeholder}</span>;
}
if (typeof value !== 'string') {
return value.label ?? '';
}
return value;
})()}
</span>
@ -171,7 +174,7 @@ function SelectDropDown({
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4 text-gray-400"
className="h-4 w-4 text-gray-400"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
@ -212,17 +215,17 @@ function SelectDropDown({
if (!option) {
return null;
}
const currentLabel =
typeof option === 'string' ? option : option.label ?? option.value ?? '';
const currentValue = typeof option === 'string' ? option : option.value ?? '';
typeof option === 'string' ? option : (option.label ?? option.value ?? '');
const currentValue = typeof option === 'string' ? option : (option.value ?? '');
const currentIcon =
typeof option === 'string' ? null : (option.icon as React.ReactNode) ?? null;
typeof option === 'string'
? null
: ((option.icon as React.ReactNode) ?? null);
let activeValue: string | number | null | Option = value;
if (typeof activeValue !== 'string') {
activeValue = activeValue?.value ?? '';
}
return (
<ListboxOption
key={i}

View file

@ -24,6 +24,8 @@ export * from './Textarea';
export * from './TextareaAutosize';
export * from './Tooltip';
export * from './Pagination';
export * from './Progress';
export * from './InputOTP';
export { default as Combobox } from './Combobox';
export { default as Dropdown } from './Dropdown';
export { default as FileUpload } from './FileUpload';

View file

@ -1,6 +1,6 @@
import { useResetRecoilState, useSetRecoilState } from 'recoil';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { MutationKeys, dataService, request } from 'librechat-data-provider';
import { MutationKeys, QueryKeys, dataService, request } from 'librechat-data-provider';
import type { UseMutationResult } from '@tanstack/react-query';
import type * as t from 'librechat-data-provider';
import useClearStates from '~/hooks/Config/useClearStates';
@ -84,3 +84,91 @@ export const useDeleteUserMutation = (
},
});
};
// Array.isArray(user?.backupCodes) && user?.backupCodes.length > 0
export const useEnableTwoFactorMutation = (): UseMutationResult<
t.TEnable2FAResponse,
unknown,
void,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(() => dataService.enableTwoFactor(), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
},
});
};
export const useVerifyTwoFactorMutation = (): UseMutationResult<
t.TVerify2FAResponse,
unknown,
t.TVerify2FARequest,
unknown
> => {
const queryClient = useQueryClient();
return useMutation((payload: t.TVerify2FARequest) => dataService.verifyTwoFactor(payload), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
},
});
};
export const useConfirmTwoFactorMutation = (): UseMutationResult<
t.TVerify2FAResponse,
unknown,
t.TVerify2FARequest,
unknown
> => {
const queryClient = useQueryClient();
return useMutation((payload: t.TVerify2FARequest) => dataService.confirmTwoFactor(payload), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
},
});
};
export const useDisableTwoFactorMutation = (): UseMutationResult<
t.TDisable2FAResponse,
unknown,
void,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(() => dataService.disableTwoFactor(), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], null);
},
});
};
export const useRegenerateBackupCodesMutation = (): UseMutationResult<
t.TRegenerateBackupCodesResponse,
unknown,
void,
unknown
> => {
const queryClient = useQueryClient();
return useMutation(() => dataService.regenerateBackupCodes(), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa', 'backup'], data);
},
});
};
export const useVerifyTwoFactorTempMutation = (
options?: t.MutationOptions<t.TVerify2FATempResponse, t.TVerify2FATempRequest, unknown, unknown>,
): UseMutationResult<t.TVerify2FATempResponse, unknown, t.TVerify2FATempRequest, unknown> => {
const queryClient = useQueryClient();
return useMutation(
(payload: t.TVerify2FATempRequest) => dataService.verifyTwoFactorTemp(payload),
{
...(options || {}),
onSuccess: (data, ...args) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
options?.onSuccess?.(data, ...args);
},
},
);
};

View file

@ -8,7 +8,7 @@ import {
createContext,
} from 'react';
import { useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { setTokenHeader, SystemRoles } from 'librechat-data-provider';
import type * as t from 'librechat-data-provider';
import {
@ -70,7 +70,12 @@ const AuthContextProvider = ({
const loginUser = useLoginUserMutation({
onSuccess: (data: t.TLoginResponse) => {
const { user, token } = data;
const { user, token, twoFAPending, tempToken } = data;
if (twoFAPending) {
// Redirect to the two-factor authentication route.
navigate(`/login/2fa?tempToken=${tempToken}`, { replace: true });
return;
}
setError(undefined);
setUserContext({ token, isAuthenticated: true, user, redirect: '/c/new' });
},
@ -195,7 +200,7 @@ const AuthContextProvider = ({
},
isAuthenticated,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[user, error, isAuthenticated, token, userRole, adminRole],
);
@ -212,4 +217,4 @@ const useAuthContext = () => {
return context;
};
export { AuthContextProvider, useAuthContext };
export { AuthContextProvider, useAuthContext, AuthContext };

View file

@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { useQueryClient } from '@tanstack/react-query';
import { QueryKeys, EModelEndpoint, LocalStorageKeys, Constants } from 'librechat-data-provider';
import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider';
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField, logger } from '~/utils';
import store from '~/store';
const useNavigateToConvo = (index = 0) => {
@ -20,7 +20,7 @@ const useNavigateToConvo = (index = 0) => {
invalidateMessages = false,
) => {
if (!conversation) {
console.log('Conversation not provided');
logger.warn('conversation', 'Conversation not provided to `navigateToConvo`');
return;
}
hasSetConversation.current = true;
@ -34,10 +34,10 @@ const useNavigateToConvo = (index = 0) => {
}
let convo = { ...conversation };
if (!convo.endpoint) {
/* undefined endpoint edge case */
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
if (!convo.endpoint || !endpointsConfig?.[convo.endpoint]) {
/* undefined/removed endpoint edge case */
const modelsConfig = queryClient.getQueryData<TModelsConfig>([QueryKeys.models]);
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
const defaultEndpoint = getDefaultEndpoint({
convoSetup: conversation,
endpointsConfig,
@ -51,10 +51,10 @@ const useNavigateToConvo = (index = 0) => {
const models = modelsConfig?.[defaultEndpoint ?? ''] ?? [];
convo = buildDefaultConvo({
models,
conversation,
endpoint: defaultEndpoint,
lastConversationSetup: conversation,
models,
});
}
clearAllConversations(true);
@ -68,7 +68,7 @@ const useNavigateToConvo = (index = 0) => {
invalidateMessages?: boolean,
) => {
if (!conversation) {
console.log('Conversation not provided');
logger.warn('conversation', 'Conversation not provided to `navigateToConvo`');
return;
}
// set conversation to the new conversation
@ -78,7 +78,7 @@ const useNavigateToConvo = (index = 0) => {
lastSelectedTools =
JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_TOOLS) ?? '') ?? [];
} catch (e) {
// console.error(e);
logger.error('conversation', 'Error parsing last selected tools', e);
}
const hasTools = (conversation.tools?.length ?? 0) > 0;
navigateToConvo(

View file

@ -1,6 +1,6 @@
import { useMemo, useCallback } from 'react';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
import { useAuthContext } from '~/hooks/AuthContext';
import { useMemo, useCallback, useContext } from 'react';
import type { TUser, PermissionTypes, Permissions } from 'librechat-data-provider';
import { AuthContext } from '~/hooks/AuthContext';
const useHasAccess = ({
permissionType,
@ -9,16 +9,31 @@ const useHasAccess = ({
permissionType: PermissionTypes;
permission: Permissions;
}) => {
const { isAuthenticated, user, roles } = useAuthContext();
const authContext = useContext(AuthContext);
const user = authContext?.user;
const roles = authContext?.roles;
const isAuthenticated = authContext?.isAuthenticated || false;
const checkAccess = useCallback(
({ user, permissionType, permission }) => {
({
user,
permissionType,
permission,
}: {
user?: TUser | null;
permissionType: PermissionTypes;
permission: Permissions;
}) => {
if (!authContext) {
return false;
}
if (isAuthenticated && user?.role != null && roles && roles[user.role]) {
return roles[user.role]?.[permissionType]?.[permission] === true;
}
return false;
},
[isAuthenticated, roles],
[authContext, isAuthenticated, roles],
);
const hasAccess = useMemo(

View file

@ -178,7 +178,6 @@
"com_endpoint_google_temp": "القيم الأعلى = أكثر عشوائية، بينما القيم الأقل = أكثر تركيزًا وحتمية. نوصي بتغيير هذا أو Top P ولكن ليس كلاهما.",
"com_endpoint_google_topk": "Top-k يغير كيفية اختيار النموذج للرموز للإخراج. top-k من 1 يعني أن الرمز المحدد هو الأكثر احتمالية بين جميع الرموز في مفردات النموذج (يسمى أيضًا الترميز الجشعي)، بينما top-k من 3 يعني أن الرمز التالي يتم اختياره من بين الرموز الثلاثة الأكثر احتمالية (باستخدام الحرارة).",
"com_endpoint_google_topp": "Top-p يغير كيفية اختيار النموذج للرموز للإخراج. يتم اختيار الرموز من الأكثر K (انظر معلمة topK) احتمالًا إلى الأقل حتى يصبح مجموع احتمالاتهم يساوي قيمة top-p.",
"com_endpoint_import": "استيراد",
"com_endpoint_instructions_assistants": "تعليمات التجاوز",
"com_endpoint_instructions_assistants_placeholder": "يتجاوز التعليمات الخاصة بالمساعد. هذا مفيد لتعديل السلوك على أساس كل مرة.",
"com_endpoint_max_output_tokens": "الحد الأقصى لعدد الرموز المنتجة",
@ -262,7 +261,6 @@
"com_nav_archive_name": "الاسم",
"com_nav_archived_chats": "الدردشات المؤرشفة",
"com_nav_archived_chats_empty": "ليس لديك أي دردشات مؤرشفة.",
"com_nav_archived_chats_manage": "إدارة",
"com_nav_at_command": "أمر-@",
"com_nav_at_command_description": "تبديل الأمر \"@\" للتنقل بين نقاط النهاية والنماذج والإعدادات المسبقة وغيرها",
"com_nav_audio_play_error": "خطأ في تشغيل الصوت: {{0}}",
@ -383,7 +381,6 @@
"com_nav_setting_speech": "الكلام",
"com_nav_settings": "الإعدادات",
"com_nav_shared_links": "روابط مشتركة",
"com_nav_shared_links_manage": "الإدارة",
"com_nav_show_code": "إظهار الشفرة دائمًا عند استخدام مفسر الشفرة",
"com_nav_slash_command": "/-الأمر",
"com_nav_slash_command_description": "تبديل الأمر \"/\" لاختيار موجه عبر لوحة المفاتيح",
@ -587,7 +584,6 @@
"com_ui_happy_birthday": "إنه عيد ميلادي الأول!",
"com_ui_host": "مُضيف",
"com_ui_image_gen": "توليد الصور",
"com_ui_import_conversation": "استيراد",
"com_ui_import_conversation_error": "حدث خطأ أثناء استيراد محادثاتك",
"com_ui_import_conversation_file_type_error": "نوع الملف غير مدعوم للاستيراد",
"com_ui_import_conversation_info": "استيراد محادثات من ملف JSON",

View file

@ -85,6 +85,7 @@
"com_auth_email_verification_redirecting": "Weiterleitung in {{0}} Sekunden...",
"com_auth_email_verification_resend_prompt": "Keine E-Mail erhalten?",
"com_auth_email_verification_success": "E-Mail erfolgreich verifiziert",
"com_auth_email_verifying_ellipsis": "Überprüfe …",
"com_auth_error_create": "Bei der Registrierung deines Kontos ist ein Fehler aufgetreten. Bitte versuche es erneut.",
"com_auth_error_invalid_reset_token": "Dieser Passwort-Reset-Token ist nicht mehr gültig.",
"com_auth_error_login": "Anmeldung mit den angegebenen Informationen nicht möglich. Bitte überprüfe deine Anmeldedaten und versuche es erneut.",
@ -121,9 +122,11 @@
"com_auth_submit_registration": "Registrierung absenden",
"com_auth_to_reset_your_password": "um Ihr Passwort zurückzusetzen.",
"com_auth_to_try_again": "um es erneut zu versuchen.",
"com_auth_two_factor": "Prüfe deine bevorzugte Einmalkennwort-App auf einen Code.",
"com_auth_username": "Benutzername (optional)",
"com_auth_username_max_length": "Benutzername darf nicht länger als 20 Zeichen sein",
"com_auth_username_min_length": "Benutzername muss mindestens 2 Zeichen lang sein",
"com_auth_verify_your_identity": "Bestätige deine Identität",
"com_auth_welcome_back": "Willkommen zurück",
"com_click_to_download": "(hier klicken zum Herunterladen)",
"com_download_expired": "Download abgelaufen",
@ -136,6 +139,8 @@
"com_endpoint_anthropic_maxoutputtokens": "Maximale Anzahl von Token, die in der Antwort erzeugt werden können. Gib einen niedrigeren Wert für kürzere Antworten und einen höheren Wert für längere Antworten an. Hinweis: Die Modelle können auch vor Erreichen dieses Maximums stoppen.",
"com_endpoint_anthropic_prompt_cache": "Prompt-Caching ermöglicht die Wiederverwendung von umfangreichen Kontexten oder Anweisungen über mehrere API-Aufrufe hinweg, wodurch Kosten und Latenzzeiten reduziert werden",
"com_endpoint_anthropic_temp": "Reicht von 0 bis 1. Verwende Temperaturen näher an 0 für analytische / Multiple-Choice-Aufgaben und näher an 1 für kreative und generative Aufgaben. Wir empfehlen, entweder dies oder Top P zu ändern, aber nicht beides.",
"com_endpoint_anthropic_thinking": "Aktiviert internes logisches Denken für unterstützte Claude-Modelle (3.7 Sonnet). Hinweis: Erfordert, dass \"Denkbudget\" festgelegt und niedriger als \"Max. Ausgabe-Token\" ist",
"com_endpoint_anthropic_thinking_budget": "Bestimmt die maximale Anzahl an Token, die Claude für seinen internen Denkprozess verwenden darf. Ein höheres Budget kann die Antwortqualität verbessern, indem es eine gründlichere Analyse bei komplexen Problemen ermöglicht. Claude nutzt jedoch möglicherweise nicht das gesamte zugewiesene Budget, insbesondere bei Werten über 32.000. Diese Einstellung muss niedriger sein als \"Max. Ausgabe-Token\".",
"com_endpoint_anthropic_topk": "Top-k ändert, wie das Modell Token für die Ausgabe auswählt. Ein Top-k von 1 bedeutet, dass das ausgewählte Token das wahrscheinlichste unter allen Token im Vokabular des Modells ist (auch \"Greedy Decoding\" genannt), während ein Top-k von 3 bedeutet, dass das nächste Token aus den 3 wahrscheinlichsten Token ausgewählt wird (unter Verwendung der Temperatur).",
"com_endpoint_anthropic_topp": "Top-p ändert, wie das Modell Token für die Ausgabe auswählt. Token werden von den wahrscheinlichsten K (siehe topK-Parameter) bis zu den am wenigsten wahrscheinlichen ausgewählt, bis die Summe ihrer Wahrscheinlichkeiten dem Top-p-Wert entspricht.",
"com_endpoint_assistant": "Assistent",
@ -182,7 +187,6 @@
"com_endpoint_google_temp": "Höhere Werte = zufälliger, während niedrigere Werte = fokussierter und deterministischer. Wir empfehlen, entweder dies oder Top P zu ändern, aber nicht beides.",
"com_endpoint_google_topk": "Top-k ändert, wie das Modell Token für die Antwort auswählt. Ein Top-k von 1 bedeutet, dass das ausgewählte Token das wahrscheinlichste unter allen Token im Vokabular des Modells ist (auch Greedy-Decoding genannt), während ein Top-k von 3 bedeutet, dass das nächste Token aus den 3 wahrscheinlichsten Token ausgewählt wird (unter Verwendung der Temperatur).",
"com_endpoint_google_topp": "Top-p ändert, wie das Modell Token für die Antwort auswählt. Token werden von den wahrscheinlichsten K (siehe topK-Parameter) bis zu den am wenigsten wahrscheinlichen ausgewählt, bis die Summe ihrer Wahrscheinlichkeiten dem Top-p-Wert entspricht.",
"com_endpoint_import": "Importieren",
"com_endpoint_instructions_assistants": "Anweisungen überschreiben",
"com_endpoint_instructions_assistants_placeholder": "Überschreibt die Anweisungen des Assistenten. Dies ist nützlich, um das Verhalten auf Basis einzelner Ausführungen zu modifizieren.",
"com_endpoint_max_output_tokens": "Max. Antwort-Token",
@ -241,6 +245,8 @@
"com_endpoint_stop": "Stop-Sequenzen",
"com_endpoint_stop_placeholder": "Trenne Stoppwörter durch Drücken der `Enter`-Taste",
"com_endpoint_temperature": "Temperatur",
"com_endpoint_thinking": "Denken",
"com_endpoint_thinking_budget": "Denkbudget",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Aktiven Assistenten verwenden",
@ -262,13 +268,13 @@
"com_files_number_selected": "{{0}} von {{1}} Datei(en) ausgewählt",
"com_generated_files": "Generierte Dateien:",
"com_hide_examples": "Beispiele ausblenden",
"com_nav_2fa": "Zwei-Faktor-Authentifizierung (2FA)",
"com_nav_account_settings": "Kontoeinstellungen",
"com_nav_always_make_prod": "Neue Versionen direkt produktiv nehmen",
"com_nav_archive_created_at": "Archivierungsdatum",
"com_nav_archive_name": "Name",
"com_nav_archived_chats": "Archivierte Chats",
"com_nav_archived_chats_empty": "Du hast keine archivierten Chats.",
"com_nav_archived_chats_manage": "Verwalten",
"com_nav_at_command": "@-Befehl",
"com_nav_at_command_description": "Schaltet den Befehl \"@\" zum Wechseln von Endpunkten, Modellen, Voreinstellungen usw. um.",
"com_nav_audio_play_error": "Fehler beim Abspielen des Audios: {{0}}",
@ -328,6 +334,7 @@
"com_nav_help_faq": "Hilfe & FAQ",
"com_nav_hide_panel": "Rechte Seitenleiste verstecken",
"com_nav_info_code_artifacts": "Aktiviert die Anzeige experimenteller Code-Artefakte neben dem Chat",
"com_nav_info_code_artifacts_agent": "Aktiviert die Verwendung von Code-Artefakten für diesen Agenten. Standardmäßig werden zusätzliche, spezielle Anweisungen für die Nutzung von Artefakten hinzugefügt, es sei denn, der \"Benutzerdefinierte Prompt-Modus\" ist aktiviert.",
"com_nav_info_custom_prompt_mode": "Wenn aktiviert, wird die Standard-Systemaufforderung für Artefakte nicht eingeschlossen. Alle Anweisungen zur Erzeugung von Artefakten müssen in diesem Modus manuell bereitgestellt werden.",
"com_nav_info_enter_to_send": "Wenn aktiviert, sendet das Drücken von `ENTER` Ihre Nachricht. Wenn deaktiviert, fügt das Drücken von Enter eine neue Zeile hinzu, und du musst `STRG + ENTER` drücken, um deine Nachricht zu senden.",
"com_nav_info_fork_change_default": "`Nur sichtbare Nachrichten` umfasst nur den direkten Pfad zur ausgewählten Nachricht. `Zugehörige Verzweigungen einbeziehen` fügt Verzweigungen entlang des Pfades hinzu. `Alle bis/von hier einbeziehen` umfasst alle verbundenen Nachrichten und Verzweigungen.",
@ -391,7 +398,6 @@
"com_nav_setting_speech": "Sprache",
"com_nav_settings": "Einstellungen",
"com_nav_shared_links": "Geteilte Links",
"com_nav_shared_links_manage": "Verwalten",
"com_nav_show_code": "Code immer anzeigen, wenn der Code-Interpreter verwendet wird",
"com_nav_show_thinking": "Denkprozess-Dropdowns standardmäßig öffnen",
"com_nav_slash_command": "/-Befehl",
@ -432,6 +438,16 @@
"com_sidepanel_parameters": "KI-Einstellungen",
"com_sidepanel_select_agent": "Wähle einen Agenten",
"com_sidepanel_select_assistant": "Assistenten auswählen",
"com_ui_2fa_account_security": "Die Zwei-Faktor-Authentifizierung bietet Ihrem Konto eine zusätzliche Sicherheitsebene.",
"com_ui_2fa_disable": "2FA deaktivieren",
"com_ui_2fa_disable_error": "Beim Deaktivieren der Zwei-Faktor-Authentifizierung ist ein Fehler aufgetreten.",
"com_ui_2fa_disabled": "2FA wurde deaktiviert.",
"com_ui_2fa_enable": "2FA aktivieren",
"com_ui_2fa_enabled": "2FA wurde aktiviert.",
"com_ui_2fa_generate_error": "Beim Erstellen der Einstellungen für die Zwei-Faktor-Authentifizierung ist ein Fehler aufgetreten.",
"com_ui_2fa_invalid": "Ungültiger Zwei-Faktor-Authentifizierungscode.",
"com_ui_2fa_setup": "2FA einrichten",
"com_ui_2fa_verified": "Die Zwei-Faktor-Authentifizierung wurde erfolgreich verifiziert.",
"com_ui_accept": "Ich akzeptiere",
"com_ui_add": "Hinzufügen",
"com_ui_add_model_preset": "Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen",
@ -453,12 +469,15 @@
"com_ui_agents_allow_use": "Verwendung von Agenten erlauben",
"com_ui_all": "alle",
"com_ui_all_proper": "Alle",
"com_ui_analyzing": "Analyse läuft",
"com_ui_analyzing_finished": "Analyse abgeschlossen",
"com_ui_api_key": "API-Schlüssel",
"com_ui_archive": "Archivieren",
"com_ui_archive_error": "Konversation konnte nicht archiviert werden",
"com_ui_artifact_click": "Zum Öffnen klicken",
"com_ui_artifacts": "Artefakte",
"com_ui_artifacts_toggle": "Artefakte-Funktion einschalten",
"com_ui_artifacts_toggle_agent": "Artefakte aktivieren",
"com_ui_ascending": "Aufsteigend",
"com_ui_assistant": "Assistent",
"com_ui_assistant_delete_error": "Beim Löschen des Assistenten ist ein Fehler aufgetreten",
@ -476,8 +495,12 @@
"com_ui_authentication": "Authentifizierung",
"com_ui_authentication_type": "Authentifizierungstyp",
"com_ui_avatar": "Avatar",
"com_ui_azure": "Azure",
"com_ui_back_to_chat": "Zurück zum Chat",
"com_ui_back_to_prompts": "Zurück zu den Prompts",
"com_ui_backup_codes": "Backup-Codes",
"com_ui_backup_codes_regenerate_error": "Beim Neuerstellen der Backup-Codes ist ein Fehler aufgetreten.",
"com_ui_backup_codes_regenerated": "Backup-Codes wurden erfolgreich neu erstellt.",
"com_ui_basic": "Basic",
"com_ui_basic_auth_header": "Basic-Authentifizierungsheader",
"com_ui_bearer": "Bearer",
@ -506,6 +529,7 @@
"com_ui_chat_history": "Chatverlauf",
"com_ui_clear": "Löschen",
"com_ui_clear_all": "Auswahl löschen",
"com_ui_client_id": "Client-ID",
"com_ui_client_secret": "Client Secret",
"com_ui_close": "Schließen",
"com_ui_close_menu": "Menü schließen",
@ -513,6 +537,7 @@
"com_ui_collapse_chat": "Chat einklappen",
"com_ui_command_placeholder": "Optional: Gib einen Promptbefehl ein oder den Namen.",
"com_ui_command_usage_placeholder": "Wähle einen Prompt nach Befehl oder Name aus",
"com_ui_complete_setup": "Einrichtung abschließen",
"com_ui_confirm_action": "Aktion bestätigen",
"com_ui_confirm_admin_use_change": "Wenn du diese Einstellung änderst, wird der Zugriff für Administratoren, einschließlich dir selbst, gesperrt. Bist du sicher, dass du fortfahren möchtest?",
"com_ui_confirm_change": "Änderung bestätigen",
@ -529,6 +554,7 @@
"com_ui_create_prompt": "Prompt erstellen",
"com_ui_currently_production": "Aktuell im Produktivbetrieb",
"com_ui_custom": "Benutzerdefiniert",
"com_ui_custom_header_name": "Benutzerdefinierter Headername",
"com_ui_custom_prompt_mode": "Benutzerdefinierter Promptmodus für Artefakte",
"com_ui_dashboard": "Dashboard",
"com_ui_date": "Datum",
@ -549,6 +575,7 @@
"com_ui_date_today": "Heute",
"com_ui_date_yesterday": "Gestern",
"com_ui_decline": "Ich akzeptiere nicht",
"com_ui_default_post_request": "Standard (POST-Anfrage)",
"com_ui_delete": "Löschen",
"com_ui_delete_action": "Aktion löschen",
"com_ui_delete_action_confirm": "Bist du sicher, dass du diese Aktion löschen möchtest?",
@ -564,8 +591,11 @@
"com_ui_descending": "Absteigend",
"com_ui_description": "Beschreibung",
"com_ui_description_placeholder": "Optional: Gib eine Beschreibung für den Prompt ein",
"com_ui_disabling": "Deaktiviere …",
"com_ui_download": "Herunterladen",
"com_ui_download_artifact": "Artefakt herunterladen",
"com_ui_download_backup": "Backup-Codes herunterladen",
"com_ui_download_backup_tooltip": "Bevor Sie fortfahren, laden Sie bitte Ihre Backup-Codes herunter. Sie benötigen sie, um den Zugang wiederherzustellen, falls Sie Ihr Authentifizierungsgerät verlieren.",
"com_ui_download_error": "Fehler beim Herunterladen der Datei. Die Datei wurde möglicherweise gelöscht.",
"com_ui_dropdown_variables": "Dropdown-Variablen:",
"com_ui_dropdown_variables_info": "Erstellen Sie benutzerdefinierte Dropdown-Menüs für Ihre Eingabeaufforderungen: `{{variable_name:option1|option2|option3}}`",
@ -589,6 +619,7 @@
"com_ui_field_required": "Dieses Feld ist erforderlich",
"com_ui_filter_prompts": "Prompts filtern",
"com_ui_filter_prompts_name": "Prompts nach Namen filtern",
"com_ui_finance": "Finanzen",
"com_ui_fork": "Abzweigen",
"com_ui_fork_all_target": "Alle bis/von hier einbeziehen",
"com_ui_fork_branches": "Zugehörige Verzweigungen einbeziehen",
@ -611,18 +642,23 @@
"com_ui_fork_split_target_setting": "Abzweigung standardmäßig von der Zielnachricht beginnen",
"com_ui_fork_success": "Konversation erfolgreich abgezweigt",
"com_ui_fork_visible": "Nur sichtbare Nachrichten",
"com_ui_generate_backup": "Backup-Codes generieren",
"com_ui_generate_qrcode": "QR-Code generieren",
"com_ui_generating": "Generiere …",
"com_ui_go_back": "Zurück",
"com_ui_go_to_conversation": "Zur Konversation gehen",
"com_ui_happy_birthday": "Es ist mein 1. Geburtstag!",
"com_ui_hide_qr": "QR-Code ausblenden",
"com_ui_host": "Host",
"com_ui_idea": "Ideen",
"com_ui_image_gen": "Bildgenerierung",
"com_ui_import_conversation": "Importieren",
"com_ui_import": "Importieren",
"com_ui_import_conversation_error": "Beim Importieren Ihrer Konversationen ist ein Fehler aufgetreten",
"com_ui_import_conversation_file_type_error": "Nicht unterstützter Importtyp",
"com_ui_import_conversation_info": "Konversationen aus einer JSON-Datei importieren",
"com_ui_import_conversation_success": "Konversationen erfolgreich importiert",
"com_ui_include_shadcnui": "Anweisungen für shadcn/ui-Komponenten einschließen",
"com_ui_include_shadcnui_agent": "shadcn/ui-Anweisungen einfügen",
"com_ui_input": "Eingabe",
"com_ui_instructions": "Anweisungen",
"com_ui_latest_footer": "Alle KIs für alle.",
@ -633,31 +669,37 @@
"com_ui_librechat_code_api_title": "KI-Code ausführen",
"com_ui_llm_menu": "LLM-Menü",
"com_ui_llms_available": "Verfügbare LLMs",
"com_ui_loading": "Lade …",
"com_ui_locked": "Gesperrt",
"com_ui_logo": "{{0}} Logo",
"com_ui_manage": "Verwalten",
"com_ui_max_tags": "Die maximale Anzahl ist {{0}}, es werden die neuesten Werte verwendet.",
"com_ui_mention": "Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln",
"com_ui_min_tags": "Es können nicht mehr Werte entfernt werden, mindestens {{0}} sind erforderlich.",
"com_ui_misc": "Verschiedenes",
"com_ui_model": "KI-Modell",
"com_ui_model_parameters": "Modell-Parameter",
"com_ui_more_info": "Mehr Infos",
"com_ui_my_prompts": "Meine Prompts",
"com_ui_name": "Name",
"com_ui_new": "Neu",
"com_ui_new_chat": "Neuer Chat",
"com_ui_next": "Weiter",
"com_ui_no": "Nein",
"com_ui_no_backup_codes": "Keine Backup-Codes verfügbar. Bitte erstelle neue.",
"com_ui_no_bookmarks": "Du hast noch keine Lesezeichen. Klicke auf einen Chat und füge ein neues hinzu",
"com_ui_no_category": "Keine Kategorie",
"com_ui_no_changes": "Keine Änderungen zum Aktualisieren",
"com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen",
"com_ui_none": "Keine",
"com_ui_none_selected": "Nichts ausgewählt",
"com_ui_not_used": "Nicht verwendet",
"com_ui_nothing_found": "Nichts gefunden",
"com_ui_oauth": "OAuth",
"com_ui_of": "von",
"com_ui_off": "Aus",
"com_ui_on": "An",
"com_ui_openai": "OpenAI",
"com_ui_page": "Seite",
"com_ui_prev": "Zurück",
"com_ui_preview": "Vorschau",
@ -679,6 +721,8 @@
"com_ui_read_aloud": "Vorlesen",
"com_ui_refresh_link": "Link aktualisieren",
"com_ui_regenerate": "Neu generieren",
"com_ui_regenerate_backup": "Backup-Codes neu generieren",
"com_ui_regenerating": "Generiere neu ...",
"com_ui_region": "Region",
"com_ui_rename": "Umbenennen",
"com_ui_rename_prompt": "Prompt umbenennen",
@ -692,13 +736,16 @@
"com_ui_revoke_keys": "Schlüssel widerrufen",
"com_ui_revoke_keys_confirm": "Bist du sicher, dass du alle Schlüssel widerrufen möchtest?",
"com_ui_role_select": "Rolle auswählen",
"com_ui_roleplay": "Rollenspiel",
"com_ui_run_code": "Code ausführen",
"com_ui_run_code_error": "Bei der Ausführung des Codes ist ein Fehler aufgetreten",
"com_ui_save": "Speichern",
"com_ui_save_submit": "Speichern & Absenden",
"com_ui_saved": "Gespeichert!",
"com_ui_schema": "Schema",
"com_ui_scope": "Umfang",
"com_ui_search": "Suche",
"com_ui_secret_key": "Geheimschlüssel",
"com_ui_select": "Auswählen",
"com_ui_select_file": "Datei auswählen",
"com_ui_select_model": "Ein KI-Modell auswählen",
@ -721,6 +768,8 @@
"com_ui_shared_link_delete_success": "Geteilter Link erfolgreich gelöscht",
"com_ui_shared_link_not_found": "Geteilter Link nicht gefunden",
"com_ui_shared_prompts": "Geteilte Prompts",
"com_ui_shop": "Einkaufen",
"com_ui_show": "Anzeigen",
"com_ui_show_all": "Alle anzeigen",
"com_ui_show_qr": "QR-Code anzeigen",
"com_ui_sign_in_to_domain": "Anmelden bei {{0}}",
@ -732,6 +781,7 @@
"com_ui_stop": "Stopp",
"com_ui_storage": "Speicher",
"com_ui_submit": "Absenden",
"com_ui_teach_or_explain": "Lernen",
"com_ui_temporary_chat": "Temporärer Chat",
"com_ui_terms_and_conditions": "Allgemeine Geschäftsbedingungen",
"com_ui_terms_of_service": "Nutzungsbedingungen",
@ -740,6 +790,7 @@
"com_ui_token_exchange_method": "Token-Austauschmethode",
"com_ui_token_url": "Token-URL",
"com_ui_tools": "Werkzeuge",
"com_ui_travel": "Reisen",
"com_ui_unarchive": "Aus Archiv holen",
"com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden",
"com_ui_unknown": "Unbekannt",
@ -756,13 +807,18 @@
"com_ui_upload_invalid_var": "Ungültige Datei zum Hochladen. Muss ein Bild sein und {{0}} MB nicht überschreiten",
"com_ui_upload_success": "Datei erfolgreich hochgeladen",
"com_ui_upload_type": "Upload-Typ auswählen",
"com_ui_use_2fa_code": "Stattdessen 2FA-Code verwenden",
"com_ui_use_backup_code": "Stattdessen Backup-Code verwenden",
"com_ui_use_micrphone": "Mikrofon verwenden",
"com_ui_use_prompt": "Prompt verwenden",
"com_ui_used": "Verwendet",
"com_ui_variables": "Variablen",
"com_ui_variables_info": "Verwende doppelte geschweifte Klammern in Ihrem Text, um Variablen zu erstellen, z.B. {{Beispielvariable}}, die du später beim Verwenden des Prompts ausfüllen kannst.",
"com_ui_verify": "Überprüfen",
"com_ui_version_var": "Version {{0}}",
"com_ui_versions": "Versionen",
"com_ui_view_source": "Quell-Chat anzeigen",
"com_ui_write": "Schreiben",
"com_ui_yes": "Ja",
"com_ui_zoom": "Zoom",
"com_user_message": "Du",

View file

@ -87,6 +87,7 @@
"com_auth_email_verification_redirecting": "Redirecting in {{0}} seconds...",
"com_auth_email_verification_resend_prompt": "Didn't receive the email?",
"com_auth_email_verification_success": "Email verified successfully",
"com_auth_email_verifying_ellipsis": "Verifying...",
"com_auth_error_create": "There was an error attempting to register your account. Please try again.",
"com_auth_error_invalid_reset_token": "This password reset token is no longer valid.",
"com_auth_error_login": "Unable to login with the information provided. Please check your credentials and try again.",
@ -123,9 +124,11 @@
"com_auth_submit_registration": "Submit registration",
"com_auth_to_reset_your_password": "to reset your password.",
"com_auth_to_try_again": "to try again.",
"com_auth_two_factor": "Check your preferred one-time password application for a code",
"com_auth_username": "Username (optional)",
"com_auth_username_max_length": "Username must be less than 20 characters",
"com_auth_username_min_length": "Username must be at least 2 characters",
"com_auth_verify_your_identity": "Verify Your Identity",
"com_auth_welcome_back": "Welcome back",
"com_click_to_download": "(click here to download)",
"com_download_expired": "(download expired)",
@ -138,6 +141,8 @@
"com_endpoint_anthropic_maxoutputtokens": "Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses. Note: models may stop before reaching this maximum.",
"com_endpoint_anthropic_prompt_cache": "Prompt caching allows reusing large context or instructions across API calls, reducing costs and latency",
"com_endpoint_anthropic_temp": "Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks. We recommend altering this or Top P but not both.",
"com_endpoint_anthropic_thinking": "Enables internal reasoning for supported Claude models (3.7 Sonnet). Note: requires \"Thinking Budget\" to be set and lower than \"Max Output Tokens\"",
"com_endpoint_anthropic_thinking_budget": "Determines the max number of tokens Claude is allowed use for its internal reasoning process. Larger budgets can improve response quality by enabling more thorough analysis for complex problems, although Claude may not use the entire budget allocated, especially at ranges above 32K. This setting must be lower than \"Max Output Tokens.\"",
"com_endpoint_anthropic_topk": "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).",
"com_endpoint_anthropic_topp": "Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.",
"com_endpoint_assistant": "Assistant",
@ -184,7 +189,6 @@
"com_endpoint_google_temp": "Higher values = more random, while lower values = more focused and deterministic. We recommend altering this or Top P but not both.",
"com_endpoint_google_topk": "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).",
"com_endpoint_google_topp": "Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.",
"com_endpoint_import": "Import",
"com_endpoint_instructions_assistants": "Override Instructions",
"com_endpoint_instructions_assistants_placeholder": "Overrides the instructions of the assistant. This is useful for modifying the behavior on a per-run basis.",
"com_endpoint_max_output_tokens": "Max Output Tokens",
@ -244,6 +248,8 @@
"com_endpoint_stop": "Stop Sequences",
"com_endpoint_stop_placeholder": "Separate values by pressing `Enter`",
"com_endpoint_temperature": "Temperature",
"com_endpoint_thinking": "Thinking",
"com_endpoint_thinking_budget": "Thinking Budget",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Use Active Assistant",
@ -266,13 +272,13 @@
"com_files_table": "something needs to go here. was empty",
"com_generated_files": "Generated files:",
"com_hide_examples": "Hide Examples",
"com_nav_2fa": "Two-Factor Authentication (2FA)",
"com_nav_account_settings": "Account Settings",
"com_nav_always_make_prod": "Always make new versions production",
"com_nav_archive_created_at": "Date Archived",
"com_nav_archive_name": "Name",
"com_nav_archived_chats": "Archived chats",
"com_nav_archived_chats_empty": "You have no archived conversations.",
"com_nav_archived_chats_manage": "Manage",
"com_nav_at_command": "@-Command",
"com_nav_at_command_description": "Toggle command \"@\" for switching endpoints, models, presets, etc.",
"com_nav_audio_play_error": "Error playing audio: {{0}}",
@ -351,6 +357,7 @@
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_finnish": "Suomi",
"com_nav_lang_french": "Français ",
"com_nav_lang_georgian": "ქართული",
"com_nav_lang_german": "Deutsch",
"com_nav_lang_hebrew": "עברית",
"com_nav_lang_indonesia": "Indonesia",
@ -396,7 +403,6 @@
"com_nav_setting_speech": "Speech",
"com_nav_settings": "Settings",
"com_nav_shared_links": "Shared links",
"com_nav_shared_links_manage": "Manage",
"com_nav_show_code": "Always show code when using code interpreter",
"com_nav_show_thinking": "Open Thinking Dropdowns by Default",
"com_nav_slash_command": "/-Command",
@ -437,6 +443,16 @@
"com_sidepanel_parameters": "Parameters",
"com_sidepanel_select_agent": "Select an Agent",
"com_sidepanel_select_assistant": "Select an Assistant",
"com_ui_2fa_account_security": "Two-factor authentication adds an extra layer of security to your account",
"com_ui_2fa_disable": "Disable 2FA",
"com_ui_2fa_disable_error": "There was an error disabling two-factor authentication",
"com_ui_2fa_disabled": "2FA has been disabled",
"com_ui_2fa_enable": "Enable 2FA",
"com_ui_2fa_enabled": "2FA has been enabled",
"com_ui_2fa_generate_error": "There was an error generating two-factor authentication settings",
"com_ui_2fa_invalid": "Invalid two-factor authentication code",
"com_ui_2fa_setup": "Setup 2FA",
"com_ui_2fa_verified": "Successfully verified Two-Factor Authentication",
"com_ui_accept": "I accept",
"com_ui_add": "Add",
"com_ui_add_model_preset": "Add a model or preset for an additional response",
@ -487,6 +503,9 @@
"com_ui_azure": "Azure",
"com_ui_back_to_chat": "Back to Chat",
"com_ui_back_to_prompts": "Back to Prompts",
"com_ui_backup_codes": "Backup Codes",
"com_ui_backup_codes_regenerate_error": "There was an error regenerating backup codes",
"com_ui_backup_codes_regenerated": "Backup codes have been regenerated successfully",
"com_ui_basic": "Basic",
"com_ui_basic_auth_header": "Basic authorization header",
"com_ui_bearer": "Bearer",
@ -523,6 +542,7 @@
"com_ui_collapse_chat": "Collapse Chat",
"com_ui_command_placeholder": "Optional: Enter a command for the prompt or name will be used",
"com_ui_command_usage_placeholder": "Select a Prompt by command or name",
"com_ui_complete_setup": "Complete Setup",
"com_ui_confirm_action": "Confirm Action",
"com_ui_confirm_admin_use_change": "Changing this setting will block access for admins, including yourself. Are you sure you want to proceed?",
"com_ui_confirm_change": "Confirm Change",
@ -581,8 +601,11 @@
"com_ui_descending": "Desc",
"com_ui_description": "Description",
"com_ui_description_placeholder": "Optional: Enter a description to display for the prompt",
"com_ui_disabling": "Disabling...",
"com_ui_download": "Download",
"com_ui_download_artifact": "Download Artifact",
"com_ui_download_backup": "Download Backup Codes",
"com_ui_download_backup_tooltip": "Before you continue, download your backup codes. You will need them to regain access if you lose your authenticator device",
"com_ui_download_error": "Error downloading file. The file may have been deleted.",
"com_ui_drag_drop": "something needs to go here. was empty",
"com_ui_dropdown_variables": "Dropdown variables:",
@ -631,6 +654,9 @@
"com_ui_fork_split_target_setting": "Start fork from target message by default",
"com_ui_fork_success": "Successfully forked conversation",
"com_ui_fork_visible": "Visible messages only",
"com_ui_generate_backup": "Generate Backup Codes",
"com_ui_generate_qrcode": "Generate QR Code",
"com_ui_generating": "Generating...",
"com_ui_global_group": "something needs to go here. was empty",
"com_ui_go_back": "Go back",
"com_ui_go_to_conversation": "Go to conversation",
@ -639,7 +665,7 @@
"com_ui_host": "Host",
"com_ui_idea": "Ideas",
"com_ui_image_gen": "Image Gen",
"com_ui_import_conversation": "Import",
"com_ui_import": "Import",
"com_ui_import_conversation_error": "There was an error importing your conversations",
"com_ui_import_conversation_file_type_error": "Unsupported import type",
"com_ui_import_conversation_info": "Import conversations from a JSON file",
@ -669,9 +695,11 @@
"com_ui_more_info": "More info",
"com_ui_my_prompts": "My Prompts",
"com_ui_name": "Name",
"com_ui_new": "New",
"com_ui_new_chat": "New chat",
"com_ui_next": "Next",
"com_ui_no": "No",
"com_ui_no_backup_codes": "No backup codes available. Please generate new ones",
"com_ui_no_bookmarks": "it seems like you have no bookmarks yet. Click on a chat and add a new one",
"com_ui_no_category": "No category",
"com_ui_no_changes": "No changes to update",
@ -680,6 +708,7 @@
"com_ui_no_valid_items": "something needs to go here. was empty",
"com_ui_none": "None",
"com_ui_none_selected": "None selected",
"com_ui_not_used": "Not Used",
"com_ui_nothing_found": "Nothing found",
"com_ui_oauth": "OAuth",
"com_ui_of": "of",
@ -707,6 +736,8 @@
"com_ui_read_aloud": "Read aloud",
"com_ui_refresh_link": "Refresh link",
"com_ui_regenerate": "Regenerate",
"com_ui_regenerate_backup": "Regenerate Backup Codes",
"com_ui_regenerating": "Regenerating...",
"com_ui_region": "Region",
"com_ui_rename": "Rename",
"com_ui_rename_prompt": "Rename Prompt",
@ -729,6 +760,7 @@
"com_ui_schema": "Schema",
"com_ui_scope": "Scope",
"com_ui_search": "Search",
"com_ui_secret_key": "Secret Key",
"com_ui_select": "Select",
"com_ui_select_file": "Select a file",
"com_ui_select_model": "Select a model",
@ -753,6 +785,7 @@
"com_ui_shared_link_not_found": "Shared link not found",
"com_ui_shared_prompts": "Shared Prompts",
"com_ui_shop": "Shopping",
"com_ui_show": "Show",
"com_ui_show_all": "Show All",
"com_ui_show_qr": "Show QR Code",
"com_ui_sign_in_to_domain": "Sign-in to {{0}}",
@ -790,10 +823,14 @@
"com_ui_upload_invalid_var": "Invalid file for upload. Must be an image not exceeding {{0}} MB",
"com_ui_upload_success": "Successfully uploaded file",
"com_ui_upload_type": "Select Upload Type",
"com_ui_use_2fa_code": "Use 2FA Code Instead",
"com_ui_use_backup_code": "Use Backup Code Instead",
"com_ui_use_micrphone": "Use microphone",
"com_ui_use_prompt": "Use prompt",
"com_ui_used": "Used",
"com_ui_variables": "Variables",
"com_ui_variables_info": "Use double braces in your text to create variables, e.g. `{{example variable}}`, to later fill when using the prompt.",
"com_ui_verify": "Verify",
"com_ui_version_var": "Version {{0}}",
"com_ui_versions": "Versions",
"com_ui_view_source": "View source chat",

View file

@ -1,4 +1,6 @@
{
"chat_direction_left_to_right": "algo debería ir aquí pero está vacío",
"chat_direction_right_to_left": "algo debería ir aquí pero está vacío",
"com_a11y_ai_composing": "La IA está componiendo la respuesta",
"com_a11y_end": "La IA ha finalizado su respuesta",
"com_a11y_start": "La IA ha comenzado su respuesta",
@ -18,13 +20,16 @@
"com_agents_not_available": "Agente no disponible",
"com_agents_search_name": "Buscar agentes por nombre",
"com_agents_update_error": "Hubo un error al actualizar su agente.",
"com_assistants_action_attempt": "El asistente quiere hablar con {{0}}",
"com_assistants_actions": "Acciones",
"com_assistants_actions_disabled": "Necesita crear un asistente antes de añadir acciones.",
"com_assistants_actions_info": "Permita que su Asistente recupere información o realice acciones a través de API's",
"com_assistants_add_actions": "Añadir Acciones",
"com_assistants_add_tools": "Añadir Herramientas",
"com_assistants_allow_sites_you_trust": "Solo permite sitios en los que confíes.",
"com_assistants_append_date": "Añadir Fecha y Hora Actual",
"com_assistants_append_date_tooltip": "Cuando está habilitado, la fecha y hora actual del cliente se adjuntarán a las instrucciones del sistema del asistente.",
"com_assistants_attempt_info": "El asistente quiere enviar lo siguiente:",
"com_assistants_available_actions": "Acciones Disponibles",
"com_assistants_capabilities": "Capacidades",
"com_assistants_code_interpreter": "Intérprete de Código",
@ -59,6 +64,7 @@
"com_assistants_update_error": "Hubo un error al actualizar su asistente.",
"com_assistants_update_success": "Actualizado con éxito",
"com_auth_already_have_account": "¿Ya tiene una cuenta?",
"com_auth_apple_login": "Inicia con Apple",
"com_auth_back_to_login": "Volver al inicio de sesión",
"com_auth_click": "Haga clic",
"com_auth_click_here": "Haz clic aquí",
@ -117,9 +123,11 @@
"com_auth_submit_registration": "Enviar registro",
"com_auth_to_reset_your_password": "para restablecer su contraseña.",
"com_auth_to_try_again": "para intentar de nuevo.",
"com_auth_two_factor": "Revisa tu aplicación preferida de OTP para obtener el código",
"com_auth_username": "Nombre de usuario (opcional)",
"com_auth_username_max_length": "El nombre de usuario debe tener menos de 20 caracteres",
"com_auth_username_min_length": "El nombre de usuario debe tener al menos 2 caracteres",
"com_auth_verify_your_identity": "Verifica Tu Identidad",
"com_auth_welcome_back": "Bienvenido de nuevo",
"com_click_to_download": "(haga clic aquí para descargar)",
"com_download_expired": "Descarga expirada",
@ -178,7 +186,6 @@
"com_endpoint_google_temp": "Los valores más altos = más aleatorios, mientras que los valores más bajos = más enfocados y deterministas. Recomendamos alterar esto o Top P, pero no ambos.",
"com_endpoint_google_topk": "Top-k cambia la forma en que el modelo selecciona tokens para la salida. Un top-k de 1 significa que el token seleccionado es el más probable entre todos los tokens en el vocabulario del modelo (también llamado decodificación codiciosa), mientras que un top-k de 3 significa que el siguiente token se selecciona entre los 3 tokens más probables (usando temperatura).",
"com_endpoint_google_topp": "Top-p cambia la forma en que el modelo selecciona tokens para la salida. Los tokens se seleccionan desde los más K (ver parámetro topK) probables hasta los menos probables hasta que la suma de sus probabilidades sea igual al valor top-p.",
"com_endpoint_import": "Importar",
"com_endpoint_instructions_assistants": "Anular instrucciones",
"com_endpoint_instructions_assistants_placeholder": "Anula las instrucciones del asistente. Esto es útil para modificar el comportamiento por ejecución.",
"com_endpoint_max_output_tokens": "Tokens de Salida Máximos",
@ -262,7 +269,6 @@
"com_nav_archive_name": "Nombre",
"com_nav_archived_chats": "Archivadas",
"com_nav_archived_chats_empty": "No tienes conversaciones archivadas.",
"com_nav_archived_chats_manage": "Gestionar",
"com_nav_at_command": "Comando @",
"com_nav_at_command_description": "Alternar comando \"@\" para cambiar entre puntos de conexión, modelos, ajustes predefinidos, etc.",
"com_nav_audio_play_error": "Error al reproducir el audio: {{0}}",
@ -383,7 +389,6 @@
"com_nav_setting_speech": "Voz y habla",
"com_nav_settings": "Configuración",
"com_nav_shared_links": "Links Compartidos",
"com_nav_shared_links_manage": "Gerenciar",
"com_nav_show_code": "Mostrar siempre el código cuando se use el intérprete de código",
"com_nav_slash_command": "Comando /",
"com_nav_slash_command_description": "Alternar comando '/' para seleccionar un mensaje predefinido mediante el teclado",
@ -423,6 +428,8 @@
"com_sidepanel_parameters": "Parámetros",
"com_sidepanel_select_agent": "Seleccione un Agente",
"com_sidepanel_select_assistant": "Seleccionar un Asistente",
"com_ui_2fa_enable": "Activa 2FA",
"com_ui_2fa_enabled": "2FA ha sido activada",
"com_ui_accept": "Acepto",
"com_ui_add": "Agregar",
"com_ui_add_model_preset": "Agregar un modelo o configuración preestablecida para una respuesta adicional",
@ -587,7 +594,6 @@
"com_ui_happy_birthday": "¡Es mi primer cumpleaños!",
"com_ui_host": "Host",
"com_ui_image_gen": "Gen Imágenes",
"com_ui_import_conversation": "Importar",
"com_ui_import_conversation_error": "Hubo un error al importar tus chats",
"com_ui_import_conversation_file_type_error": "com_ui_import_conversation_file_type_error: Tipo de archivo no compatible para importar",
"com_ui_import_conversation_info": "Importar chats de un archivo JSON",

View file

@ -1,6 +1,6 @@
{
"chat_direction_left_to_right": "midagi peaks siia minema. Oli tühi",
"chat_direction_right_to_left": "midagi peaks siia minema. Oli tühi",
"chat_direction_left_to_right": "Joonda vestlus vasakult paremale.",
"chat_direction_right_to_left": "Joonda vestlus paremalt vasakule.",
"com_a11y_ai_composing": "AI genereerib vastust.",
"com_a11y_end": "AI on oma vastuse lõpetanud.",
"com_a11y_start": "AI on oma vastuse andmise alustanud.",
@ -87,6 +87,7 @@
"com_auth_email_verification_redirecting": "Suunatakse ümber {{0}} sekundi pärast...",
"com_auth_email_verification_resend_prompt": "Kas sa ei saanud e-kirja?",
"com_auth_email_verification_success": "E-post kinnitatud",
"com_auth_email_verifying_ellipsis": "Kontrollimine...",
"com_auth_error_create": "Konto registreerimisel tekkis viga. Proovige uuesti.",
"com_auth_error_invalid_reset_token": "See parooli lähtestamise tunnus pole enam kehtiv.",
"com_auth_error_login": "Sisselogimine esitatud teabega ei õnnestu. Palun kontrolli oma andmeid ja proovi uuesti.",
@ -123,9 +124,11 @@
"com_auth_submit_registration": "Saada registreerimine",
"com_auth_to_reset_your_password": "parooli lähtestamiseks.",
"com_auth_to_try_again": "uuesti proovimiseks.",
"com_auth_two_factor": "Kontrolli oma eelistatud ühekordse parooli rakendust koodi saamiseks",
"com_auth_username": "Kasutajanimi (valikuline)",
"com_auth_username_max_length": "Kasutajanimi peab olema vähem kui 20 tähemärki",
"com_auth_username_min_length": "Kasutajanimi peab olema vähemalt 2 tähemärki",
"com_auth_verify_your_identity": "Kontrolli",
"com_auth_welcome_back": "Teretulemast tagasi",
"com_click_to_download": "(vajuta siia, et alla laadida)",
"com_download_expired": "(allalaadimine aegunud)",
@ -184,7 +187,6 @@
"com_endpoint_google_temp": "Kõrgemad väärtused = juhuslikum, samas kui madalamad väärtused = keskendunum ja deterministlikum. Soovitame muuta kas seda või Top P-d, aga mitte mõlemat.",
"com_endpoint_google_topk": "Top-k muudab seda, kuidas mudel valib väljundi jaoks märgid. Top-k väärtus 1 tähendab, et valitud märk on kõige tõenäolisem kõigi mudeli sõnavaras olevate märkide seas (nimetatakse ka ahneks dekodeerimiseks), samas kui top-k väärtus 3 tähendab, et järgmine märk valitakse 3 kõige tõenäolisema märgi seast (kasutades temperatuuri).",
"com_endpoint_google_topp": "Top-p muudab seda, kuidas mudel valib väljundi jaoks märgid. Märgid valitakse kõige tõenäolisemast K (vt parameetrit topK) kuni vähim tõenäoliseni, kuni nende tõenäosuste summa on võrdne top-p väärtusega.",
"com_endpoint_import": "Impordi",
"com_endpoint_instructions_assistants": "Tühista juhised",
"com_endpoint_instructions_assistants_placeholder": "Tühistab assistendi juhised. See on kasulik käitumise muutmiseks käivituse kohta.",
"com_endpoint_max_output_tokens": "Maksimaalsed väljundmärgid",
@ -215,7 +217,7 @@
"com_endpoint_plug_use_functions": "Kasuta funktsioone",
"com_endpoint_presence_penalty": "Olekukaristus",
"com_endpoint_preset": "eelseadistus",
"com_endpoint_preset_custom_name_placeholder": "midagi peaks siia minema. Oli tühi",
"com_endpoint_preset_custom_name_placeholder": "Otspunkti kohandatud nimi.",
"com_endpoint_preset_default": "on nüüd vaike-eelseadistus.",
"com_endpoint_preset_default_item": "Vaikimisi:",
"com_endpoint_preset_default_none": "Vaikimisi eelseadistus pole aktiivne.",
@ -263,16 +265,16 @@
"com_files_filter": "Filtreeri faile...",
"com_files_no_results": "Tulemusi pole.",
"com_files_number_selected": "{{0}} / {{1}} üksust valitud",
"com_files_table": "Mmdagi peaks siia minema. Oli tühi",
"com_files_table": "Failide tabel",
"com_generated_files": "Genereeritud failid:",
"com_hide_examples": "Peida näited",
"com_nav_2fa": "Kaheastmeline autentimine (2FA)",
"com_nav_account_settings": "Konto seaded",
"com_nav_always_make_prod": "Tee uued versioonid alati toodangusse",
"com_nav_archive_created_at": "Arhiveerimise kuupäev",
"com_nav_archive_name": "Nimi",
"com_nav_archived_chats": "Arhiveeritud vestlused",
"com_nav_archived_chats_empty": "Sul ei ole arhiveeritud vestlusi.",
"com_nav_archived_chats_manage": "Halda",
"com_nav_at_command": "@-käsk",
"com_nav_at_command_description": "Lülita käsk \"@\" sisse/välja lõpp-punktide, mudelite, eelseadistuste jms vahetamiseks.",
"com_nav_audio_play_error": "Viga heli esitamisel: {{0}}",
@ -396,7 +398,6 @@
"com_nav_setting_speech": "Kõne",
"com_nav_settings": "Seaded",
"com_nav_shared_links": "Jagatud lingid",
"com_nav_shared_links_manage": "Halda",
"com_nav_show_code": "Näita koodi alati, kui kasutatakse koodiinterpreteerijat",
"com_nav_show_thinking": "Ava mõtlemise rippmenüüd vaikimisi",
"com_nav_slash_command": "/-käsk",
@ -437,6 +438,16 @@
"com_sidepanel_parameters": "Parameetrid",
"com_sidepanel_select_agent": "Vali agent",
"com_sidepanel_select_assistant": "Vali assistent",
"com_ui_2fa_account_security": "Kaheastmeline autentimine lisab teie kontole täiendava turvalisuse kihi",
"com_ui_2fa_disable": "Lülita 2FA välja",
"com_ui_2fa_disable_error": "Tekkis viga kaheastmelise autentimise väljalülitamisel",
"com_ui_2fa_disabled": "2FA on välja lülitatud",
"com_ui_2fa_enable": "Aktiveeri 2FA",
"com_ui_2fa_enabled": "2FA on aktiveeritud",
"com_ui_2fa_generate_error": "Kaheastmelise autentimise seadete genereerimisel tekkis viga",
"com_ui_2fa_invalid": "Vale kaheastmeline autentimise kood",
"com_ui_2fa_setup": "Seadista 2FA",
"com_ui_2fa_verified": "Kaheastmeline autentimine õnnestus",
"com_ui_accept": "Nõustun",
"com_ui_add": "Lisa",
"com_ui_add_model_preset": "Lisa mudel või eelseadistus täiendava vastuse jaoks",
@ -451,7 +462,7 @@
"com_ui_agent_duplicate_error": "Agendi dubleerimisel tekkis viga",
"com_ui_agent_duplicated": "Agendi dubleerimine õnnestus",
"com_ui_agent_editing_allowed": "Teised kasutajad saavad seda agenti juba muuta",
"com_ui_agent_shared_to_all": "Mmdagi peaks siia minema. Oli tühi",
"com_ui_agent_shared_to_all": "Seda agenti on jagatud kõigi kasutajatega",
"com_ui_agents": "Agendid",
"com_ui_agents_allow_create": "Luba agentide loomine",
"com_ui_agents_allow_share_global": "Luba agentide jagamine kõigile kasutajatele",
@ -487,6 +498,9 @@
"com_ui_azure": "Azure",
"com_ui_back_to_chat": "Tagasi vestlusesse",
"com_ui_back_to_prompts": "Tagasi sisendite juurde",
"com_ui_backup_codes": "Varukoodid",
"com_ui_backup_codes_regenerate_error": "Varukoodide loomisel tekkis viga",
"com_ui_backup_codes_regenerated": "Varukoodide loomine oli edukas",
"com_ui_basic": "Põhiline",
"com_ui_basic_auth_header": "Põhiline autentimise päis",
"com_ui_bearer": "Bearer",
@ -523,6 +537,7 @@
"com_ui_collapse_chat": "Ahenda vestlus",
"com_ui_command_placeholder": "Valikuline: sisesta sisendi jaoks käsk või kasutatakse nime",
"com_ui_command_usage_placeholder": "Vali sisend käsu või nime järgi",
"com_ui_complete_setup": "Valmis",
"com_ui_confirm_action": "Kinnita tegevus",
"com_ui_confirm_admin_use_change": "Selle seadistuse muutmine blokeerib juurdepääsu administraatoritele, sealhulgas sinule endale. Oled sa kindel, et sa soovid jätkata?",
"com_ui_confirm_change": "Kinnita muudatus",
@ -576,10 +591,13 @@
"com_ui_descending": "Desc",
"com_ui_description": "Kirjeldus",
"com_ui_description_placeholder": "Valikuline: sisesta sisendi jaoks kuvatav kirjeldus",
"com_ui_disabling": "Välja lülitamine...",
"com_ui_download": "Laadi alla",
"com_ui_download_artifact": "Laadi artefakt alla",
"com_ui_download_backup": "Laadi alla varukoodid",
"com_ui_download_backup_tooltip": "Enne jätkamist laadi alla oma varukoodid. Vajad neid ligipääsu taastamiseks, kui peaksid oma autentimisseadme kaotama.",
"com_ui_download_error": "Viga faili allalaadimisel. Fail võib olla kustutatud.",
"com_ui_drag_drop": "Midagi peaks siia minema. Oli tühi",
"com_ui_drag_drop": "Lohistage",
"com_ui_dropdown_variables": "Rippmenüü muutujad:",
"com_ui_dropdown_variables_info": "Loo sisendite jaoks kohandatud rippmenüüd: `{{muutuja_nimi:valik1|valik2|valik3}}`",
"com_ui_duplicate": "Dubleeri",
@ -587,6 +605,7 @@
"com_ui_duplication_processing": "Vestlust dubleeritakse...",
"com_ui_duplication_success": "Vestluse dubleerimine õnnestus",
"com_ui_edit": "Muuda",
"com_ui_empty_category": "-",
"com_ui_endpoint": "Otspunkt",
"com_ui_endpoint_menu": "LLM otspunkti menüü",
"com_ui_endpoints_available": "Saadaolevad otspunktid",
@ -602,6 +621,7 @@
"com_ui_field_required": "See väli on kohustuslik",
"com_ui_filter_prompts": "Filtreeri sisendid",
"com_ui_filter_prompts_name": "Filtreeri sisendeid nime järgi",
"com_ui_finance": "Raha",
"com_ui_fork": "Hargne",
"com_ui_fork_all_target": "Kaasa kõik siia/siit",
"com_ui_fork_branches": "Kaasa seotud harud",
@ -624,14 +644,18 @@
"com_ui_fork_split_target_setting": "Alusta vaikimisi sihtsõnumist hargnemist",
"com_ui_fork_success": "Vestluse hargnemine õnnestus",
"com_ui_fork_visible": "Ainult nähtavad sõnumid",
"com_ui_global_group": "Midagi peaks siia minema. Oli tühi",
"com_ui_generate_backup": "Loo varukoodid",
"com_ui_generate_qrcode": "Loo QR-kood",
"com_ui_generating": "Loomine...",
"com_ui_global_group": "Ülene grupp",
"com_ui_go_back": "Mine tagasi",
"com_ui_go_to_conversation": "Mine vestlusesse",
"com_ui_happy_birthday": "Mul on 1. sünnipäev!",
"com_ui_hide_qr": "Peida QR-kood",
"com_ui_host": "Host",
"com_ui_idea": "Ideed",
"com_ui_image_gen": "Pildi genereerimine",
"com_ui_import_conversation": "Impordi",
"com_ui_import": "Impordi",
"com_ui_import_conversation_error": "Vestluste importimisel tekkis viga",
"com_ui_import_conversation_file_type_error": "Toetamatu imporditüüp",
"com_ui_import_conversation_info": "Impordi vestlused JSON-failist",
@ -648,12 +672,14 @@
"com_ui_librechat_code_api_title": "Käivita AI koodi",
"com_ui_llm_menu": "LLM menüü",
"com_ui_llms_available": "Saadaolevad LLM-id",
"com_ui_loading": "Laeb...",
"com_ui_locked": "Lukus",
"com_ui_logo": "{{0}} logo",
"com_ui_manage": "Halda",
"com_ui_max_tags": "Maksimaalne lubatud arv on {{0}}, kasutades viimaseid väärtusi.",
"com_ui_mention": "Maini otspunkti, assistenti või eelseadistust, et sellele kiiresti üle minna",
"com_ui_min_tags": "Rohkem väärtusi ei saa eemaldada, vaja on vähemalt {{0}}.",
"com_ui_misc": "Muu",
"com_ui_model": "Mudel",
"com_ui_model_parameters": "Mudeli parameetrid",
"com_ui_more_info": "Rohkem infot",
@ -662,14 +688,16 @@
"com_ui_new_chat": "Uus vestlus",
"com_ui_next": "Järgmine",
"com_ui_no": "Ei",
"com_ui_no_backup_codes": "Varukoodid puuduvad. Palun loo uued",
"com_ui_no_bookmarks": "Tundub, et sul pole veel järjehoidjaid. Klõpsa vestlusele ja lisa uus",
"com_ui_no_category": "Kategooriat pole",
"com_ui_no_changes": "Uuendamiseks pole muudatusi",
"com_ui_no_data": "midagi peaks siia minema. Oli tühi",
"com_ui_no_data": "Andmed puuduvad!",
"com_ui_no_terms_content": "Kuvamiseks puudub kasutustingimuste sisu",
"com_ui_no_valid_items": "midagi peaks siia minema. Oli tühi",
"com_ui_no_valid_items": "Sobivad üksused puuduvad!",
"com_ui_none": "Puudub",
"com_ui_none_selected": "Ühtegi pole valitud",
"com_ui_not_used": "Kasutamata",
"com_ui_nothing_found": "Midagi ei leitud",
"com_ui_oauth": "OAuth",
"com_ui_of": "kohta",
@ -697,6 +725,8 @@
"com_ui_read_aloud": "Loe valjusti",
"com_ui_refresh_link": "Värskenda linki",
"com_ui_regenerate": "Genereeri uuesti",
"com_ui_regenerate_backup": "Loo varukoodid uuesti",
"com_ui_regenerating": "Uuesti loomine...",
"com_ui_region": "Piirkond",
"com_ui_rename": "Nimeta ümber",
"com_ui_rename_prompt": "Nimeta sisend ümber",
@ -710,6 +740,7 @@
"com_ui_revoke_keys": "Tühista võtmed",
"com_ui_revoke_keys_confirm": "Oled sa kindel, et sa soovid kõik võtmed tühistada?",
"com_ui_role_select": "Roll",
"com_ui_roleplay": "Rollimäng",
"com_ui_run_code": "Käivita kood",
"com_ui_run_code_error": "Koodi käivitamisel tekkis viga",
"com_ui_save": "Salvesta",
@ -718,6 +749,7 @@
"com_ui_schema": "Skeem",
"com_ui_scope": "Ulatus",
"com_ui_search": "Otsi",
"com_ui_secret_key": "Salavõti",
"com_ui_select": "Vali",
"com_ui_select_file": "Vali fail",
"com_ui_select_model": "Vali mudel",
@ -732,7 +764,7 @@
"com_ui_share_create_message": "Sinu nimi ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.",
"com_ui_share_delete_error": "Jagatud lingi kustutamisel tekkis viga",
"com_ui_share_error": "Vestluslingi jagamisel tekkis viga",
"com_ui_share_form_description": "Midagi peaks siia minema. Oli tühi",
"com_ui_share_form_description": "Jaga kasutamist.",
"com_ui_share_link_to_chat": "Jaga linki vestlusele",
"com_ui_share_to_all_users": "Jaga kõigile kasutajatele",
"com_ui_share_update_message": "Sinu nimi, kohandatud juhised ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.",
@ -741,6 +773,8 @@
"com_ui_shared_link_delete_success": "Jagatud lingi kustutamine õnnestus",
"com_ui_shared_link_not_found": "Jagatud linki ei leitud",
"com_ui_shared_prompts": "Jagatud sisendid",
"com_ui_shop": "Ostlemine",
"com_ui_show": "Kuva",
"com_ui_show_all": "Näita kõiki",
"com_ui_show_qr": "Näita QR-koodi",
"com_ui_sign_in_to_domain": "Logi sisse {{0}}",
@ -752,6 +786,7 @@
"com_ui_stop": "Peata",
"com_ui_storage": "Salvestusruum",
"com_ui_submit": "Esita",
"com_ui_teach_or_explain": "Õppimine",
"com_ui_temporary_chat": "Ajutine vestlus",
"com_ui_terms_and_conditions": "Kasutustingimused",
"com_ui_terms_of_service": "Teenuse tingimused",
@ -760,6 +795,7 @@
"com_ui_token_exchange_method": "Märgi vahetamise meetod",
"com_ui_token_url": "Märgi URL",
"com_ui_tools": "Tööriistad",
"com_ui_travel": "Reisimine",
"com_ui_unarchive": "Arhiveeri lahti",
"com_ui_unarchive_error": "Vestluse arhiveerimine lahti ebaõnnestus",
"com_ui_unknown": "Tundmatu",
@ -776,13 +812,18 @@
"com_ui_upload_invalid_var": "Fail on üleslaadimiseks vigane. Peab olema pilt, mis ei ületa {{0}} MB",
"com_ui_upload_success": "Faili üleslaadimine õnnestus",
"com_ui_upload_type": "Vali üleslaadimise tüüp",
"com_ui_use_2fa_code": "Kasuta hoopis 2FA koodi",
"com_ui_use_backup_code": "Kasuta hoopis varukoodi",
"com_ui_use_micrphone": "Kasuta mikrofoni",
"com_ui_use_prompt": "Kasuta sisendit",
"com_ui_used": "Kasutatud",
"com_ui_variables": "Muutujad",
"com_ui_variables_info": "Kasuta oma tekstis topelt sulgusid, et luua muutujaid, nt `{{näidismuutuja}}`, et hiljem sisendi kasutamisel täita.",
"com_ui_verify": "Kontrolli",
"com_ui_version_var": "Versioon {{0}}",
"com_ui_versions": "Versioonid",
"com_ui_view_source": "Vaata algset vestlust",
"com_ui_write": "Kirjutamine",
"com_ui_yes": "Jah",
"com_ui_zoom": "Suumi",
"com_user_message": "Sina",

View file

@ -149,7 +149,6 @@
"com_endpoint_google_temp": "Korkeampi arvo = satunnaisempi; matalampi arvo = keskittyneempi ja deterministisempi. Suosittelemme, että muokkaat tätä tai Top P:tä, mutta ei molempia.",
"com_endpoint_google_topk": "Top-k vaikuttaa siihen, miten malli valitsee tokeineita tulokseen. Jos Top-k on 1, valitaan se token, joka on kaikkien todennäköisen mallin sanastossa (tunnetaan myös nimellä ahne dekoodaus), kun taas top-k 3 tarkoittaisi, että seuraavat token valitaan 3 todennäköisimmän tokenin joukosta, lämpötilaa hyödyntäen.",
"com_endpoint_google_topp": "Top-P vaikuttaa siihen kuinka malli valitsee tokeneita tulokseen. Tokenit valitaan top-k:sta (ks. Top-k -parametri) todennäköisimmistä vähiten todennäköseen, kunnes niiden todennäköisyyksien summa ylittää Top-P -arvon.",
"com_endpoint_import": "Tuo",
"com_endpoint_instructions_assistants": "Yliaja ohjeet",
"com_endpoint_instructions_assistants_placeholder": "Yliajaa Avustajan ohjeet. Tätä voi hyödyntää käytöksen muuttamiseen keskustelukohtaisesti.",
"com_endpoint_max_output_tokens": "Tulos-tokeneiden maksimimäärä",
@ -220,7 +219,6 @@
"com_nav_archive_name": "Nimi",
"com_nav_archived_chats": "Arkistoidut keskustelut",
"com_nav_archived_chats_empty": "Sinulla ei ole arkistoituja keskusteluita.",
"com_nav_archived_chats_manage": "Hallinnoi",
"com_nav_audio_play_error": "Virhe ääntä toistaessa: {{0}}",
"com_nav_audio_process_error": "Virhe ääntä käsitellessä: {{0}}",
"com_nav_auto_scroll": "Vieritä automaattisesti viimeisimpään viestiin keskustelua avatessa",
@ -315,7 +313,6 @@
"com_nav_setting_speech": "Puhe",
"com_nav_settings": "Asetukset",
"com_nav_shared_links": "Jaetut linkit",
"com_nav_shared_links_manage": "Hallinnoi",
"com_nav_show_code": "Kooditulkkia käyttäessä näytä aina koodi",
"com_nav_speech_to_text": "Puheesta tekstiksi",
"com_nav_text_to_speech": "Tekstistä puheeksi",
@ -461,7 +458,6 @@
"com_ui_happy_birthday": "On 1. syntymäpäiväni!",
"com_ui_host": "Host",
"com_ui_image_gen": "Kuvanluonti",
"com_ui_import_conversation": "Tuo",
"com_ui_import_conversation_error": "Keskustelujesi tuonnissa tapahtui virhe",
"com_ui_import_conversation_file_type_error": "Tiedostotyyppi ei ole tuettu tuonnissa",
"com_ui_import_conversation_info": "Tuo keskusteluja JSON-tiedostosta",

View file

@ -179,7 +179,6 @@
"com_endpoint_google_temp": "Des valeurs plus élevées = plus aléatoires, tandis que des valeurs plus faibles = plus concentrées et déterministes. Nous vous recommandons de modifier ceci ou Top P mais pas les deux.",
"com_endpoint_google_topk": "Top-k change la façon dont le modèle sélectionne les jetons pour la sortie. Un top-k de 1 signifie que le jeton sélectionné est le plus probable parmi tous les jetons du vocabulaire du modèle (également appelé décodage glouton), tandis qu'un top-k de 3 signifie que le jeton suivant est sélectionné parmi les 3 jetons les plus probables (en utilisant la température).",
"com_endpoint_google_topp": "Top-p change la façon dont le modèle sélectionne les jetons pour la sortie. Les jetons sont sélectionnés du plus K (voir le paramètre topK) probable au moins jusqu'à ce que la somme de leurs probabilités égale la valeur top-p.",
"com_endpoint_import": "Importer",
"com_endpoint_instructions_assistants": "Instructions de remplacement",
"com_endpoint_instructions_assistants_placeholder": "Remplace les instructions de l'assistant. Cela est utile pour modifier le comportement au cas par cas.",
"com_endpoint_max_output_tokens": "Nombre maximum de jetons en sortie",
@ -265,7 +264,6 @@
"com_nav_archive_name": "Nom",
"com_nav_archived_chats": "Conversations archivées",
"com_nav_archived_chats_empty": "Vous n'avez aucune conversation archivée.",
"com_nav_archived_chats_manage": "Gérer",
"com_nav_at_command": "Commande-@",
"com_nav_at_command_description": "Basculer la commande \"@\" pour changer d'endpoints, de modèles, de préréglages, etc.",
"com_nav_audio_play_error": "Erreur de lecture audio : {{0}}",
@ -388,7 +386,6 @@
"com_nav_setting_speech": "Parole",
"com_nav_settings": "Paramètres",
"com_nav_shared_links": "Liens partagés",
"com_nav_shared_links_manage": "Gérer",
"com_nav_show_code": "Toujours afficher le code lors de l'utilisation de l'interpréteur de code",
"com_nav_show_thinking": "Ovrir les menus déroulants de réflexion par défaut",
"com_nav_slash_command": "/-Commande",
@ -602,7 +599,6 @@
"com_ui_hide_qr": "Cacher le code QR",
"com_ui_host": "Hôte",
"com_ui_image_gen": "Génération d'image",
"com_ui_import_conversation": "Importer",
"com_ui_import_conversation_error": "Une erreur s'est produite lors de l'importation de vos conversations",
"com_ui_import_conversation_file_type_error": "Type de fichier non pris en charge pour l'importation",
"com_ui_import_conversation_info": "Importer des conversations à partir d'un fichier JSON",

View file

@ -1,24 +1,71 @@
{
"chat_direction_left_to_right": "חייב להיות כאן תוכן, אין אפשרות להשאיר ריק",
"chat_direction_right_to_left": "חייב להיות כאן תוכן, אין אפשרות להשאיר ריק",
"com_a11y_ai_composing": "הבינה המלאכותית (AI) עדיין יוצרת",
"com_a11y_end": "הבינה המלאכותית (AI) סיימה להשיב.",
"com_a11y_start": "הבינה המלאכותית (AI) מתחילה להשיב.",
"com_agents_allow_editing": "אפשר למשתמשים אחרים לערוך את הסוכן שלך",
"com_agents_by_librechat": "על ידי LibreChat",
"com_agents_code_interpreter": "כאשר מופעל, מאפשר לסוכן שלך למנף את ה-API של מפענח הקוד כדי להריץ את הקוד שנוצר, כולל עיבוד קבצים, בצורה מאובטחת. דורש מפתח API חוקי.",
"com_agents_code_interpreter_title": "מפענח קוד API",
"com_agents_create_error": "אירעה שגיאה ביצירת הסוכן שלך.",
"com_agents_description_placeholder": "אופציונלי: תאר את הסוכן שלך כאן",
"com_agents_enable_file_search": "אפשר חיפוש בקבצים",
"com_agents_file_search_disabled": "יש ליצור את הסוכן לפני העלאת קבצים לחיפוש",
"com_agents_file_search_info": "כאשר הסוכן מופעל הוא יקבל מידע על שמות הקבצים המפורטים להלן, כדי שהוא יוכל לאחזר את הקשר רלוונטי.",
"com_agents_instructions_placeholder": "הוראות המערכת שבהן ישתמש הסוכן",
"com_agents_missing_provider_model": "אנא בחר את הספק ואת הדגם לפני יצירת הסוכן.",
"com_agents_name_placeholder": "אופציונלי: שם הסוכן",
"com_agents_no_access": "אין לך גישה לערוך את הסוכן הזה.",
"com_agents_not_available": "הסוכן לא זמין",
"com_agents_search_name": "חפש סוכן לפי שם",
"com_agents_update_error": "אירעה שגיאה בעדכון הסוכן שלך.",
"com_assistants_action_attempt": "הסוכן מעוניין לתקשר עם {{0}}",
"com_assistants_actions": "פעולות",
"com_assistants_actions_disabled": "עליך ליצור סייען לפני הוספת פעולות.",
"com_assistants_actions_info": "אפשר לסייען לאחזר מידע או לבצע פעולות באמצעות API",
"com_assistants_add_actions": "הוסף פעולות",
"com_assistants_add_tools": "הוסף כלים",
"com_assistants_allow_sites_you_trust": "אפשר רק אתרים שאתה סומך עליהם.",
"com_assistants_append_date": "הוסף תאריך ושעה נוכחיים",
"com_assistants_append_date_tooltip": "כשמופעל, תאריך ושעה נוכחיים של הלקוח יוספים להוראות מערכת הסייען.",
"com_assistants_code_interpreter": "מתורגמן קוד",
"com_assistants_code_interpreter_files": "הקבצים הבאים זמינים רק עבור מתורגמן קוד:",
"com_assistants_attempt_info": "הסייען רוצה לשלוח את הדברים הבאים:",
"com_assistants_available_actions": "פעולות זמינות",
"com_assistants_capabilities": "יכולות",
"com_assistants_code_interpreter": "מפענח קוד",
"com_assistants_code_interpreter_files": "הקבצים הבאים זמינים רק עבור מפענח קוד:",
"com_assistants_code_interpreter_info": "מתורגמן קוד מאפשר לסייען לכתוב ולהריץ קוד. כלי זה יכול לעבד קבצים עם נתונים ועיצוב מגוונים, וליצור קבצים כגון גרפים.",
"com_assistants_completed_action": "תקשר עם {{0}}",
"com_assistants_completed_function": "מריץ {{0}}",
"com_assistants_conversation_starters": "התחלות שיחה",
"com_assistants_conversation_starters_placeholder": "הכנס פתיח לשיחה",
"com_assistants_create_error": "אירעה שגיאה ביצירת הסייען שלך.",
"com_assistants_create_success": "נוצר בהצלחה",
"com_assistants_description_placeholder": "אופציונלי: תאר את ה-סייען שלך כאן",
"com_assistants_delete_actions_error": "אירעה שגיאה במחיקת הפעולה.",
"com_assistants_delete_actions_success": "הפעולה נמחקה בהצלחה מהסייען",
"com_assistants_description_placeholder": "אופציונלי: תאר את הסייען שלך כאן",
"com_assistants_domain_info": "הסייען שלח את המידע ל{{0}}",
"com_assistants_file_search": "חיפוש קבצים",
"com_assistants_file_search_info": "חיפוש קבצים מאפשר לסייען לקבל ידע מהקבצים שאתה או המשתמשים שלך מעלים. לאחר העלאת קובץ, העוזר מחליט באופן אוטומטי מתי לאחזר תוכן על סמך בקשות המשתמש. אין תמיכה בצירוף מאגרי וקטורים לחיפוש קבצים. אתה יכול לצרף אותם ממגרש החול או לצרף קבצים להודעות לחיפוש קבצים על בסיס שרשור.",
"com_assistants_function_use": "הסייען השתמש ב{{0}}",
"com_assistants_image_vision": "מציג תמונות",
"com_assistants_instructions_placeholder": "הוראות המערכת שהסייען משתמש בהן",
"com_assistants_knowledge": "ידע",
"com_assistants_knowledge_disabled": "יש ליצור סייען, ויש להפעיל ולשמור את מתורגמן קוד או אחזור לפני העלאת קבצים כ-ידע.",
"com_assistants_knowledge_info": "אם אתה מעלה קבצים תחת ידע, שיחות עם ה-סייען שלך עשויות לכלול תוכן מהקובץ.",
"com_assistants_max_starters_reached": "הגעת למספר המקסימלי של תווים לפתיח לשיחות",
"com_assistants_name_placeholder": "אופציונלי: שם הסייען",
"com_assistants_non_retrieval_model": "חיפוש בקבצים אינו מופעל במודל הזה. אנא בחר מודל אחר",
"com_assistants_retrieval": "אחזור",
"com_assistants_running_action": "פעולות ריצה",
"com_assistants_search_name": "חפש סייען לפי שם",
"com_assistants_update_actions_error": "אירעה שגיאה ביצירה או העדכון של הפעולה.",
"com_assistants_update_actions_success": "הפעולה נוצרה או עודכנה בהצלחה",
"com_assistants_update_error": "אירעה שגיאה בעדכון הסייען שלך.",
"com_assistants_update_success": "עודכן בהצלחה",
"com_auth_already_have_account": "כבר יש לך חשבון?",
"com_auth_back_to_login": "חזרה לכניסה",
"com_auth_apple_login": "היכנס באמצעות חשבון אפל",
"com_auth_back_to_login": "חזור להתחברות",
"com_auth_click": "קליק",
"com_auth_click_here": "לחץ כאן",
"com_auth_continue": "המשך",
@ -30,12 +77,24 @@
"com_auth_email_min_length": "אימייל (דוא\"ל) חייב להיות בן 6 תווים לפחות",
"com_auth_email_pattern": "עליך להזין כתובת אימייל (דוא\"ל) חוקית",
"com_auth_email_required": "נדרש דוא\"ל",
"com_auth_email_resend_link": "שלח שוב דוא\"ל",
"com_auth_email_resent_failed": "נכשלה שליחת דוא\"ל לאימות מחדש",
"com_auth_email_resent_success": "דוא\"ל לאימות נשלח שוב בהצלחה",
"com_auth_email_verification_failed": "אימות הדוא\"ל נכשל",
"com_auth_email_verification_failed_token_missing": "האימות נכשל, חסר טוקן",
"com_auth_email_verification_in_progress": "מאמת את הדוא\"ל שלך, אנא המתן",
"com_auth_email_verification_invalid": "אימות הדוא\"ל נכשל",
"com_auth_email_verification_redirecting": "מפנה מחדש בעוד {{0}} שניות...",
"com_auth_email_verification_resend_prompt": "לא קיבלת את הדוא\"ל?",
"com_auth_email_verification_success": "הדוא\"ל אומת בהצלחה",
"com_auth_email_verifying_ellipsis": "מאמת...",
"com_auth_error_create": "אירעה שגיאה בניסיון לרשום את החשבון שלך. בבקשה נסה שוב.",
"com_auth_error_invalid_reset_token": "אסימון איפוס הסיסמה הזה אינו תקף עוד.",
"com_auth_error_login": "לא ניתן להתחבר עם המידע שסופק. אנא בדוק את האישורים שלך ונסה שוב.",
"com_auth_error_login_ban": "החשבון שלך נחסם באופן זמני עקב הפרות של השירות שלנו.",
"com_auth_error_login_rl": "יותר מדי ניסיונות כניסה בזמן קצר. בבקשה נסה שוב מאוחר יותר.",
"com_auth_error_login_server": "הייתה שגיאת שרת פנימית. אנא המתן מספר רגעים ונסה שוב.",
"com_auth_error_login_unverified": "הדוא\"ל שלך לא אומת. אנא חפש בדוא\"ל שלך קישור לאימות.",
"com_auth_facebook_login": "המשך עם פייסבוק",
"com_auth_full_name": "שם מלא",
"com_auth_github_login": "המשך עם Github",
@ -54,7 +113,10 @@
"com_auth_password_min_length": "הסיסמה חייבת להיות בת 8 תווים לפחות",
"com_auth_password_not_match": "הסיסמאות אינן תואמות",
"com_auth_password_required": "נדרשת סיסמה",
"com_auth_registration_success_generic": "אנא בדוק את הדוא\"ל שלך כדי לאמת את כתובת הדוא\"ל שלך.",
"com_auth_registration_success_insecure": "ההרשמה הצליחה",
"com_auth_reset_password": "אפס את הסיסמה שלך",
"com_auth_reset_password_if_email_exists": "אם קיים חשבון עם דוא\"ל זה, נשלח דוא\"ל עם הוראות לאיפוס סיסמה. אנא הקפד לבדוק גם בתיקיית הספאם שלך.",
"com_auth_reset_password_link_sent": "אימייל (דוא\"ל) נשלח",
"com_auth_reset_password_success": "איפוס סיסמה הצליח",
"com_auth_sign_in": "כניסה",
@ -62,19 +124,29 @@
"com_auth_submit_registration": "שלח רישום",
"com_auth_to_reset_your_password": "כדי לאפס את הסיסמה שלך.",
"com_auth_to_try_again": "כדי לנסות שוב.",
"com_auth_two_factor": "בדוק את יישום הסיסמה החד-פעמית שלך לקבלת קוד",
"com_auth_username": "שם משתמש (אופציונלי)",
"com_auth_username_max_length": "שם המשתמש חייב להיות פחות מ-20 תווים",
"com_auth_username_min_length": "שם משתמש חייב להיות לפחות 2 תווים",
"com_auth_verify_your_identity": "אמת את הזהות שלך",
"com_auth_welcome_back": "ברוכים הבאים",
"com_click_to_download": "(לחץ כאן להורדה)",
"com_download_expired": "(פג תוקף ההורדה)",
"com_download_expires": "(לחץ כאן כדי להוריד - יפוג בעוד {{0}}) ",
"com_endpoint": "נקודת קצה",
"com_endpoint_agent": "סוכן",
"com_endpoint_agent_model": "מודל סוכן (מומלץ: GPT-3.5)",
"com_endpoint_agent_placeholder": "אנא בחר סוכן",
"com_endpoint_anthropic_maxoutputtokens": "מספר האסימונים המרבי שניתן להפיק בתגובה. ציין ערך נמוך יותר עבור תגובות קצרות יותר וערך גבוה יותר עבור תגובות ארוכות יותר.",
"com_endpoint_anthropic_prompt_cache": "שמירת מטמון מהירה מאפשרת שימוש חוזר בהקשר גדול או בהוראות בקריאות API, תוך הפחתת העלויות וההשהייה",
"com_endpoint_anthropic_temp": "נע בין 0 ל-1. השתמש בטמפ' הקרובה יותר ל-0 עבור בחירה אנליטית / מרובה, וקרוב יותר ל-1 עבור משימות יצירתיות ויצירתיות. אנו ממליצים לשנות את זה או את Top P אבל לא את שניהם.",
"com_endpoint_anthropic_thinking": "מאפשר חשיבה פנימית עבור דגמי Claude נתמכים (3.7 Sonnet). הערה: דורש שההגדרה של 'תקציב חשיבה' תהיה נמוכה מ'מקסימום טוקנים לפלט'",
"com_endpoint_anthropic_thinking_budget": "קובע את מספר הטוקנים המקסימלי שקלוד רשאי להשתמש בו עבור תהליך החשיבה הפנימי. תקציב גבוה יותר עשוי לשפר את איכות התשובה על ידי מתן אפשרות לניתוח מעמיק יותר של בעיות מורכבות, אם כי קלוד לא בהכרח ישתמש בכל התקציב שהוקצה, במיוחד בטווחים שמעל 32K. הגדרה זו חייבת להיות נמוכה מ'מקסימום טוקנים לפלט'.",
"com_endpoint_anthropic_topk": "Top-k משנה את האופן שבו המודל בוחר אסימונים לפלט. Top-k של 1 פירושו שהאסימון שנבחר הוא הסביר ביותר מבין כל האסימונים באוצר המילים של הדגם (נקרא גם פענוח חמדן), בעוד ש-top-k של 3 פירושו שהאסימון הבא נבחר מבין 3 הכי הרבה. אסימונים סבירים (באמצעות טמפרטורה).",
"com_endpoint_anthropic_topp": "Top-p משנה את האופן שבו המודל בוחר אסימונים לפלט. אסימונים נבחרים מבין רוב K (ראה פרמטר topK) הסביר לפחות עד שסכום ההסתברויות שלהם שווה לערך העליון-p.",
"com_endpoint_assistant": "סייען",
"com_endpoint_assistant_model": "מודל סייען",
"com_endpoint_assistant_placeholder": "אנא בחר סייען מלוח הצד הימני",
"com_endpoint_completion": "השלמה",
"com_endpoint_completion_model": "מודל השלמה (מומלץ: GPT-4)",
"com_endpoint_config_click_here": "לחץ כאן",
@ -95,16 +167,20 @@
"com_endpoint_config_key_import_json_key_invalid": "מפתח JSON חשבון שירות לא חוקי, האם ייבאת את הקובץ הנכון?",
"com_endpoint_config_key_import_json_key_success": "מפתח JSON של חשבון שירות יובא בהצלחה",
"com_endpoint_config_key_name": "מפתח",
"com_endpoint_config_key_never_expires": "המפתח שלך לא יפוג לעולם",
"com_endpoint_config_placeholder": "הגדר את המפתח שלך בתפריט הכותרת לצאט.",
"com_endpoint_config_value": "הזן ערך עבור",
"com_endpoint_context": "הקשר",
"com_endpoint_context_info": "המספר המרבי של הטוקנים שניתן להשתמש בהם בחלון ההקשר. השתמש בזה כדי לשלוט בכמה טוקנים ישלחו בכל בקשה. אם לא צוין, יתבצע שימוש בברירת המחדל של המערכת המבוססות על גודל חלון ההקשר ברירת המחדל של המודלים. הגדרת ערכים גבוהים יותר עלולה לגרום לשגיאות ו/או עלות טוקנים גבוהה יותר.",
"com_endpoint_context_tokens": "מקסימום טוקנים בחלון ההקשר",
"com_endpoint_custom_name": "שם מותאם אישית",
"com_endpoint_default": "default",
"com_endpoint_default": "ברירת מחדל",
"com_endpoint_default_blank": "ברירת מחדל: ריק",
"com_endpoint_default_empty": "ברירת מחדל: ריקה",
"com_endpoint_default_with_num": "ברירת מחדל: {{0}}",
"com_endpoint_examples": "הגדרות קבועות מראש",
"com_endpoint_export": "ייצוא",
"com_endpoint_export_share": "ייצא/שתף",
"com_endpoint_frequency_penalty": "עונש תדירות",
"com_endpoint_func_hover": "אפשר שימוש בפלאגינים כפונקציות OpenAI",
"com_endpoint_google_custom_name_placeholder": "הגדר שם מותאם אישית עבור Google",
@ -116,6 +192,7 @@
"com_endpoint_instructions_assistants_placeholder": "עובר את הוראות הסייען. זה שימושי לשינוי ההתנהגות על בסיס ריצה.",
"com_endpoint_max_output_tokens": "אסימוני פלט מרבי",
"com_endpoint_message": "הודעה",
"com_endpoint_message_new": "הודעה {{0}}",
"com_endpoint_message_not_appendable": "ערוך את ההודעה שלך או צור מחדש.",
"com_endpoint_my_preset": "ההגדרה המוגדרת מראש שלי",
"com_endpoint_no_presets": "אין עדיין הגדרות מוגדרות מראש, השתמש בלחצן ההגדרות כדי ליצור אחת",
@ -124,19 +201,25 @@
"com_endpoint_openai_detail": "ההחלטה לבקשות חזון. \"נמוך\" זול ומהיר יותר, \"גבוה\" מפורט ויקר יותר, ו\"אוטומטי\" יבחר אוטומטית בין השניים על סמך רזולוציית התמונה.",
"com_endpoint_openai_freq": "מספר בין -2.0 ל-2.0. ערכים חיוביים מענישים אסימונים חדשים בהתבסס על התדירות הקיימת שלהם בטקסט עד כה, ומקטינים את הסבירות של המודל לחזור על אותה שורה מילה במילה.",
"com_endpoint_openai_max": "האסימונים המקסימליים להפיק. האורך הכולל של אסימוני קלט ואסימונים שנוצרו מוגבל על ידי אורך ההקשר של המודל.",
"com_endpoint_openai_max_tokens": "שדה 'max_tokens' אופציונלי, הוא מייצג את המספר המרבי של טוקנים שניתן ליצור בהשלמת הצ'אט. האורך הכולל של טוקני קלט והטוקנים שנוצרו מוגבל על ידי אורך ההקשר של המודל. אתה עלול להיתקל בשגיאות אם המספר הזה חורג מטוקני ההקשר המקסימליים.",
"com_endpoint_openai_pres": "מספר בין -2.0 ל-2.0. ערכים חיוביים מענישים אסימונים חדשים על סמך האם הם מופיעים בטקסט עד כה, ומגדילים את הסבירות של המודל לדבר על נושאים חדשים.",
"com_endpoint_openai_prompt_prefix_placeholder": "הגדר הוראות מותאמות אישית לכלול בהודעת המערכת. ברירת מחדל: אין",
"com_endpoint_openai_reasoning_effort": "במודלים o1 בלבד: מגביל את מאמץ ההנמקה במודלים של הגיון. הפחתת מאמץ החשיבה יכולה לגרום לתגובות מהירות יותר ולפחות טוקנים בשימוש בהנמקה בתגובה.",
"com_endpoint_openai_resend": "שלח שוב את כל התמונות שצורפו בעבר. הערה: זה יכול להגדיל משמעותית את עלות האסימונים ואתה עלול להיתקל בשגיאות עם קבצים מצורפים רבים של תמונות.",
"com_endpoint_openai_resend_files": "שלח שוב את כל הקבצים שצורפו בעבר. הערה: זה יגדיל את עלות הטוקנים, ואתה עלול להיתקל בשגיאות עם קבצים מצורפים רבים.",
"com_endpoint_openai_stop": "עד 4 רצפים שבהם ה-API יפסיק לייצר טוקנים נוספים.",
"com_endpoint_openai_temp": "ערכים גבוהים יותר = יותר אקראיים, בעוד שערכים נמוכים יותר = יותר ממוקד ודטרמיניסטי. אנו ממליצים לשנות את זה או את Top P אבל לא את שניהם.",
"com_endpoint_openai_topp": "חלופה לדגימה עם טמפרטורה, הנקראת דגימת גרעין, שבה המודל מחשיב את תוצאות האסימונים עם מסת ההסתברות top_p. אז 0.1 אומר שרק האסימונים המהווים את מסת ההסתברות העליונה של 10% נחשבים. אנו ממליצים לשנות את זה או את הטמפרטורה אבל לא את שניהם.",
"com_endpoint_output": "פלט",
"com_endpoint_plug_image_detail": "פרטי תמונה",
"com_endpoint_plug_resend_files": "שלח שוב את הקובץ",
"com_endpoint_plug_set_custom_instructions_for_gpt_placeholder": "הגדר הוראות מותאמות אישית לכלול בהודעת המערכת. ברירת מחדל: אין",
"com_endpoint_plug_skip_completion": "השלמת דילוג",
"com_endpoint_plug_use_functions": "השתמש בפונקציות",
"com_endpoint_presence_penalty": "עונש נוכחות",
"com_endpoint_preset": "preset",
"com_endpoint_preset_default": "הוא כעת ברירת המחדל המוגדרת מראש.",
"com_endpoint_preset": "הגדרה קבועה מראש",
"com_endpoint_preset_custom_name_placeholder": "אין אפשרות להשאיר את השדה הזה ריק, חייב לביות כאן ערך",
"com_endpoint_preset_default": "מוגדר כמו הגדרות ברירת המחדל המוגדרת מראש.",
"com_endpoint_preset_default_item": "ברירת מחדל:",
"com_endpoint_preset_default_none": "אין ברירת מחדל פעילה.",
"com_endpoint_preset_default_removed": "איננו עוד ברירת המחדל המוגדרת מראש.",
@ -151,32 +234,90 @@
"com_endpoint_preset_title": "הגדרה מראש",
"com_endpoint_presets": "presets",
"com_endpoint_presets_clear_warning": "האם אתה בטוח שאתה רוצה לנקות את כל הקביעות המוגדרות מראש? זה בלתי הפיך.",
"com_endpoint_prompt_cache": "השתמש בשמירה במטמון של הנחיות (פרומפטים)",
"com_endpoint_prompt_prefix": "הוראות מותאמות אישית",
"com_endpoint_prompt_prefix_assistants": "הוראות נוספות",
"com_endpoint_prompt_prefix_assistants_placeholder": "הגדר הוראות נוספות או הקשר על גבי ההנחיות הראשיות של ה-סייען. התעלמו אם ריק.",
"com_endpoint_prompt_prefix_placeholder": "הגדר הוראות מותאמות אישית או הקשר. התעלמו אם ריק.",
"com_endpoint_save_as_preset": "שמור כ-preset",
"com_endpoint_reasoning_effort": "מאמץ בתהליך החשיבה",
"com_endpoint_save_as_preset": "שמור כתבנית",
"com_endpoint_search": "חפש נקודת קצה לפי שם",
"com_endpoint_set_custom_name": "הגדר שם מותאם אישית, למקרה שתוכל למצוא את הקביעה המוגדרת מראש",
"com_endpoint_skip_hover": "אפשר דילוג על שלב ההשלמה, הסוקר את התשובה הסופית ואת השלבים שנוצרו",
"com_endpoint_stop": "רצף לעצירה",
"com_endpoint_stop_placeholder": "הפרד ערכים על ידי לחיצה על 'Enter'",
"com_endpoint_temperature": "טמפרטורה",
"com_endpoint_thinking": "חשיבה",
"com_endpoint_thinking_budget": "תקציב חשיבה",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "השתמש ב-סייען פעיל",
"com_error_expired_user_key": "המפתח שסופק עבור {{0}} פג ב-{{1}}. אנא ספק מפתח חדש ונסה שוב.",
"com_error_files_dupe": "זוהה קובץ כפול",
"com_error_files_empty": "אין אפשרות לקבצים ריקים",
"com_error_files_process": "אירעה שגיאה במהלך עיבוד הקובץ.",
"com_error_files_unsupported_capability": "לא הופעלו התכונות התומכות בסוג קובץ זה.",
"com_error_files_upload": "אירעה שגיאה בעת העלאת הקובץ",
"com_error_files_upload_canceled": "בקשת העלאת הקובץ בוטלה. הערה: ייתכן שהעלאת הקובץ עדיין בעיבוד ותצטרך למחוק אותו בצורה ידנית.",
"com_error_files_validation": "אירעה שגיאה במהלך אימות הקובץ.",
"com_error_input_length": "מספר הטוקנים של ההודעות האחרונות גבוה מדי, והוא חורג ממגבלת האסימונים ({{0}} בהתאמה). אנא קצר את ההודעה שלך, שנה את גודל ההקשר המקסימלי בפרמטרי השיחה, או התחל שיחה חדשה.",
"com_error_invalid_user_key": "מפתח שסופק אינו חוקי. אנא ספק מפתח חוקי ונסה שוב.",
"com_error_moderation": "נראה שהתוכן שנשלח סומן על ידי מערכת הניהול שלנו בגלל שהוא אינו תואם את הנחיות הקהילה שלנו. אנחנו לא יכולים להמשיך עם הנושא הספציפי הזה. אם יש לך שאלות או נושאים אחרים שתרצה לחקור, אנא ערוך את ההודעה שלך, או צור שיחה חדשה.",
"com_error_no_base_url": "לא נמצאה כתובת URL. אנא ספק כתובת ונסה שוב.",
"com_error_no_user_key": "לא נמצא מפתח. אנא ספק מפתח ונסה שוב.",
"com_files_filter": "סינון קבצים...",
"com_files_no_results": "אין תוצאות",
"com_files_number_selected": "{{0}} מתוך {{1}} פריטים נבחרו",
"com_files_table": "השדה חייב להכיל תוכן, הוא אינו יכול להישאר ריק",
"com_generated_files": "קבצים שנוצרו:",
"com_hide_examples": "הסתר דוגמאות",
"com_nav_archive_created_at": "תאריך יצרן",
"com_nav_2fa": "אימות דו-שלבי (2FA)",
"com_nav_account_settings": "הגדרות חשבון",
"com_nav_always_make_prod": "ייצר תמיד גרסאות חדשות",
"com_nav_archive_created_at": "תאריך ייצור",
"com_nav_archive_name": "שם",
"com_nav_archived_chats": "שיחות מארכיון",
"com_nav_archived_chats_empty": "אין שיחות מארכיון.",
"com_nav_archived_chats_manage": "ניהול",
"com_nav_at_command": "@-פקודה",
"com_nav_at_command_description": "הפקודה \"@\" משמשת כמנגנון הפעלה/החלפה של נקודות קצה, מודלים, הגדרות קבועות מראש וכו'.",
"com_nav_audio_play_error": "שגיאה בהפעלת אודיו: {{0}}",
"com_nav_audio_process_error": "שגיאה בעיבוד האודיו: {{0}}",
"com_nav_auto_scroll": "Auto-s גלול אל הכי חדש בפתיחה",
"com_nav_auto_send_prompts": "שליחת הנחיות (פרומפטים) אוטומטית",
"com_nav_auto_send_text": "טקסט לשליחה אוטומטית",
"com_nav_auto_send_text_disabled": "הגדר -1 כדי להשבית",
"com_nav_auto_transcribe_audio": "תמלול אוטומטי של אודיו",
"com_nav_automatic_playback": "הפעלה אוטומטית של ההודעה האחרונה",
"com_nav_balance": "לְאַזֵן",
"com_nav_browser": "דפדפן",
"com_nav_buffer_append_error": "בעיה בהזרמת אודיו. ההשמעה עשויה להיות מקוטעת.",
"com_nav_change_picture": "שנה תמונה",
"com_nav_chat_commands": "פקודות צ'אט",
"com_nav_chat_commands_info": "פקודות אלו מופעלות על ידי הקלדת תווים ספציפיים בתחילת ההודעה. כל פקודה מופעלת על ידי הקידומת המיועדת לה. אתה יכול להשבית אותם אם אתה משתמש בתווים אלה לעתים קרובות כדי להתחיל הודעות.",
"com_nav_chat_direction": "כיוונון צ'אט",
"com_nav_clear_all_chats": "נקה את כל השיחות",
"com_nav_clear_cache_confirm_message": "האם אתה בטוח שברצונך לנקות את המטמון?",
"com_nav_clear_conversation": "נקה שיחות",
"com_nav_clear_conversation_confirm_message": "אתה בטוח שאתה רוצה לנקות את כל השיחות? זה בלתי הפיך.",
"com_nav_close_sidebar": "סגור סרגל צד",
"com_nav_confirm_clear": "אשר נקה",
"com_nav_commands": "פקודות",
"com_nav_confirm_clear": "אשר ניקוי",
"com_nav_conversation_mode": "מצב שיחה",
"com_nav_convo_menu_options": "אפשרויות מצב שיחה",
"com_nav_db_sensitivity": "רגישות דציבלים",
"com_nav_delete_account": "מחיקת החשבון",
"com_nav_delete_account_button": "מחק את החשבון שלי לצמיתות",
"com_nav_delete_account_confirm": "מחק חשבון - אתה בטוח?",
"com_nav_delete_account_email_placeholder": "אנא הזן את כתובת הדוא\"ל של החשבון שלך",
"com_nav_delete_cache_storage": "מחק אחסון מטמון TTS",
"com_nav_delete_data_info": "כל הנתונים שלך יימחקו",
"com_nav_delete_warning": "אזהרה: פעולה זו תמחק לצמיתות את חשבונך.",
"com_nav_edge": "נקודת קצה",
"com_nav_enable_cache_tts": "אפשר מטמון ב- TTS",
"com_nav_enable_cloud_browser_voice": "השתמש בקולות מבוססי ענן",
"com_nav_enabled": "מופעל",
"com_nav_engine": "מנוע",
"com_nav_enter_to_send": "הקש Enter כדי לשלוח את ההודעה",
"com_nav_export": "ייצא",
"com_nav_export_all_message_branches": "ייצא את כל ענפי ההודעות",
"com_nav_export_conversation": "ייצא שיחה",
@ -186,151 +327,506 @@
"com_nav_export_recursive": "רקורסיבי",
"com_nav_export_recursive_or_sequential": "רקורסיבי או רציף?",
"com_nav_export_type": "סוג",
"com_nav_external": "חיצוני",
"com_nav_font_size": "גודל גופן",
"com_nav_font_size_base": "מדיום",
"com_nav_font_size_lg": "גדול",
"com_nav_font_size_sm": "קטן",
"com_nav_font_size_xl": "גדול מאוד",
"com_nav_font_size_xs": "קט מאוד",
"com_nav_help_faq": "עזרה ושאלות נפוצות",
"com_nav_hide_panel": "הסתר לוח הצד הימני ביותר",
"com_nav_lang_arabic": "العربية",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_chinese": "中文",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_finnish": "Suomi",
"com_nav_lang_french": "Français ",
"com_nav_lang_german": "Deutsch",
"com_nav_info_code_artifacts": "אפשר הצגה של רכיבי תצוגת קוד ניסיוניים לצד הצ'אט",
"com_nav_info_code_artifacts_agent": "אפשר שימוש ברכיבי תצוגת קוד עבור סוכן זה כברירת מחדל, מתווספות הוראות נוספות ספציפיות לשימוש ברכיבי התצוגה אלא אם \"מצב הנחיה מותאם אישית\" מופעל.",
"com_nav_info_custom_prompt_mode": "כאשר אפשרות זו מופעלת, הנחיית ברירת המחדל של מערכת רכיבי תצוגה לא תיכלל. כל ההוראות ליצירת רכיבי תצוגה יהיו חייבות להינתן באופן ידני במצב זה.",
"com_nav_info_enter_to_send": "כאשר מופעל, לחיצה על \"ENTER\" תשלח את ההודעה שלך, כאשר מושבת לחיצה על \"Enter\" תוסיף שורה חדשה, ותצטרך ללחוץ על \"CTRL + ENTER\" כדי לשלוח את ההודעה.",
"com_nav_info_fork_change_default": "'הודעות ישירות בלבד' כולל רק את הנתיב הישיר להודעה שנבחרה. 'כלול הסתעפויות קשורות' מוסיף את כל ההסתעפויות הקשורות לאורך הנתיב. 'כלול הכל עד כאן/מכאן' כולל את כל ההודעות וההסתעפויות המחוברות.",
"com_nav_info_fork_split_target_setting": "כאשר אפשרות זו מופעלת, הפיצול יתחיל מהודעת היעד ועד להודעה האחרונה בשיחה, בהתאם להתנהגות שנבחרה",
"com_nav_info_include_shadcnui": "כאשר אפשרות זו מופעלת, ייכללו הוראות לשימוש ברכיבי shadcn/ui. shadcn/ui הוא אוסף של רכיבים לשימוש חוזר שנבנו באמצעות Radix UI ו-Tailwind CSS.\nהערה: ההוראות הללו ארוכות, ולכן כדאי להפעיל אותן רק אם חשוב לך ליידע את מודל ה-LLM (מודל השפה) על הייבוא והרכיבים הנכונים.\nלמידע נוסף על רכיבים אלה, בקר בכתובת: https://ui.shadcn.com/",
"com_nav_info_latex_parsing": "כאשר אפשרות זו מופעלת, קוד LaTeX בהודעות יעובד ויוצג כמשוואות מתמטיות. השבתת אפשרות זו עשויה לשפר את הביצועים אם אינך זקוק לעיבוד LaTeX.",
"com_nav_info_save_draft": "כאשר אפשרות זו מופעלת, הטקסט והקבצים המצורפים שאתה מזין בטופס הצ'אט יישמרו באופן אוטומטי כטיוטות במכשיר שלך. טיוטות אלו יהיו זמינות גם אם תטען מחדש את הדף או תעבור לשיחה אחרת. הטיוטות נשמרות באופן מקומי במכשיר שלך ונמחקות לאחר שליחת ההודעה.",
"com_nav_info_show_thinking": "כאשר אפשרות זו מופעלת, תיבות תצוגה שמציגות את תהליך החשיבה של הבינה המלאכותית יופיעו פתוחות כברירת מחדל, כך שתוכל לראות את תהליך הניתוח בזמן אמת. כאשר האפשרות מושבתת, תיבות הבחירה יישארו סגורות כברירת מחדל, מה שיוצר ממשק נקי וזורם יותר.",
"com_nav_info_user_name_display": "כאשר אפשרות זו מופעלת, שם המשתמש של השולח יוצג מעל כל הודעה שאתה שולח. כאשר האפשרות מושבתת, יוצג רק הכיתוב \"אתה\" מעל ההודעות שלך.",
"com_nav_lang_arabic": "ערבית (العربية)",
"com_nav_lang_auto": "זיהוי באופן אוטומטי",
"com_nav_lang_brazilian_portuguese": "פורטוגזית ברזילאית (Português Brasileiro)",
"com_nav_lang_chinese": "סינית (中文)",
"com_nav_lang_dutch": "הולנדית (Nederlands)",
"com_nav_lang_english": "אנגלית (English)",
"com_nav_lang_estonian": "אסטונית (Eesti keel)",
"com_nav_lang_finnish": "פינית (Suomi)",
"com_nav_lang_french": "צרפתית (Français)",
"com_nav_lang_german": "גרמנית (Deutsch)",
"com_nav_lang_hebrew": "עברית",
"com_nav_lang_indonesia": "Indonesia",
"com_nav_lang_italian": "Italiano",
"com_nav_lang_japanese": "日本語",
"com_nav_lang_korean": "한국어",
"com_nav_lang_polish": "Polski",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_russian": "Русский",
"com_nav_lang_spanish": "Español",
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_indonesia": "אינדונזית (Indonesia)",
"com_nav_lang_italian": "איטלקית (Italiano)",
"com_nav_lang_japanese": "יפנית (日本語)",
"com_nav_lang_korean": "קוראנית (한국어)",
"com_nav_lang_polish": "פולנית (Polski)",
"com_nav_lang_portuguese": "פורטוגזית (Português)",
"com_nav_lang_russian": "רוסית (Русский)",
"com_nav_lang_spanish": "ספרדית (Español)",
"com_nav_lang_swedish": "שוודית (Svenska)",
"com_nav_lang_traditional_chinese": "סינית מסורתית (繁體中文)",
"com_nav_lang_turkish": "טורקית (Türkçe)",
"com_nav_lang_vietnamese": "וייטנאמית (Tiếng Việt)",
"com_nav_language": "שפה",
"com_nav_latex_parsing": "ניתוח LaTeX בהודעות (עשוי להשפיע על הביצועים)",
"com_nav_log_out": "צא",
"com_nav_long_audio_warning": "העיבוד של טקסטים ארוכים ייקח יותר זמן.",
"com_nav_maximize_chat_space": "הגדל את שטח הצ'אט",
"com_nav_modular_chat": "אפשר החלפת נקודות קצה באמצע שיחה",
"com_nav_my_files": "הקבצים שלי",
"com_nav_no_search_results": "לא נמצאו תוצאות בחיפוש",
"com_nav_not_supported": "לא נתמך",
"com_nav_open_sidebar": "פתח סרגל צד",
"com_nav_playback_rate": "קצב השמעת האודיו",
"com_nav_plugin_auth_error": "אירעה שגיאה בניסיון לאמת את הפלאגין הזה. בבקשה נסה שוב.",
"com_nav_plugin_install": "התקן",
"com_nav_plugin_search": "תוספי חיפוש",
"com_nav_plugin_store": "חנות פלאגין",
"com_nav_plugin_uninstall": "הסר התקנה",
"com_nav_plus_command": "פקודות+-",
"com_nav_plus_command_description": "הפעל או בטל את הפקודה '+' כדי להוסיף הגדרת תגובות מרובות",
"com_nav_profile_picture": "תמונת פרופיל",
"com_nav_save_drafts": "שמיר את האפצה באותו מחשב",
"com_nav_scroll_button": "לחצן לגלילה עד הסוף",
"com_nav_search_placeholder": "חפש הודעות",
"com_nav_send_message": "שלח הודעה",
"com_nav_setting_account": "חשבון",
"com_nav_setting_beta": "תכונות ביטא",
"com_nav_setting_chat": "צ'אט",
"com_nav_setting_data": "בקרות נתונים",
"com_nav_setting_general": "כללי",
"com_nav_setting_speech": "דיבור",
"com_nav_settings": "הגדרות",
"com_nav_shared_links": "קישורים משותפים",
"com_nav_shared_links_manage": "ניהול",
"com_nav_show_code": "הצג תמיד את הקוד בעת שימוש במפענח הקוד.",
"com_nav_show_thinking": "פתח תצוגות חשיבה כברירת מחדל",
"com_nav_slash_command": "פקודת/-",
"com_nav_slash_command_description": "הפעל/כבה את הפקודה '/' לבחירת הנחיה (פרומפט) באמצעות המקלדת.",
"com_nav_source_buffer_error": "שגיאה בהגדרת השמעת האודיו. אנא רענן את הדף",
"com_nav_speech_cancel_error": "לא ניתן להפסיק את השמעת האודיו. ייתכן שתצטרך לרענן את הדף.",
"com_nav_speech_to_text": "דיבור לטקסט",
"com_nav_stop_generating": "עצור את היצירה",
"com_nav_text_to_speech": "טקסט לדיבור",
"com_nav_theme": "נושא",
"com_nav_theme_dark": "כהה",
"com_nav_theme_light": "אור",
"com_nav_theme_system": "מערכת",
"com_nav_tool_dialog": "כלי סייען",
"com_nav_tool_dialog_agents": "כלי סוכנים",
"com_nav_tool_dialog_description": "יש לשמור את האסיסטנט כדי להמשיך בבחירת הכלים.",
"com_nav_tool_remove": "הסר",
"com_nav_tool_search": "כלי חיפוש",
"com_nav_user": "USER",
"com_nav_tts_init_error": "כשל ניסיון אתחול ההמרה מטקסט לדיבור: {{0}}",
"com_nav_tts_unsupported_error": "המרה מטקסט לדיבור עבור המנוע הנבחר אינה נתמכת בדפדפן זה.",
"com_nav_user": "משתמש",
"com_nav_user_msg_markdown": "הצגת הודעות משתמש כ-Markdown",
"com_nav_user_name_display": "הצג שם משתמש בהודעות",
"com_nav_welcome_message": "איך אני יכול לעזור לך היום?",
"com_nav_voice_select": "קול",
"com_nav_voices_fetch_error": "לא ניתן לאחזר אפשרויות קול. אנא בדוק את חיבור האינטרנט שלך.",
"com_nav_welcome_agent": "אנא בחר סוכן",
"com_nav_welcome_assistant": "אנא בחר סיייען",
"com_nav_welcome_message": "?איך אני יכול לעזור לך היום",
"com_show_agent_settings": "הצג הגדרות סוכן",
"com_show_completion_settings": "הצג הגדרות השלמה",
"com_show_examples": "הצג דוגמאות",
"com_sidepanel_agent_builder": "בניית סוכן",
"com_sidepanel_assistant_builder": "בניית סייען",
"com_sidepanel_attach_files": "צרף קבצים",
"com_sidepanel_conversation_tags": "סימניות",
"com_sidepanel_hide_panel": "הסתר פאנל",
"com_sidepanel_manage_files": "נהל קבצים",
"com_sidepanel_parameters": "פרמטרים",
"com_sidepanel_select_agent": "בחר סוכן",
"com_sidepanel_select_assistant": "בחר סייען",
"com_ui_2fa_account_security": "אימות דו-שלבי מוסיף שכבת אבטחה נוספת לחשבון שלך",
"com_ui_2fa_disable": "השבת אימות דו-שלבי (2FA)",
"com_ui_2fa_disable_error": "התרחשה שגיאה בעת ביטול האימות הדו-שלבי",
"com_ui_2fa_disabled": "האימות הדו-שלבי הושבת (2FA)",
"com_ui_2fa_enable": "אפשר אימות דו-שלבי (2FA)",
"com_ui_2fa_enabled": "האימות הדו-שלבי (2FA) הופעל",
"com_ui_2fa_generate_error": "תרחשה שגיאה בעת יצירת הגדרות האימות הדו-שלבי (2FA)",
"com_ui_2fa_invalid": "קוד האימות הדו-שלבי שגוי",
"com_ui_2fa_setup": "הגדר אימות דו-שלבי (2FA)",
"com_ui_2fa_verified": "האימות הדו-שלבי אומת בהצלחה",
"com_ui_accept": "אני מקבל",
"com_ui_add": "הוסף",
"com_ui_add_model_preset": "הוספת מודל או הגדרה קבועה לתגובה נוספת",
"com_ui_add_multi_conversation": "הוספת תמיכה בשיחות מרובות",
"com_ui_admin": "אדמין",
"com_ui_admin_access_warning": "השבתת גישת המנהל לתכונה זו עלולה לגרום לבעיות בלתי צפויות בממשק המשתמש שידרשו רענון. אם השינוי נשמר, הדרך היחידה להחזיר את ההגדרה היא דרך הגדרת הממשק בקובץ librechat.yaml, שמשפיעה על כל התפקידים.",
"com_ui_admin_settings": "הגדרות אדמין",
"com_ui_advanced": "מתקדם",
"com_ui_agent": "סוכן",
"com_ui_agent_delete_error": "אירעה שגיאה בעת מחיקת הסוכן.",
"com_ui_agent_deleted": "הסוכן נמחק בהצלחה.",
"com_ui_agent_duplicate_error": "אירעה שגיאה בעת שכפול הסוכן",
"com_ui_agent_duplicated": "הסוכן שוכפל בהצלחה",
"com_ui_agent_editing_allowed": "משתמשים אחרים יכולים כבר לערוך את הסוכן.",
"com_ui_agent_shared_to_all": "השדה חייב להכיל תוכן, אי אפשר להשאיר אותו ריק",
"com_ui_agents": "סוכנים",
"com_ui_agents_allow_create": "אפשר יצירת סוכנים",
"com_ui_agents_allow_share_global": "אפשר שיתוף סוכנים לכל המשתמשים",
"com_ui_agents_allow_use": "אפשר שימוש בסוכנים",
"com_ui_all": "הכל",
"com_ui_all_proper": "הכל",
"com_ui_analyzing": "ניתוח",
"com_ui_analyzing_finished": "סיים ניתוח",
"com_ui_api_key": "מפתח API",
"com_ui_archive": "ארכיון",
"com_ui_archive_error": "אירעה שגיאה בארכיון השיחה",
"com_ui_archive_error": "אירעה שגיאה באירכוב השיחה",
"com_ui_artifact_click": "לחץ לפתיחה",
"com_ui_artifacts": "רכיבי תצוגה",
"com_ui_artifacts_toggle": "הפעל/כבה רכיבי תצוגה",
"com_ui_artifacts_toggle_agent": "אפשר רכיבי תצוגה",
"com_ui_ascending": "סדר עולה",
"com_ui_assistant": "סייען",
"com_ui_assistant_delete_error": "אירעה שגיאה בעת מחיקת הסייען",
"com_ui_assistant_deleted": "הסייען נמחק בהצלחה",
"com_ui_assistants": "סייען",
"com_ui_assistants_output": "פלט סייענים",
"com_ui_attach_error": "לא ניתן לצרף קובץ. צור או בחר שיחה, או נסה לרענן את הדף.",
"com_ui_attach_error_openai": "לא ניתן לצרף את קבצי הסייען לנקודות קצה אחרות",
"com_ui_attach_error_size": "חרגת ממגבלת גודל הקובץ עבור נקודת הקצה:",
"com_ui_attach_error_type": "סוג קובץ לא נתמך עבור נקודת קצה:",
"com_ui_attach_warn_endpoint": "עשוי להתעלם מקבצים שאינם של הסייען שאין להם כלי תואם",
"com_ui_attachment": "קובץ מצורף",
"com_ui_auth_type": "סוג אישור",
"com_ui_auth_url": "כתובת URL לאימות הרשאה",
"com_ui_authentication": "אימות",
"com_ui_authentication_type": "סוג אימות",
"com_ui_avatar": "אווטאר",
"com_ui_back_to_chat": "חזור לצ'אט",
"com_ui_back_to_prompts": "חזור להנחיות (פרומפטים)",
"com_ui_backup_codes": "קודי גיבוי",
"com_ui_backup_codes_regenerate_error": "אירעה שגיאה בעת יצירת קודי הגיבוי מחדש",
"com_ui_backup_codes_regenerated": "קודי הגיבוי נוצרו מחדש בהצלחה",
"com_ui_basic": "בסיסי",
"com_ui_basic_auth_header": "כותרת אימות בסיסי",
"com_ui_bearer": "נושא הרשאה",
"com_ui_bookmark_delete_confirm": "האם אתה בטוח שברצונך למחוק את הסימניה הזו?",
"com_ui_bookmarks": "סימניות",
"com_ui_bookmarks_add": "הוסף סימניות",
"com_ui_bookmarks_add_to_conversation": "הוסף לשיחה הנוכחית",
"com_ui_bookmarks_count": "ספירה",
"com_ui_bookmarks_create_error": "אירעה שגיאה בעת יצירת הסימניה",
"com_ui_bookmarks_create_exists": "סימניה זו כבר קיימת",
"com_ui_bookmarks_create_success": "הסימניה נוצרה בהצלחה",
"com_ui_bookmarks_delete": "מחק סימ",
"com_ui_bookmarks_delete_error": "אירעה שגיאה בעת מחיקת הסימניה",
"com_ui_bookmarks_delete_success": "הסימניה נמחקה בהצלחה",
"com_ui_bookmarks_description": "תיאור",
"com_ui_bookmarks_edit": "ערוך סימניה",
"com_ui_bookmarks_filter": "סינון סימניות...",
"com_ui_bookmarks_new": "סימניה חדשה",
"com_ui_bookmarks_title": "כותרת",
"com_ui_bookmarks_update_error": "אירעה שגיאה בעת עדכון הסימניה",
"com_ui_bookmarks_update_success": "הסימניה עודכנה בהצלחה",
"com_ui_bulk_delete_error": "מחיקת קישורים משותפים נכשלה",
"com_ui_callback_url": "כתובת URL להחזרת המידע",
"com_ui_cancel": "בטל",
"com_ui_chat": "צ'אט",
"com_ui_chat_history": "נקה היסטוריה",
"com_ui_clear": "נקה",
"com_ui_clear_all": "נקה הכל",
"com_ui_client_id": "מזהה לקוח",
"com_ui_client_secret": "ב",
"com_ui_close": "סגור",
"com_ui_close_menu": "סגור תפריט",
"com_ui_code": "קוד",
"com_ui_collapse_chat": "כווץ צ'אט",
"com_ui_command_placeholder": "אופציונלי: הזן פקודה להנחיה (פרומפט), או שיעשה שימוש בשם",
"com_ui_command_usage_placeholder": "בחר הנחיה (פרומפט) לפי פקודה או שם",
"com_ui_complete_setup": "ההגדרה הושלמה",
"com_ui_confirm_action": "אשר פעולה",
"com_ui_confirm_admin_use_change": "שינוי הגדרה זו יחסום גישה למנהלים, כולל אותך. האם אתה בטוח שברצונך להמשיך?",
"com_ui_confirm_change": "אשר את השינוי",
"com_ui_context": "הקשר",
"com_ui_continue": "המשך",
"com_ui_controls": "פקדים",
"com_ui_copied": "הועתק!",
"com_ui_copied_to_clipboard": "הועתק ללוח",
"com_ui_copy_code": "העתק קוד",
"com_ui_copy_link": "העתק קישור",
"com_ui_copy_to_clipboard": "העתק ללוח",
"com_ui_create": "צור",
"com_ui_create_link": "צור קישור",
"com_ui_create_prompt": "צור הנחיה (פרומפט)",
"com_ui_currently_production": "נוצר עכשיו",
"com_ui_custom": "מותאם אישית",
"com_ui_custom_header_name": "שם כותרת מותאם אישית",
"com_ui_custom_prompt_mode": "מצב הנחיה (פרומפט) מותאם אישית",
"com_ui_dashboard": "לוח מחוונים",
"com_ui_date": "תאריך",
"com_ui_date_april": "אפריל",
"com_ui_date_august": "אוגוסט",
"com_ui_date_december": "דצמבר",
"com_ui_date_february": "פברואר",
"com_ui_date_january": "ינואר",
"com_ui_date_july": "יולי",
"com_ui_date_june": "יוני",
"com_ui_date_march": "מרץ",
"com_ui_date_may": "מאי",
"com_ui_date_november": "נובמבר",
"com_ui_date_october": "אוקטובר",
"com_ui_date_previous_30_days": "30 ימים אחרונים",
"com_ui_date_previous_7_days": "7 ימים אחרונים",
"com_ui_date_september": "ספטמבר",
"com_ui_date_today": "היום",
"com_ui_date_yesterday": "אתמול",
"com_ui_decline": "אני לא מקבל",
"com_ui_default_post_request": "ברירת המחדל (בקשת POST)",
"com_ui_delete": "מחק",
"com_ui_delete_action": "מחק פעולה",
"com_ui_delete_action_confirm": "האם אתה בטוח שברצונך למחוק פעולה זו?",
"com_ui_delete_agent_confirm": "האם אתה בטוח שברצונך למחוק את הסייען הזה?",
"com_ui_delete_assistant_confirm": "האם אתה בטוח שאתה רוצה למחוק את הסייען הזה? אי אפשר לבטל את זה.",
"com_ui_delete_confirm": "זה ימחק",
"com_ui_delete_confirm_prompt_version_var": "פעולה זו תמחק את הגרסה שנבחרה עבור \"{{0}}\". אם לא קיימות גרסאות נוספות, ההנחיה תימחק.",
"com_ui_delete_conversation": "למחוק את השיחה (צאט)?",
"com_ui_delete_prompt": "מחק הנחיה (פרומפט)",
"com_ui_delete_shared_link": "מחק קישור שיתוף",
"com_ui_delete_tool": "מחק כלי",
"com_ui_delete_tool_confirm": "האת אתה בטוח שאתה רוצה למחוק את הכלי הזה?",
"com_ui_descending": "תיאור",
"com_ui_description": "תיאור",
"com_ui_description_placeholder": "אופציונלי: הזן תיאור שיוצג עבור ההנחיה (פרומפט)",
"com_ui_disabling": "מבטל הפעלה...",
"com_ui_download": "הורדות",
"com_ui_download_artifact": "רכיב תצוגת הורדות",
"com_ui_download_backup": "הורד קודי גיבוי",
"com_ui_download_backup_tooltip": "לפני שתמשיך, הורד את קודי הגיבוי שלך. תזדקק להם כדי לשחזר גישה במקרה שתאבד את מכשיר האימות שלך",
"com_ui_download_error": "וזה: שגיאה בהורדת הקובץ. ייתכן שהקובץ נמחק",
"com_ui_drag_drop": "השדה חייב להכיל תוכן, הוא אינו יכול להישאר ריק",
"com_ui_dropdown_variables": "רשימה נפתחת של משתנים",
"com_ui_dropdown_variables_info": "צור תפריטי רשימה נפתחת מותאמים אישית עבור ההנחיות שלך:\n{{variable_name:option1|option2|option3}}",
"com_ui_duplicate": "שכפל",
"com_ui_duplication_error": "אירעה שגיאה בעת שכפול השיחה",
"com_ui_duplication_processing": "משכפל את השיחה...",
"com_ui_duplication_success": "השיחה שוכפלה בהצלחה",
"com_ui_edit": "ערוך",
"com_ui_empty_category": "-",
"com_ui_endpoint": "נקודת קצה",
"com_ui_endpoint_menu": "תפריט נקודת קצה LLM",
"com_ui_endpoints_available": "נקודות קצה זמינות",
"com_ui_enter": "Enter",
"com_ui_enter_api_key": "הכנס מפתח API",
"com_ui_enter_openapi_schema": "הזן כאן את סכימת OpenAPI שלך",
"com_ui_enter_var": "הכנס {{0}}",
"com_ui_error": "שגיאה",
"com_ui_error_connection": "שגיאה בחיבור לשרת, נסה לרענן את הדף",
"com_ui_error_save_admin_settings": "אירעה שגיאה בשמירת הגדרות הניהול שלך",
"com_ui_examples": "דוגמאות",
"com_ui_export_convo_modal": "חלון ייצוא שיחה",
"com_ui_field_required": "שדה זה נדרש",
"com_ui_filter_prompts": "סינון הנחיות (פרומפטים)",
"com_ui_filter_prompts_name": "סינון הנחיות (פרומפטים) לפי שם",
"com_ui_finance": "פיננסי",
"com_ui_fork": "הסתעפות",
"com_ui_fork_all_target": "כלול את כל ההודעות שנשלחו/התקבלו מכאן.",
"com_ui_fork_branches": "כלול הסתעפויות קשורות",
"com_ui_fork_change_default": "הגדרות הסתעפויות ברירת מחדל",
"com_ui_fork_default": "השתמש בהגדרות הסתעפויות ברירת מחדל",
"com_ui_fork_error": "אירעה שגיאה בעת פיצול השיחה",
"com_ui_fork_from_message": "בחר הגדרת הסתעפויות",
"com_ui_fork_info_1": "השתמש בהגדרה זו כדי ליצור הסתעפות של הודעות עם ההתנהגות הרצויה.",
"com_ui_fork_info_2": "\"הסתעפות\" מתייחסת ליצירת שיחה חדשה המתחילה/מסתיימת מהודעות ספציפיות בשיחה הנוכחית, תוך יצירת העתק בהתאם לאפשרויות שנבחרו.",
"com_ui_fork_info_3": "\"הודעת היעד\" מתייחסת להודעה שממנה נפתחה חלונית זו, או, אם סימנת \"{{0}}\", להודעה האחרונה בשיחה.",
"com_ui_fork_info_branches": "אפשרות זו מפצלת את ההודעות הגלויות, יחד עם ההסתעפויות הקשורות; במילים אחרות, המסלול הישיר להודעת היעד, כולל את ההסתעפויות לאורך המסלול.",
"com_ui_fork_info_remember": "סמן כדי לזכור את האפשרויות שבחרת לשימושים הבאים, כך שתוכל ליצור הסתעפויות בשיחות מהר יותר לפי העדפתך.",
"com_ui_fork_info_start": "כאשר מסומן, ההסתעפות תחל מההודעה זו ותימשך עד להודעה האחרונה בשיחה, על פי ההתנהגות שנבחרה לעיל.",
"com_ui_fork_info_target": "אפשרות זו תיצור הסתעפות שתכלול את כל ההודעות המובילות להודעת היעד, כולל ההודעות הסמוכות; במילים אחרות, כל ההסתעפויות של ההודעות יכללו, בין אם הם גלויות או לא, ובין אם הם נמצאות באותו מסלול או לא.",
"com_ui_fork_info_visible": "אפשרות זו תיצור הסתעפות רק של ההודעות הגלויות; במילים אחרות, רק את המסלול הישיר להודעת היעד, ללא הסתעפויות נוספות.",
"com_ui_fork_processing": "יוצר הסתעפות בשיחה...",
"com_ui_fork_remember": "זכור",
"com_ui_fork_remember_checked": "הבחירה שלך תישמר אחרי השימוש. תוכל לשנות זאת בכל זמן בהגדרות.",
"com_ui_fork_split_target": "התחל הסתעפות כאן",
"com_ui_fork_split_target_setting": "התחל הסתעפות מהודעת היעד כברירת מחדל",
"com_ui_fork_success": "יצירת ההסתעפות בשיחה הסתיימה בהצלחה",
"com_ui_fork_visible": "הודעות גלויות בלבד",
"com_ui_generate_backup": "צור קודי גיבוי",
"com_ui_generate_qrcode": "צור קוד QR",
"com_ui_generating": "יוצר...",
"com_ui_global_group": "שדה זה לא יכול להישאר ריק",
"com_ui_go_back": "חזור",
"com_ui_go_to_conversation": "חזור לצ'אט",
"com_ui_happy_birthday": "זה יום ההולדת הראשון שלי!",
"com_ui_import_conversation": "יבוא",
"com_ui_hide_qr": "הסתר קוד QR",
"com_ui_host": "מארח",
"com_ui_idea": "רעיונות",
"com_ui_image_gen": "מחולל תמונות",
"com_ui_import": "ייבוא",
"com_ui_import_conversation_error": "אירעה שגיאה בעת ייבוא השיחות שלך",
"com_ui_import_conversation_file_type_error": "סוג ייבוא לא נתמך",
"com_ui_import_conversation_info": "ייבא שיחות מקובץ JSON",
"com_ui_import_conversation_success": "השיחות יובאו בהצלחה",
"com_ui_include_shadcnui": "יש לכלול הוראות לשימוש ברכיבי ממשק המשתמש של shadcn/ui",
"com_ui_include_shadcnui_agent": "יש לכלול הוראות שימוש ב-shadcn/ui",
"com_ui_input": "קלט",
"com_ui_instructions": "הוראות",
"com_ui_latest_footer": "גישה לכל הבינות המלאכותיות (AI) לכולם",
"com_ui_latest_production_version": "גרסת הפיתוח העדכנית ביותר",
"com_ui_latest_version": "גרסה אחרונה",
"com_ui_librechat_code_api_key": "קבל את מפתח ה-API של מפענח הקוד LibreChat",
"com_ui_librechat_code_api_subtitle": "אבטחה ללא פשרות. תמיכה במגוון שפות תכנות. יכולת עבודה מלאה עם קבצים.",
"com_ui_librechat_code_api_title": "הרץ קוד AI",
"com_ui_llm_menu": "תפריט מודל שפה גדול (LLM)",
"com_ui_llms_available": "מודל שפה גדול (LLM)",
"com_ui_loading": "טוען...",
"com_ui_locked": "נעול",
"com_ui_logo": "\"לוגו {{0}}\"",
"com_ui_manage": "נהל",
"com_ui_max_tags": "המספר המקסימלי המותר על פי הערכים העדכניים הוא {{0}}.",
"com_ui_mention": "ציין נקודת קצה, סייען, או הנחייה (פרופמט) כדי לעבור אליה במהירות",
"com_ui_min_tags": "לא ניתן למחוק ערכים נוספים, יש צורך במינימום {{0}} ערכים.",
"com_ui_misc": "כללי",
"com_ui_model": "דגם",
"com_ui_model_parameters": "הגדרות המודל",
"com_ui_more_info": "מידע נוסף",
"com_ui_my_prompts": "ההנחיות (פרומפטים) שלי",
"com_ui_name": "שם",
"com_ui_new_chat": "שיחה חדשה",
"com_ui_next": "הבא",
"com_ui_no": "לא",
"com_ui_no_backup_codes": "אין קודי גיבוי זמינים. אנא צור קודים חדשים",
"com_ui_no_bookmarks": "עדיין אין לך סימניות. בחר שיחה והוסף סימניה חדשה",
"com_ui_no_category": "אין קטגוריה",
"com_ui_no_changes": "אין שינויים לעדכן",
"com_ui_no_data": "השדה חייב להכיל תוכן, הוא לא יכול להישאר ריק",
"com_ui_no_terms_content": "אין תוכן תנאים והגבלות להצגה",
"com_ui_no_valid_items": "השדה חייב להכיל תוכן, הוא לא יכול להישאר ריק",
"com_ui_none": "אף אחד",
"com_ui_none_selected": "לא ",
"com_ui_not_used": "לא בשימוש",
"com_ui_nothing_found": "לא נמצא",
"com_ui_oauth": "פרוטוקול אימות פתוח (OAuth)",
"com_ui_of": "של",
"com_ui_off": "של",
"com_ui_on": "פעיל",
"com_ui_page": "עמוד",
"com_ui_prev": "הקודם",
"com_ui_preview": "תצוגה מקדימה",
"com_ui_privacy_policy": "מדיניות פרטיות",
"com_ui_privacy_policy_url": "קישור למדיניות הפרטיות",
"com_ui_prompt": "הנחיה (פרומפט)",
"com_ui_prompt_already_shared_to_all": "ההנחיה הזו כבר משותפת עם כל המשתמשים",
"com_ui_prompt_name": "שם הנחיה (פרומפט)",
"com_ui_prompt_name_required": "נדרש שם הנחיה (פרומפט)",
"com_ui_prompt_preview_not_shared": "היוצר לא אפשר שיתוף פעולה להנחיה זו",
"com_ui_prompt_text": "טקסט",
"com_ui_prompt_text_required": "נדרש טקסט",
"com_ui_prompt_update_error": "אירעה שגיאה בעדכון ההנחיה (פרומפט)",
"com_ui_prompts": "הנחיות (פרומפטים)",
"com_ui_prompts_allow_create": "אפשר יצירת הנחיות",
"com_ui_prompts_allow_share_global": "אפשר שיתוף הנחיות (פרומפטים) עם כל המשתמשים",
"com_ui_prompts_allow_use": "אפשר שימוש בהנחיות (פרומפטים)",
"com_ui_provider": "ספק",
"com_ui_read_aloud": "הקראה",
"com_ui_refresh_link": "רענון קישור",
"com_ui_regenerate": "לחדש",
"com_ui_rename": "שם מחדש",
"com_ui_regenerate_backup": "צור קודי גיבוי מחדש",
"com_ui_regenerating": "יוצר מחדש...",
"com_ui_region": "איזור",
"com_ui_rename": "שנה שם",
"com_ui_rename_prompt": "שנה שם הנחיה (פרומפט)",
"com_ui_requires_auth": "נדרש אימות",
"com_ui_reset_var": "איפוס {{0}}",
"com_ui_result": "תוצאה",
"com_ui_revoke": "בטל",
"com_ui_revoke_info": "בטל את כל האישורים שסופקו על ידי המשתמש",
"com_ui_revoke_key_confirm": "האם אתה בטוח שברצונך לבטל את המפתח הזה?",
"com_ui_revoke_key_endpoint": "ביטול מפתח עבור {{0}}",
"com_ui_revoke_keys": "ביטול מפתחות",
"com_ui_revoke_keys_confirm": "האם אתה בטוח שברצונך לבטל את כל המפתחות?",
"com_ui_role_select": "תפקיד",
"com_ui_roleplay": "משחק תפקידים",
"com_ui_run_code": "הרץ קו",
"com_ui_run_code_error": "אירעה שגיאה בהרצת הקוד",
"com_ui_save": "שמור",
"com_ui_save_submit": "שמור ושלח",
"com_ui_saved": "שמור!",
"com_ui_schema": "סכמה",
"com_ui_scope": "תחום",
"com_ui_search": "חיפוש",
"com_ui_secret_key": "מפתח סודי",
"com_ui_select": "בחר",
"com_ui_select_model": "בחר דגם",
"com_ui_select_file": "בחר קובץ",
"com_ui_select_model": "בחר מודל",
"com_ui_select_provider": "בחר ספק",
"com_ui_select_provider_first": "ראשית בחר ספק",
"com_ui_select_region": "בחר איזור",
"com_ui_select_search_model": "חפש מודל לפי שם",
"com_ui_select_search_plugin": "חפש פאלגין לפי שם",
"com_ui_select_search_provider": "חפש ספק לפי שם",
"com_ui_select_search_region": "חפש איזור לפי שם",
"com_ui_share": "שתף",
"com_ui_share_create_message": "שמך וכל הודעה שתוסיף לאחר השיתוף יישארו פרטיים.",
"com_ui_share_delete_error": "אירעה שגיאה בעת מחיקת הקישור המשותף.",
"com_ui_share_error": "אירעה שגיאה בעת שיתוף קישור הצ'אט",
"com_ui_share_form_description": "השדה חייב להכיל תוכן, הוא אינו יכול להישאר ריק",
"com_ui_share_link_to_chat": "שתף קישור בצ'אט",
"com_ui_share_update_message": "Your name, custom instructions, and any messages you add after sharing stay private.",
"com_ui_shared_link_not_found": "Shared link not found",
"com_ui_share_to_all_users": "שתף עם כל המשתמשים",
"com_ui_share_update_message": "השם שלך, ההוראות המותאמות אישית וכל ההודעות שתוסיף לאחר השיתוף יישארו פרטיים.",
"com_ui_share_var": "שתף {{0}}",
"com_ui_shared_link_bulk_delete_success": "הקישורים המשותפים נמחקו בהצלחה",
"com_ui_shared_link_delete_success": "הקישור המשותף נמחק בהצלחה",
"com_ui_shared_link_not_found": "הקישור המשותף לא נמצא",
"com_ui_shared_prompts": "הנחיות (פרומפטים) משותפות",
"com_ui_shop": "קניות",
"com_ui_show": "הצג",
"com_ui_show_all": "הראה הכל",
"com_ui_show_qr": "הראה קוד QR",
"com_ui_sign_in_to_domain": "היכנס אל {{0}}",
"com_ui_simple": "פשוט",
"com_ui_size": "סוג",
"com_ui_special_variables": "משתנים מיוחדים:",
"com_ui_special_variables_info": "השתמש ב-`{{current_date}}` עבור התאריך הנוכחי, וב-`{{current_user}}` עבור שם החשבון שלך.",
"com_ui_speech_while_submitting": "לא ניתן לשלוח אודיו בזמן שנוצרת תגובה",
"com_ui_stop": "עצור",
"com_ui_storage": "אחסון",
"com_ui_submit": "שלח",
"com_ui_teach_or_explain": "למידה",
"com_ui_temporary_chat": "צ'אט זמני",
"com_ui_terms_and_conditions": "תנאים והגבלות",
"com_ui_terms_of_service": "תנאי השירות",
"com_ui_thinking": "חושב...",
"com_ui_thoughts": "מחשבות",
"com_ui_token_exchange_method": "שיטת החלפת טוקנים",
"com_ui_token_url": "קישור URL לטוקן",
"com_ui_tools": "כלים",
"com_ui_travel": "מסע",
"com_ui_unarchive": "לארכיון",
"com_ui_unarchive_error": "אירעה שגיאה בארכיון השיחה",
"com_ui_unknown": "לא ידוע",
"com_ui_update": "עדכון",
"com_ui_upload": "העלה",
"com_ui_upload_code_files": "העלאה עבור מפענח הקוד",
"com_ui_upload_delay": "העלאת \"{{0}}\" לוקחת יותר זמן מהצפוי. אנא המתן בזמן שהקובץ מסיים את האינדוקס לאחזור.",
"com_ui_upload_error": "אירעה שגיאה בהעלאת הקובץ שלך",
"com_ui_upload_file_search": "העלאה לחיפוש בקבצים",
"com_ui_upload_files": "העלה קבצים",
"com_ui_upload_success": "קובץ שהועלה בהצלחה",
"com_ui_use_prompt": "השתמש בהודעת",
"com_user_message": "אתה"
"com_ui_upload_image": "העלה תמונה",
"com_ui_upload_image_input": "העלה תמונה",
"com_ui_upload_invalid": "אין אפשרות להעלות את הקובץ. התמונה חורגת מהמגבלה",
"com_ui_upload_invalid_var": "אין אפשרות להעלות את הקובץ. התמונה צריכה להיות בגודל של עד {{0}} MB",
"com_ui_upload_success": "הקובץ הועלה בהצלחה",
"com_ui_upload_type": "בחר סוג העלאה",
"com_ui_use_2fa_code": "השתמש בקוד אימות דו-שלבי (2FA) במקום",
"com_ui_use_backup_code": "השתמש בקוד גיבוי במקום",
"com_ui_use_micrphone": "שימוש במיקורפון",
"com_ui_use_prompt": "השתמש בהנחיה (פרומפט)",
"com_ui_used": "נוצל",
"com_ui_variables": "משתנים",
"com_ui_variables_info": "השתמש בסוגריים מסולסלות כפולות בטקסט שלך ליצירת משתנים, לדוגמא `{{example variable}}`, כדי למלא אותם מאוחר יותר בשימוש בהנחיה.",
"com_ui_verify": "אמת",
"com_ui_version_var": "גרסה {{0}}",
"com_ui_versions": "גרסה",
"com_ui_view_source": "הצג צ'אט מקורי",
"com_ui_write": "כתיבה",
"com_ui_yes": "כן",
"com_ui_zoom": "זום",
"com_user_message": "אתה",
"com_warning_resubmit_unsupported": "שליחת הודעה מחדש אינה נתמכת עבור נקודת קצה זו."
}

View file

@ -15,6 +15,7 @@ import translationPt_BR from './pt-BR/translation.json';
import translationPt_PT from './pt-PT/translation.json';
import translationRu from './ru/translation.json';
import translationJa from './ja/translation.json';
import translationKa from './ka/translation.json';
import translationSv from './sv/translation.json';
import translationKo from './ko/translation.json';
import translationVi from './vi/translation.json';
@ -43,6 +44,7 @@ export const resources = {
'pt-PT': { translation: translationPt_PT },
ru: { translation: translationRu },
ja: { translation: translationJa },
ka: { translation: translationKa },
sv: { translation: translationSv },
ko: { translation: translationKo },
vi: { translation: translationVi },
@ -58,9 +60,9 @@ i18n
.use(initReactI18next)
.init({
fallbackLng: {
'zh-TW': ['zh-Hant'],
'zh-HK': ['zh-Hant'],
'zh': ['zh-Hans'],
'zh-TW': ['zh-Hant', 'en'],
'zh-HK': ['zh-Hant', 'en'],
'zh': ['zh-Hans', 'en'],
default: ['en'],
},
fallbackNS: 'translation',

View file

@ -91,7 +91,6 @@
"com_endpoint_google_temp": "Nilai yang lebih tinggi = lebih acak, sedangkan nilai yang lebih rendah = lebih fokus dan deterministik. Kami merekomendasikan untuk mengubah ini atau Top P tetapi tidak keduanya.",
"com_endpoint_google_topk": "Top-k mengubah cara model memilih token untuk output. Top-k 1 berarti token yang dipilih adalah yang paling mungkin di antara semua token dalam kosakata model (juga disebut decoding serakah), sedangkan top-k 3 berarti token berikutnya dipilih dari antara 3 token yang paling mungkin (menggunakan temperatur).",
"com_endpoint_google_topp": "Top-p mengubah cara model memilih token untuk output. Token dipilih dari yang paling mungkin (lihat parameter topK) hingga yang paling tidak mungkin sampai jumlah probabilitas mereka sama dengan nilai top-p.",
"com_endpoint_import": "Impor",
"com_endpoint_max_output_tokens": "Token Output Maks",
"com_endpoint_message": "Pesan",
"com_endpoint_message_not_appendable": "Edit pesan Anda atau Regenerasi.",
@ -142,7 +141,6 @@
"com_nav_archive_name": "Nama",
"com_nav_archived_chats": "Percakapan Arsip",
"com_nav_archived_chats_empty": "Tidak ada percakapan yang diarsipkan.",
"com_nav_archived_chats_manage": "Pengelolaan",
"com_nav_auto_scroll": "Otomatis gulir ke Baru saat Buka",
"com_nav_balance": "Keseimbangan",
"com_nav_change_picture": "Ubah foto",
@ -205,7 +203,6 @@
"com_nav_setting_general": "Umum",
"com_nav_settings": "Pengaturan",
"com_nav_shared_links": "Link berbagi",
"com_nav_shared_links_manage": "Pengeluaran",
"com_nav_theme": "Tema",
"com_nav_theme_dark": "Gelap",
"com_nav_theme_light": "Terang",
@ -250,7 +247,6 @@
"com_ui_enter": "Masuk",
"com_ui_examples": "Contoh",
"com_ui_happy_birthday": "Ini ulang tahun pertamaku!",
"com_ui_import_conversation": "Impor",
"com_ui_import_conversation_error": "Terjadi kesalahan saat mengimpor percakapan Anda",
"com_ui_import_conversation_info": "Impor percakapan dari file JSON",
"com_ui_import_conversation_success": "Percakapan berhasil diimpor",

View file

@ -179,7 +179,6 @@
"com_endpoint_google_temp": "Valori più alti = più casualità, mentre valori più bassi = più focalizzati e deterministici. Consigliamo di modificare questo o Top P ma non entrambi.",
"com_endpoint_google_topk": "Top-k cambia il modo in cui il modello seleziona i token per l'output. Un top-k di 1 significa che il token selezionato è il più probabile tra tutti i token nel vocabolario del modello (anche chiamato greedy decoding), mentre un top-k di 3 significa che il prossimo token è selezionato tra i 3 più probabili (usando la temperatura).",
"com_endpoint_google_topp": "Top-p cambia il modo in cui il modello seleziona i token per l'output. I token vengono selezionati dai più probabili K (vedi parametro topK) ai meno probabili fino a quando la somma delle loro probabilità eguaglia il valore top-p.",
"com_endpoint_import": "Importa",
"com_endpoint_instructions_assistants": "Sovrascrivi istruzioni",
"com_endpoint_instructions_assistants_placeholder": "Sovrascrive le istruzioni dell'assistente. Utile per modificare il comportamento su base singola.",
"com_endpoint_max_output_tokens": "Token di output massimi",
@ -265,7 +264,6 @@
"com_nav_archive_name": "Nome",
"com_nav_archived_chats": "Chat archiviate",
"com_nav_archived_chats_empty": "Non hai chat archiviate.",
"com_nav_archived_chats_manage": "Gestisci",
"com_nav_at_command": "Comando @",
"com_nav_at_command_description": "Attiva il comando \"@\" per cambiare endpoint, modelli, preset e altro",
"com_nav_audio_play_error": "Errore durante la riproduzione audio: {{0}}",
@ -388,7 +386,6 @@
"com_nav_setting_speech": "Voce",
"com_nav_settings": "Impostazioni",
"com_nav_shared_links": "Link condivisi",
"com_nav_shared_links_manage": "Gestisci",
"com_nav_show_code": "Mostra sempre il codice quando si usa l'interprete di codice",
"com_nav_show_thinking": "Apri i menu a tendina del ragionamento per impostazione predefinita",
"com_nav_slash_command": "/-Comando",
@ -603,7 +600,6 @@
"com_ui_hide_qr": "Nascondi codice QR",
"com_ui_host": "Host",
"com_ui_image_gen": "Generazione immagine",
"com_ui_import_conversation": "Importa",
"com_ui_import_conversation_error": "Si è verificato un errore durante l'importazione delle conversazioni",
"com_ui_import_conversation_file_type_error": "Tipo di importazione non supportato",
"com_ui_import_conversation_info": "Importa conversazioni da un file JSON",

View file

@ -178,7 +178,6 @@
"com_endpoint_google_temp": "大きい値 = ランダム性が増します。低い値 = より決定論的になります。この値を変更するか、Top P の変更をおすすめしますが、両方を変更はおすすめしません。",
"com_endpoint_google_topk": "Top-k はモデルがトークンをどのように選択して出力するかを変更します。top-kが1の場合はモデルの語彙に含まれるすべてのトークンの中で最も確率が高い1つが選択されます(greedy decodingと呼ばれている)。top-kが3の場合は上位3つのトークンの中から選択されます。(temperatureを使用)",
"com_endpoint_google_topp": "Top-p はモデルがトークンをどのように選択して出力するかを変更します。K(topKを参照)の確率の合計がtop-pの確率と等しくなるまでのトークンが選択されます。",
"com_endpoint_import": "インポート",
"com_endpoint_instructions_assistants": "指示をオーバーライドする",
"com_endpoint_instructions_assistants_placeholder": "アシスタントの指示を上書きします。これは、実行ごとに動作を変更する場合に便利です。",
"com_endpoint_max_output_tokens": "最大出力トークン数",
@ -262,7 +261,6 @@
"com_nav_archive_name": "名前",
"com_nav_archived_chats": "アーカイブされたチャット",
"com_nav_archived_chats_empty": "アーカイブされたチャットはありません",
"com_nav_archived_chats_manage": "管理",
"com_nav_at_command": "@-Command",
"com_nav_at_command_description": "コマンド\"@\"でエンドポイント、モデル、プリセットを切り替える",
"com_nav_audio_play_error": "オーディオの再生エラー: {{0}}",
@ -383,7 +381,6 @@
"com_nav_setting_speech": "スピーチ",
"com_nav_settings": "設定",
"com_nav_shared_links": "共有リンク",
"com_nav_shared_links_manage": "管理",
"com_nav_show_code": "Code Interpreter を使用する際は常にコードを表示する",
"com_nav_slash_command": "/-Command",
"com_nav_slash_command_description": "コマンド\"/\"でキーボードでプロンプトを選択する",
@ -587,7 +584,6 @@
"com_ui_happy_birthday": "初めての誕生日です!",
"com_ui_host": "ホスト",
"com_ui_image_gen": "画像生成",
"com_ui_import_conversation": "インポート",
"com_ui_import_conversation_error": "会話のインポート時にエラーが発生しました",
"com_ui_import_conversation_file_type_error": "サポートされていないインポート形式です",
"com_ui_import_conversation_info": "JSONファイルから会話をインポートする",

View file

@ -0,0 +1 @@
{}

View file

@ -178,7 +178,6 @@
"com_endpoint_google_temp": "높은 값 = 더 무작위, 낮은 값 = 더 집중적이고 결정적입니다. 이 값을 변경하거나 Top P 중 하나만 변경하는 것을 권장합니다.",
"com_endpoint_google_topk": "Top-k는 모델이 출력에 사용할 토큰을 선택하는 방식을 변경합니다. top-k가 1인 경우 모델의 어휘 중 가장 확률이 높은 토큰이 선택됩니다(greedy decoding). top-k가 3인 경우 다음 토큰은 가장 확률이 높은 3개의 토큰 중에서 선택됩니다(temperature 사용).",
"com_endpoint_google_topp": "Top-p는 모델이 출력에 사용할 토큰을 선택하는 방식을 변경합니다. 토큰은 가장 높은 확률부터 가장 낮은 확률까지 선택됩니다. 선택된 토큰의 확률의 합이 top-p 값과 같아질 때까지 선택됩니다.",
"com_endpoint_import": "가져오기",
"com_endpoint_instructions_assistants": "에이전트 지침 재정의",
"com_endpoint_instructions_assistants_placeholder": "어시스턴트의 지침을 재정의합니다. 이를 통해 실행마다 동작을 수정할 수 있습니다.",
"com_endpoint_max_output_tokens": "최대 출력 토큰 수",
@ -262,7 +261,6 @@
"com_nav_archive_name": "이름",
"com_nav_archived_chats": "아카이브된 채팅",
"com_nav_archived_chats_empty": "아카이브된 채팅이 없습니다",
"com_nav_archived_chats_manage": "관리",
"com_nav_at_command": "@ 명령어",
"com_nav_at_command_description": "엔드포인트, 모델, 프리셋 등을 전환하는 \"@\" 명령어 토글",
"com_nav_audio_play_error": "오디오 재생 오류: {{0}}",
@ -383,7 +381,6 @@
"com_nav_setting_speech": "음성",
"com_nav_settings": "설정",
"com_nav_shared_links": "공유 링크",
"com_nav_shared_links_manage": "관리",
"com_nav_show_code": "코드 인터프리터 사용 시 항상 코드 표시",
"com_nav_slash_command": "슬래시 명령어",
"com_nav_slash_command_description": "키보드로 프롬프트를 선택하려면 \"/\" 명령어 토글",
@ -587,7 +584,6 @@
"com_ui_happy_birthday": "내 첫 생일이야!",
"com_ui_host": "호스트",
"com_ui_image_gen": "이미지 생성",
"com_ui_import_conversation": "가져오기",
"com_ui_import_conversation_error": "대화를 가져오는 동안 오류가 발생했습니다",
"com_ui_import_conversation_file_type_error": "가져올 수 없는 파일 형식입니다",
"com_ui_import_conversation_info": "JSON 파일에서 대화 가져오기",

View file

@ -93,7 +93,6 @@
"com_endpoint_google_temp": "Hogere waarden = meer willekeurig, terwijl lagere waarden = meer gericht en deterministisch. We raden aan dit of Top P te wijzigen, maar niet beide.",
"com_endpoint_google_topk": "Top-k verandert hoe het model tokens selecteert voor uitvoer. Een top-k van 1 betekent dat het geselecteerde token het meest waarschijnlijk is van alle tokens in de vocabulaire van het model (ook wel 'greedy decoding' genoemd), terwijl een top-k van 3 betekent dat het volgende token wordt geselecteerd uit de 3 meest waarschijnlijke tokens (met behulp van temperatuur).",
"com_endpoint_google_topp": "Top-p verandert hoe het model tokens selecteert voor uitvoer. Tokens worden geselecteerd van meest K (zie topK-parameter) waarschijnlijk tot minst waarschijnlijk totdat de som van hun kansen gelijk is aan de top-p-waarde.",
"com_endpoint_import": "Importeren",
"com_endpoint_max_output_tokens": "Max. uitvoertokens",
"com_endpoint_my_preset": "Mijn voorinstelling",
"com_endpoint_no_presets": "Nog geen voorinstellingen, gebruik de instellingenknop om er een te maken",
@ -127,7 +126,6 @@
"com_nav_archive_name": "Naam",
"com_nav_archived_chats": "Gearchiveerde chats",
"com_nav_archived_chats_empty": "Geen gearchiveerde chats",
"com_nav_archived_chats_manage": "Beheren",
"com_nav_auto_scroll": "Automatisch scrollen naar Nieuwste bij openen",
"com_nav_balance": "Evenwicht",
"com_nav_clear_all_chats": "Alle chats wissen",
@ -182,7 +180,6 @@
"com_nav_setting_general": "Algemeen",
"com_nav_settings": "Instellingen",
"com_nav_shared_links": "Gedeelde links",
"com_nav_shared_links_manage": "Beheren",
"com_nav_theme": "Thema",
"com_nav_theme_dark": "Donker",
"com_nav_theme_light": "Licht",
@ -222,7 +219,6 @@
"com_ui_enter": "Invoeren",
"com_ui_examples": "Voorbeelden",
"com_ui_happy_birthday": "Het is mijn eerste verjaardag!",
"com_ui_import_conversation": "Importeren",
"com_ui_import_conversation_error": "Er is een fout opgetreden bij het importeren van je gesprekken",
"com_ui_import_conversation_info": "Gesprekken importeren vanuit een JSON-bestand",
"com_ui_import_conversation_success": "Gesprekken succesvol geïmporteerd",

View file

@ -161,7 +161,6 @@
"com_endpoint_google_temp": "Wyższe wartości oznaczają większą losowość, natomiast niższe wartości prowadzą do bardziej skoncentrowanych i deterministycznych wyników. Zalecamy dostosowanie tej wartości lub Top P, ale nie obu jednocześnie.",
"com_endpoint_google_topk": "Top-k wpływa na sposób, w jaki model wybiera tokeny do wygenerowania odpowiedzi. Top-k 1 oznacza, że wybrany token jest najbardziej prawdopodobny spośród wszystkich tokenów w słowniku modelu (nazywane też dekodowaniem zachłannym), podczas gdy top-k 3 oznacza, że następny token jest wybierany spośród 3 najbardziej prawdopodobnych tokenów (z uwzględnieniem temperatury).",
"com_endpoint_google_topp": "Top-p wpływa na sposób, w jaki model wybiera tokeny do wygenerowania odpowiedzi. Tokeny są wybierane od najbardziej prawdopodobnych do najmniej, aż suma ich prawdopodobieństw osiągnie wartość top-p.",
"com_endpoint_import": "Importuj",
"com_endpoint_instructions_assistants": "Nadpisz instrukcje",
"com_endpoint_max_output_tokens": "Maksymalna liczba tokenów wyjściowych",
"com_endpoint_message": "Wiadomość",
@ -238,7 +237,6 @@
"com_nav_archive_name": "Nazwa",
"com_nav_archived_chats": "Zarchiwizowane rozmowy",
"com_nav_archived_chats_empty": "Nie masz żadnych zarchiwizowanych rozmów.",
"com_nav_archived_chats_manage": "Zarządzaj",
"com_nav_at_command": "Polecenie @",
"com_nav_at_command_description": "Przełącz polecenie \"@\" do przełączania punktów końcowych, modeli, presetów, itp.",
"com_nav_audio_play_error": "Błąd odtwarzania audio: {0}",
@ -355,7 +353,6 @@
"com_nav_setting_speech": "Mowa",
"com_nav_settings": "Ustawienia",
"com_nav_shared_links": "Linki udostępnione",
"com_nav_shared_links_manage": "Beheren",
"com_nav_show_code": "Zawsze pokazuj kod podczas używania interpretera kodu",
"com_nav_show_thinking": "Domyślnie otwieraj rozwijane menu myślenia",
"com_nav_slash_command": "Polecenie /",
@ -565,7 +562,6 @@
"com_ui_hide_qr": "Ukryj kod QR",
"com_ui_host": "Host",
"com_ui_image_gen": "Generowanie obrazu",
"com_ui_import_conversation": "Importuj",
"com_ui_import_conversation_error": "Wystąpił błąd podczas importowania konwersacji",
"com_ui_import_conversation_file_type_error": "Nieobsługiwany typ importu",
"com_ui_import_conversation_info": "Importuj konwersacje z pliku JSON",

View file

@ -1,9 +1,16 @@
{
"chat_direction_left_to_right": "algo precisa ir aqui. esta vazio",
"chat_direction_right_to_left": "algo precisa ir aqui. esta vazio",
"com_a11y_ai_composing": "A IA ainda está compondo.",
"com_a11y_end": "A IA terminou de responder.",
"com_a11y_start": "A IA começou a responder.",
"com_agents_allow_editing": "Permitir que outros usuários editem seu agente",
"com_agents_by_librechat": "por LibreChat",
"com_agents_code_interpreter": "Quando ativado, permite que seu agente aproveite a API do interpretador de código LibreChat para executar o código gerado, incluindo o processamento de arquivos, com segurança. Requer uma chave de API válida.",
"com_agents_code_interpreter_title": "API do Interpretador de Código",
"com_agents_create_error": "Houve um erro ao criar seu agente.",
"com_agents_description_placeholder": "Opcional: Descreva seu Agente aqui",
"com_agents_enable_file_search": "Habilitar pesquisa de arquivos",
"com_agents_instructions_placeholder": "As instruções do sistema que o agente usa",
"com_agents_name_placeholder": "Opcional: O nome do agente",
"com_agents_search_name": "Pesquisar agentes por nome",
@ -163,7 +170,6 @@
"com_endpoint_google_temp": "Valores mais altos = mais aleatório, enquanto valores mais baixos = mais focado e determinístico. Recomendamos alterar isso ou Top P, mas não ambos.",
"com_endpoint_google_topk": "Top-k altera como o modelo seleciona tokens para saída. Um top-k de 1 significa que o token selecionado é o mais provável entre todos os tokens no vocabulário do modelo (também chamado de decodificação gananciosa), enquanto um top-k de 3 significa que o próximo token é selecionado entre os 3 tokens mais prováveis (usando temperatura).",
"com_endpoint_google_topp": "Top-p altera como o modelo seleciona tokens para saída. Os tokens são selecionados dos mais prováveis (veja o parâmetro topK) até os menos prováveis até que a soma de suas probabilidades atinja o valor top-p.",
"com_endpoint_import": "Importar",
"com_endpoint_instructions_assistants": "Substituir Instruções",
"com_endpoint_instructions_assistants_placeholder": "Substitui as instruções do assistente. Isso é útil para modificar o comportamento em uma base por execução.",
"com_endpoint_max_output_tokens": "Máximo de Tokens de Saída",
@ -237,7 +243,6 @@
"com_nav_archive_name": "Nome",
"com_nav_archived_chats": "Chats Arquivados",
"com_nav_archived_chats_empty": "Você não tem conversas arquivadas.",
"com_nav_archived_chats_manage": "Gerenciar",
"com_nav_at_command": "Comando @",
"com_nav_at_command_description": "Alternar comando \"@\" para alternar endpoints, modelos, predefinições, etc.",
"com_nav_audio_play_error": "Erro ao reproduzir áudio: {{0}}",
@ -353,7 +358,6 @@
"com_nav_setting_speech": "Fala",
"com_nav_settings": "Configurações",
"com_nav_shared_links": "Links compartilhados",
"com_nav_shared_links_manage": "Gerenciar",
"com_nav_show_code": "Sempre mostrar código ao usar o interpretador de código",
"com_nav_slash_command": "Comando /",
"com_nav_slash_command_description": "Alternar comando \"/\" para selecionar um prompt via teclado",
@ -530,7 +534,6 @@
"com_ui_happy_birthday": "É meu 1º aniversário!",
"com_ui_host": "Host",
"com_ui_image_gen": "Geração de Imagem",
"com_ui_import_conversation": "Importar",
"com_ui_import_conversation_error": "Houve um erro ao importar suas conversas",
"com_ui_import_conversation_file_type_error": "Tipo de importação não suportado",
"com_ui_import_conversation_info": "Importar conversas de um arquivo JSON",
@ -630,6 +633,8 @@
"com_ui_variables_info": "Use chaves duplas no seu texto para criar variáveis, por exemplo, `{{exemplo de variável}}`, para preencher posteriormente ao usar o prompt.",
"com_ui_version_var": "Versão {{0}}",
"com_ui_versions": "Versões",
"com_ui_write": "Escrevendo",
"com_ui_yes": "Sim",
"com_ui_zoom": "Zoom",
"com_user_message": "Você"
}

View file

@ -182,7 +182,6 @@
"com_endpoint_google_temp": "Valores mais altos = mais aleatório, enquanto valores mais baixos = mais focado e determinístico. Recomendamos alterar isso ou Top P, mas não ambos.",
"com_endpoint_google_topk": "Top-k altera como o modelo seleciona tokens para saída. Um top-k de 1 significa que o token selecionado é o mais provável entre todos os tokens no vocabulário do modelo (também chamado de decodificação gananciosa), enquanto um top-k de 3 significa que o próximo token é selecionado entre os 3 tokens mais prováveis (usando temperatura).",
"com_endpoint_google_topp": "Top-p altera como o modelo seleciona tokens para saída. Os tokens são selecionados dos mais prováveis (veja o parâmetro topK) até os menos prováveis até que a soma de suas probabilidades atinja o valor top-p.",
"com_endpoint_import": "Importar",
"com_endpoint_instructions_assistants": "Substituir Instruções",
"com_endpoint_instructions_assistants_placeholder": "Substitui as instruções do assistente. Isso é útil para modificar o comportamento em uma base por execução.",
"com_endpoint_max_output_tokens": "Máximo de Tokens de Saída",
@ -268,7 +267,6 @@
"com_nav_archive_name": "Nome",
"com_nav_archived_chats": "Chats Arquivados",
"com_nav_archived_chats_empty": "Você não tem conversas arquivadas.",
"com_nav_archived_chats_manage": "Gerenciar",
"com_nav_at_command": "Comando @",
"com_nav_at_command_description": "Alternar comando \"@\" para alternar endpoints, modelos, predefinições, etc.",
"com_nav_audio_play_error": "Erro ao reproduzir áudio: {{0}}",
@ -391,7 +389,6 @@
"com_nav_setting_speech": "Fala",
"com_nav_settings": "Configurações",
"com_nav_shared_links": "Links compartilhados",
"com_nav_shared_links_manage": "Gerenciar",
"com_nav_show_code": "Sempre mostrar código ao usar o interpretador de código",
"com_nav_show_thinking": "Abrir Dropdown de lógica por defeito.",
"com_nav_slash_command": "Comando /",
@ -626,7 +623,6 @@
"com_ui_host": "Host",
"com_ui_idea": "Ideias",
"com_ui_image_gen": "Geração de Imagem",
"com_ui_import_conversation": "Importar",
"com_ui_import_conversation_error": "Houve um erro ao importar suas conversas",
"com_ui_import_conversation_file_type_error": "Tipo de importação não suportado",
"com_ui_import_conversation_info": "Importar conversas de um arquivo JSON",

View file

@ -178,7 +178,6 @@
"com_endpoint_google_temp": "Более высокие значения = более случайные результаты, более низкие значения = более фокусированные и детерминированные результаты. Мы рекомендуем изменять это или Top P, но не оба значения одновременно.",
"com_endpoint_google_topk": "Top-k изменяет то, как модель выбирает токены для вывода. Top-k равное 1 означает, что выбирается наиболее вероятный токен из всего словаря модели (так называемое жадное декодирование), а Top-k равное 3 означает, что следующий токен выбирается из трех наиболее вероятных токенов (с использованием температуры).",
"com_endpoint_google_topp": "Top-p изменяет то, как модель выбирает токены для вывода. Токены выбираются из наиболее вероятных K (см. параметр topK) до наименее вероятных, пока сумма их вероятностей не достигнет значения top-p.",
"com_endpoint_import": "Импорт",
"com_endpoint_instructions_assistants": "Инструкции для ассистентов",
"com_endpoint_instructions_assistants_placeholder": "Переопределяет инструкции для ассистента. Это полезно для изменения поведения для отдельного запуска.",
"com_endpoint_max_output_tokens": "Максимальное количество выводимых токенов",
@ -262,7 +261,6 @@
"com_nav_archive_name": "Имя",
"com_nav_archived_chats": "Архивированные чаты",
"com_nav_archived_chats_empty": "У вас нет архивированных чатов.",
"com_nav_archived_chats_manage": "Управление",
"com_nav_at_command": "@-команда",
"com_nav_at_command_description": "Переключение команды \"@\" для выбора эндпоинтов, моделей, пресетов и др.",
"com_nav_audio_play_error": "Ошибка воспроизведения аудио: {{0}}",
@ -383,7 +381,6 @@
"com_nav_setting_speech": "Голос",
"com_nav_settings": "Настройки",
"com_nav_shared_links": "Связываемые ссылки",
"com_nav_shared_links_manage": "Управление",
"com_nav_show_code": "Всегда показывать код при использовании интерпретатора",
"com_nav_slash_command": "/-Команда",
"com_nav_slash_command_description": "Вызов командной строки клавишей '/' для выбора промта с клавиатуры",
@ -587,7 +584,6 @@
"com_ui_happy_birthday": "Это мой первый день рождения!",
"com_ui_host": "Хост",
"com_ui_image_gen": "Генератор изображений",
"com_ui_import_conversation": "Импортировать",
"com_ui_import_conversation_error": "При импорте бесед произошла ошибка",
"com_ui_import_conversation_file_type_error": "Неподдерживаемый тип импорта",
"com_ui_import_conversation_info": "Импортировать беседы из файла JSON",

View file

@ -82,7 +82,6 @@
"com_endpoint_google_temp": "Högre värden = mer slumpmässigt, medan lägre värden = mer fokuserat och bestämt. Vi rekommenderar att ändra detta eller Top P men inte båda.",
"com_endpoint_google_topk": "Top-k ändrar hur modellen väljer tokens för utdata. Ett top-k av 1 innebär att den valda token är den mest sannolika bland alla tokens i modellens vokabulär (kallas också girig avkodning), medan ett top-k av 3 innebär att nästa token väljs bland de 3 mest sannolika tokens (med temperatur).",
"com_endpoint_google_topp": "Top-p ändrar hur modellen väljer tokens för utdata. Tokens väljs från de mest K (se topK-parameter) sannolika till de minst tills summan av deras sannolikheter når top-p-värdet.",
"com_endpoint_import": "Importera",
"com_endpoint_max_output_tokens": "Max utdatatokens",
"com_endpoint_my_preset": "Min förinställning",
"com_endpoint_no_presets": "Ingen förinställning ännu",
@ -115,7 +114,6 @@
"com_nav_archive_name": "Namn",
"com_nav_archived_chats": "Arkiverade chattar",
"com_nav_archived_chats_empty": "Du har inga arkiverade chattar.",
"com_nav_archived_chats_manage": "Hantera",
"com_nav_balance": "Balans",
"com_nav_clear_all_chats": "Rensa alla chattar",
"com_nav_clear_conversation": "Rensa konversationer",
@ -169,7 +167,6 @@
"com_nav_setting_general": "Allmänt",
"com_nav_settings": "Inställningar",
"com_nav_shared_links": "Delade länkar",
"com_nav_shared_links_manage": "Hantera",
"com_nav_theme": "Tema",
"com_nav_theme_dark": "Mörkt",
"com_nav_theme_light": "Ljust",
@ -209,7 +206,6 @@
"com_ui_enter": "Ange",
"com_ui_examples": "Exempel",
"com_ui_happy_birthday": "Det är min första födelsedag!",
"com_ui_import_conversation": "Importera",
"com_ui_import_conversation_error": "Det uppstod ett fel vid import av dina konversationer",
"com_ui_import_conversation_info": "Importera konversationer från en JSON-fil",
"com_ui_import_conversation_success": "Konversationer har importerats framgångsrikt",

View file

@ -179,7 +179,6 @@
"com_endpoint_google_temp": "Yüksek değerler = daha rastgele, düşük değerler = daha odaklı ve belirleyici. Bu parametre ile Olasılık Kütüphanesini değiştirmeyi öneririz (ikisini birden değiştirmemek).",
"com_endpoint_google_topk": "Top-k, modelin çıktı için token seçimini nasıl yaptığını değiştirir. 1 olan bir top-k, modelin kelime haznesindeki en olası tokenin seçildiği (açgözlü kod çözme olarak da adlandırılır) anlamına gelirken, 3 olan bir top-k, bir sonraki tokenin en olası üç token arasından (sıcaklık kullanılarak) seçileceği anlamına gelir.",
"com_endpoint_google_topp": "Olasılık Kütüphanesi, modelin çıktı için token seçme şeklini değiştirir. Tokenler, en olasılıktan (bkz. topK parametresi) en az olasıya kadar seçilir ve olasılıkları toplamı, top-p değerine eşit olana kadar devam eder.",
"com_endpoint_import": "İthal et",
"com_endpoint_instructions_assistants": "Talimatları Geçersiz Kıl",
"com_endpoint_instructions_assistants_placeholder": "Asistanın talimatlarını geçersiz kılar. Bu, davranışı tek tek çalışma bazında değiştirmek için yararlıdır.",
"com_endpoint_max_output_tokens": "Maksimum Çıktı Tokenleri",
@ -265,7 +264,6 @@
"com_nav_archive_name": "Ad",
"com_nav_archived_chats": "Arşivlenmiş sohbetler",
"com_nav_archived_chats_empty": "Arşivlenmiş konuşmanız yok.",
"com_nav_archived_chats_manage": "Yönet",
"com_nav_at_command": "@-Komutu",
"com_nav_at_command_description": "Uç noktaları, modelleri, ön ayarları vb. değiştirmek için \"@\" komutunu aç/kapat",
"com_nav_audio_play_error": "Ses oynatma hatası: {{0}}",
@ -388,7 +386,6 @@
"com_nav_setting_speech": "Konuşma",
"com_nav_settings": "Ayarlar",
"com_nav_shared_links": "Paylaşılan bağlantılar",
"com_nav_shared_links_manage": "Yönet",
"com_nav_show_code": "Kod yorumlayıcı kullanırken her zaman kodu göster",
"com_nav_show_thinking": "Düşünme Açılır Menülerini Varsayılan Olarak Aç",
"com_nav_slash_command": "/-Komutu",
@ -605,7 +602,6 @@
"com_ui_hide_qr": "QR Kodunu Gizle",
"com_ui_host": "Host",
"com_ui_image_gen": "Görüntü Oluştur",
"com_ui_import_conversation": "İçe Aktar",
"com_ui_import_conversation_error": "Konuşmalarınızı içe aktarma sırasında bir hata oluştu",
"com_ui_import_conversation_file_type_error": "Desteklenmeyen içe aktarma türü",
"com_ui_import_conversation_info": "JSON dosyasından konuşmaları içe aktar",

View file

@ -84,7 +84,6 @@
"com_endpoint_google_temp": "Giá trị cao = ngẫu nhiên hơn, trong khi giá trị thấp = tập trung và xác định hơn. Chúng tôi khuyến nghị thay đổi giá trị này hoặc Top P nhưng không phải cả hai.",
"com_endpoint_google_topk": "Top-k thay đổi cách mô hình chọn mã thông báo để xuất. Top-k là 1 có nghĩa là mã thông báo được chọn là phổ biến nhất trong tất cả các mã thông báo trong bảng từ vựng của mô hình (còn được gọi là giải mã tham lam), trong khi top-k là 3 có nghĩa là mã thông báo tiếp theo được chọn từ giữa 3 mã thông báo phổ biến nhất (sử dụng nhiệt độ).",
"com_endpoint_google_topp": "Top-p thay đổi cách mô hình chọn mã thông báo để xuất. Mã thông báo được chọn từ căn cứ có xác suất cao nhất đến thấp nhất cho đến khi tổng xác suất của chúng bằng giá trị top-p.",
"com_endpoint_import": "Nhập",
"com_endpoint_max_output_tokens": "Số mã thông báo tối đa",
"com_endpoint_my_preset": "Đặt sẵn của tôi",
"com_endpoint_no_presets": "Chưa có đặt sẵn",
@ -167,7 +166,6 @@
"com_nav_setting_general": "Chung",
"com_nav_settings": "Cài đặt",
"com_nav_shared_links": "Liên kết được chia sẻ",
"com_nav_shared_links_manage": "Quản l",
"com_nav_theme": "Chủ đề",
"com_nav_theme_dark": "Tối",
"com_nav_theme_light": "Sáng",
@ -207,7 +205,6 @@
"com_ui_enter": "Nhập",
"com_ui_examples": "Ví dụ",
"com_ui_happy_birthday": "Đây là sinh nhật đầu tiên của tôi!",
"com_ui_import_conversation": "Nhập khẩu",
"com_ui_import_conversation_error": "Đã xảy ra lỗi khi nhập khẩu cuộc trò chuyện của bạn",
"com_ui_import_conversation_info": "Nhập khẩu cuộc trò chuyện từ một tệp JSON",
"com_ui_import_conversation_success": "Đã nhập khẩu cuộc trò chuyện thành công",

View file

@ -1,4 +1,6 @@
{
"chat_direction_left_to_right": "未找到描述。",
"chat_direction_right_to_left": "未找到描述。",
"com_a11y_ai_composing": "AI 仍在撰写中。",
"com_a11y_end": "AI 已完成回复。",
"com_a11y_start": "AI 已开始回复。",
@ -85,6 +87,7 @@
"com_auth_email_verification_redirecting": "在 {{0}} 秒后重定向...",
"com_auth_email_verification_resend_prompt": "未收到邮件?",
"com_auth_email_verification_success": "邮箱验证成功",
"com_auth_email_verifying_ellipsis": "验证中...",
"com_auth_error_create": "注册账户过程中出现错误,请重试。",
"com_auth_error_invalid_reset_token": "重置密码的密钥已失效。",
"com_auth_error_login": "无法登录,请确认提供的账户密码正确,并重新尝试。",
@ -121,9 +124,11 @@
"com_auth_submit_registration": "注册提交",
"com_auth_to_reset_your_password": "重置密码。",
"com_auth_to_try_again": "再试一次。",
"com_auth_two_factor": "查看您首选的一次性密码应用程序,获取密码",
"com_auth_username": "用户名(可选)",
"com_auth_username_max_length": "用户名最多 20 个字符",
"com_auth_username_min_length": "用户名至少 2 个字符",
"com_auth_verify_your_identity": "验证您的身份",
"com_auth_welcome_back": "欢迎",
"com_click_to_download": "(点击此处下载)",
"com_download_expired": "下载已过期",
@ -136,6 +141,8 @@
"com_endpoint_anthropic_maxoutputtokens": "响应中可以生成的最大令牌数。指定较低的值以获得较短的响应,指定较高的值以获得较长的响应。注意:模型可能会在达到此最大值之前停止。",
"com_endpoint_anthropic_prompt_cache": "提示词缓存允许在 API 调用中复用大型上下文或指令,从而降低成本和延迟",
"com_endpoint_anthropic_temp": "值介于 0 到 1 之间。对于分析性/选择性任务,值应更接近 0对于创造性和生成性任务值应更接近 1。我们建议更改该参数或 Top P但不要同时更改这两个参数。",
"com_endpoint_anthropic_thinking": "启用支持的 Claude 模型3.7 Sonnet的内部推理。注要求设置 \"思维预算\",且低于 \"最大输出令牌\"。",
"com_endpoint_anthropic_thinking_budget": "决定 Claude 内部推理过程允许使用的最大Token 数。尽管 Claude 可能不会使用分配的全部预算,尤其是在超过 32K 的范围内,但较大的预算可以对复杂问题进行更深入的分析,从而提高响应质量。此设置必须小于 \"最大输出 Token \"。",
"com_endpoint_anthropic_topk": "top-k 会改变模型选择输出词元的方式。top-k 为 1 意味着所选词是模型词汇中概率最大的(也称为贪心解码),而 top-k 为 3 意味着下一个词是从 3 个概率最大的词中选出的(使用随机性)。",
"com_endpoint_anthropic_topp": "top-p核采样会改变模型选择输出词元的方式。从概率最大的 K参见topK参数向最小的 K 选择,直到它们的概率之和等于 top-p 值。",
"com_endpoint_assistant": "助手",
@ -182,7 +189,6 @@
"com_endpoint_google_temp": "值越高表示输出越随机,值越低表示输出越确定。建议不要同时改变此值和 Top-p。",
"com_endpoint_google_topk": "top-k 会改变模型选择输出词的方式。top-k 为 1 意味着所选词是模型词汇中概率最大的(也称为贪心解码),而 top-k 为 3 意味着下一个词是从 3 个概率最大的词中选出的(使用随机性)。",
"com_endpoint_google_topp": "top-p核采样会改变模型选择输出词的方式。从概率最大的 K参见topK参数向最小的 K 选择,直到它们的概率之和等于 top-p 值。",
"com_endpoint_import": "导入",
"com_endpoint_instructions_assistants": "覆写指令",
"com_endpoint_instructions_assistants_placeholder": "覆盖助手的指令。这对于需要逐次修改行为非常有用。",
"com_endpoint_max_output_tokens": "最大输出词元数",
@ -199,6 +205,7 @@
"com_endpoint_openai_max_tokens": "可选的 'max_tokens' 字段,表示在聊天补全中可生成的最大词元数量。输入词元和生成词元的总长度受模型上下文长度的限制。如果该数值超过最大上下文词元数,您可能会遇到错误。",
"com_endpoint_openai_pres": "值介于 -2.0 到 2.0 之间。正值将惩罚当前已经使用的词元,从而增加讨论新话题的可能性。",
"com_endpoint_openai_prompt_prefix_placeholder": "在系统消息中添加自定义指令,默认为空",
"com_endpoint_openai_reasoning_effort": "仅 o1 模型:限制推理模型的推理工作量。减少推理工作可加快回复速度,减少回复中用于推理的标记。",
"com_endpoint_openai_resend": "重新发送所有先前附加的图像。注意:这会显着增加词元成本,并且可能会遇到很多关于图像附件的错误。",
"com_endpoint_openai_resend_files": "重新发送所有先前附加的文件。注意:这会显着增加词元成本,并且可能会遇到很多关于图像附件的错误。",
"com_endpoint_openai_stop": "最多 4 个序列API 将停止生成更多词元。",
@ -212,6 +219,7 @@
"com_endpoint_plug_use_functions": "使用函数",
"com_endpoint_presence_penalty": "话题新鲜度",
"com_endpoint_preset": "预设",
"com_endpoint_preset_custom_name_placeholder": "这里需要放置一些内容,但目前是空的。",
"com_endpoint_preset_default": "现在是默认预设。",
"com_endpoint_preset_default_item": "默认:",
"com_endpoint_preset_default_none": "无默认预设可用。",
@ -240,6 +248,8 @@
"com_endpoint_stop": "停止序列",
"com_endpoint_stop_placeholder": "按 `Enter` 键分隔多个值",
"com_endpoint_temperature": "随机性",
"com_endpoint_thinking": "思考中",
"com_endpoint_thinking_budget": "预算思考",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "使用激活的助手",
@ -259,15 +269,16 @@
"com_files_filter": "筛选文件...",
"com_files_no_results": "无结果。",
"com_files_number_selected": "已选择 {{0}} 个文件(共 {{1}} 个文件)",
"com_files_table": "这里需要放一些内容,但目前是空的。",
"com_generated_files": "生成的文件",
"com_hide_examples": "隐藏示例",
"com_nav_2fa": "双重身份验证 (2FA)",
"com_nav_account_settings": "账户设置",
"com_nav_always_make_prod": "始终应用新版本",
"com_nav_archive_created_at": "归档时间",
"com_nav_archive_name": "名称",
"com_nav_archived_chats": "归档的对话",
"com_nav_archived_chats_empty": "您没有归档的对话。",
"com_nav_archived_chats_manage": "管理",
"com_nav_at_command": "@-命令",
"com_nav_at_command_description": "切换至命令 “@” 以更改端点、模型、预设等",
"com_nav_audio_play_error": "播放音频时发生错误:{{0}}",
@ -327,6 +338,7 @@
"com_nav_help_faq": "帮助",
"com_nav_hide_panel": "隐藏最右侧面板",
"com_nav_info_code_artifacts": "启用在对话旁显示的实验性代码工件",
"com_nav_info_code_artifacts_agent": "使该代理能够使用代码附件。默认情况下,除非启用“自定义提示模式”,否则会添加与附件使用相关的额外说明。",
"com_nav_info_custom_prompt_mode": "启用后,默认的工件系统提示将不会包含在内。在此模式下,必须手动提供所有生成工件的指令。",
"com_nav_info_enter_to_send": "启用后,按下 `ENTER` 将发送您的消息。禁用后,按下 `ENTER` 将添加新行,您需要按下 `CTRL + ENTER` / `⌘ + ENTER` 来发送消息。",
"com_nav_info_fork_change_default": "`仅可见消息` 仅包含到所选消息的直接路径,`包含相关分支` 添加路径上的分支,`包含所有目标` 包括所有连接的消息和分支。",
@ -345,6 +357,7 @@
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_finnish": "Suomi",
"com_nav_lang_french": "Français ",
"com_nav_lang_georgian": "格鲁吉亚语Georgian",
"com_nav_lang_german": "Deutsch",
"com_nav_lang_hebrew": "עברית",
"com_nav_lang_indonesia": "Indonesia",
@ -390,8 +403,8 @@
"com_nav_setting_speech": "语音",
"com_nav_settings": "设置",
"com_nav_shared_links": "共享链接",
"com_nav_shared_links_manage": "管理",
"com_nav_show_code": "使用代码解释器时始终显示代码",
"com_nav_show_thinking": "默认情况下启用思考下拉菜单",
"com_nav_slash_command": "/-命令",
"com_nav_slash_command_description": "切换至命令 “/” 以通过键盘选择提示词",
"com_nav_source_buffer_error": "设置音频播放时发生错误。请刷新页面。",
@ -430,6 +443,16 @@
"com_sidepanel_parameters": "参数",
"com_sidepanel_select_agent": "选择助手",
"com_sidepanel_select_assistant": "选择助手",
"com_ui_2fa_account_security": "双重身份验证为您的账户提供了额外的安全保护",
"com_ui_2fa_disable": "关闭双重身份验证",
"com_ui_2fa_disable_error": "禁用双重身份验证时出现错误",
"com_ui_2fa_disabled": "双重身份验证已被禁用",
"com_ui_2fa_enable": "双重身份验证",
"com_ui_2fa_enabled": "双重身份验证已启用",
"com_ui_2fa_generate_error": "生成双重身份验证设置时发生错误。",
"com_ui_2fa_invalid": "无效的双重身份验证代码",
"com_ui_2fa_setup": "设置双重身份验证",
"com_ui_2fa_verified": "成功验证双重身份验证",
"com_ui_accept": "我接受",
"com_ui_add": "添加",
"com_ui_add_model_preset": "添加一个模型或预设以获得额外的回复",
@ -444,17 +467,22 @@
"com_ui_agent_duplicate_error": "复制助手时发生错误",
"com_ui_agent_duplicated": "助手复制成功",
"com_ui_agent_editing_allowed": "其他用户已可以编辑此助手",
"com_ui_agent_shared_to_all": "这里需要填入一些内容 之前是空的",
"com_ui_agents": "代理",
"com_ui_agents_allow_create": "允许创建助手",
"com_ui_agents_allow_share_global": "允许与所有用户共享助手",
"com_ui_agents_allow_use": "允许使用助手",
"com_ui_all": "所有",
"com_ui_all_proper": "所有",
"com_ui_analyzing": "正在分析",
"com_ui_analyzing_finished": "完成分析",
"com_ui_api_key": "API 密钥",
"com_ui_archive": "归档",
"com_ui_archive_error": "归档对话失败",
"com_ui_artifact_click": "点击以打开",
"com_ui_artifacts": "Artifacts",
"com_ui_artifacts_toggle": "切换至 Artifacts UI",
"com_ui_artifacts_toggle_agent": "启用附件",
"com_ui_ascending": "升序",
"com_ui_assistant": "助手",
"com_ui_assistant_delete_error": "删除助手时出现错误",
@ -472,6 +500,7 @@
"com_ui_authentication": "认证",
"com_ui_authentication_type": "认证类型",
"com_ui_avatar": "头像",
"com_ui_azure": "Azure",
"com_ui_back_to_chat": "返回对话",
"com_ui_back_to_prompts": "返回提示词",
"com_ui_basic": "基本",
@ -611,7 +640,6 @@
"com_ui_hide_qr": "隐藏二维码",
"com_ui_host": "主机",
"com_ui_image_gen": "图片生成",
"com_ui_import_conversation": "导入",
"com_ui_import_conversation_error": "导入对话时发生错误",
"com_ui_import_conversation_file_type_error": "不支持的导入类型",
"com_ui_import_conversation_info": "从 JSON 文件导入对话",
@ -724,6 +752,7 @@
"com_ui_stop": "停止",
"com_ui_storage": "存储",
"com_ui_submit": "提交",
"com_ui_teach_or_explain": "学习中",
"com_ui_temporary_chat": "临时对话",
"com_ui_terms_and_conditions": "条款和条件",
"com_ui_terms_of_service": "服务政策",

View file

@ -178,7 +178,6 @@
"com_endpoint_google_temp": "較高的值表示更隨機,而較低的值表示更集中和確定。我們建議修改這個或 Top P但不建議兩者都修改。",
"com_endpoint_google_topk": "Top-k 調整模型如何選取輸出的 token。當 Top-k 設為 1 時,模型會選取在其詞彙庫中機率最高的 token 進行輸出(這也被稱為貪婪解碼)。相對地,當 Top-k 設為 3 時,模型會從機率最高的三個 token 中選取下一個輸出 token這會涉及到所謂的「溫度」調整",
"com_endpoint_google_topp": "Top-p 調整模型在輸出 token 時的選擇機制。從最可能的 K見 topK 參數)開始選擇 token直到它們的機率之和達到 top-p 值。",
"com_endpoint_import": "匯入",
"com_endpoint_instructions_assistants": "覆寫提示指令",
"com_endpoint_instructions_assistants_placeholder": "覆寫助理的提示指令。這對於在每次執行時修改行為很有用。",
"com_endpoint_max_output_tokens": "最大輸出 token 數",
@ -262,7 +261,6 @@
"com_nav_archive_name": "名稱",
"com_nav_archived_chats": "封存的對話",
"com_nav_archived_chats_empty": "您沒有任何封存的對話。",
"com_nav_archived_chats_manage": "管理",
"com_nav_at_command": "@-指令",
"com_nav_at_command_description": "使用「@」指令切換端點、模型和預設值等",
"com_nav_audio_play_error": "播放音訊時發生錯誤:{{0}}",
@ -383,7 +381,6 @@
"com_nav_setting_speech": "語音",
"com_nav_settings": "設定",
"com_nav_shared_links": "共享連結",
"com_nav_shared_links_manage": "管理",
"com_nav_show_code": "一律顯示使用程式碼解譯器時的程式碼",
"com_nav_slash_command": "/指令",
"com_nav_slash_command_description": "使用鍵盤按下 \"/\" 快速選擇提示詞",
@ -587,7 +584,6 @@
"com_ui_happy_birthday": "這是我的第一個生日!",
"com_ui_host": "主機",
"com_ui_image_gen": "影像生成",
"com_ui_import_conversation": "匯入",
"com_ui_import_conversation_error": "匯入對話時發生錯誤",
"com_ui_import_conversation_file_type_error": "不支援的匯入檔案類型",
"com_ui_import_conversation_info": "從 JSON 文件匯入對話",

View file

@ -10,6 +10,7 @@ const headerMap: Record<string, TranslationKeys> = {
'/register': 'com_auth_create_account',
'/forgot-password': 'com_auth_reset_password',
'/reset-password': 'com_auth_reset_password',
'/login/2fa': 'com_auth_verify_your_identity',
};
export default function StartupLayout({ isAuthenticated }: { isAuthenticated?: boolean }) {

View file

@ -6,6 +6,7 @@ import {
ResetPassword,
VerifyEmail,
ApiErrorWatcher,
TwoFactorScreen,
} from '~/components/Auth';
import { AuthContextProvider } from '~/hooks/AuthContext';
import RouteErrorBoundary from './RouteErrorBoundary';
@ -66,6 +67,10 @@ export const router = createBrowserRouter([
path: 'login',
element: <Login />,
},
{
path: 'login/2fa',
element: <TwoFactorScreen />,
},
],
},
dashboardRoutes,

View file

@ -8,14 +8,14 @@ import type { TConversation } from 'librechat-data-provider';
import { getLocalStorageItems } from './localStorage';
const buildDefaultConvo = ({
models,
conversation,
endpoint = null,
models,
lastConversationSetup,
}: {
conversation: TConversation;
endpoint: EModelEndpoint | null;
models: string[];
conversation: TConversation;
endpoint?: EModelEndpoint | null;
lastConversationSetup: TConversation | null;
}): TConversation => {
const { lastSelectedModel, lastSelectedTools } = getLocalStorageItems();
@ -33,7 +33,7 @@ const buildDefaultConvo = ({
const model = lastConversationSetup?.model ?? lastSelectedModel?.[endpoint] ?? '';
const secondaryModel: string | null =
endpoint === EModelEndpoint.gptPlugins
? lastConversationSetup?.agentOptions?.model ?? lastSelectedModel?.secondaryModel ?? null
? (lastConversationSetup?.agentOptions?.model ?? lastSelectedModel?.secondaryModel ?? null)
: null;
let possibleModels: string[], secondaryModels: string[];

View file

@ -4,12 +4,17 @@ const loggerFilter = import.meta.env.VITE_LOGGER_FILTER || '';
type LogFunction = (...args: unknown[]) => void;
const createLogFunction = (consoleMethod: LogFunction): LogFunction => {
const createLogFunction = (
consoleMethod: LogFunction,
type?: 'log' | 'warn' | 'error' | 'info' | 'debug' | 'dir',
): LogFunction => {
return (...args: unknown[]) => {
if (isDevelopment || isLoggerEnabled) {
const tag = typeof args[0] === 'string' ? args[0] : '';
if (shouldLog(tag)) {
if (tag && args.length > 1) {
if (tag && typeof args[1] === 'string' && type === 'error') {
consoleMethod(`[${tag}] ${args[1]}`, ...args.slice(2));
} else if (tag && args.length > 1) {
consoleMethod(`[${tag}]`, ...args.slice(1));
} else {
consoleMethod(...args);
@ -20,12 +25,12 @@ const createLogFunction = (consoleMethod: LogFunction): LogFunction => {
};
const logger = {
log: createLogFunction(console.log),
warn: createLogFunction(console.warn),
error: createLogFunction(console.error),
info: createLogFunction(console.info),
debug: createLogFunction(console.debug),
dir: createLogFunction(console.dir),
log: createLogFunction(console.log, 'log'),
dir: createLogFunction(console.dir, 'dir'),
warn: createLogFunction(console.warn, 'warn'),
info: createLogFunction(console.info, 'info'),
error: createLogFunction(console.error, 'error'),
debug: createLogFunction(console.debug, 'debug'),
};
function shouldLog(tag: string): boolean {

View file

@ -35,10 +35,5 @@
"test/setupTests.js",
"env.d.ts",
"../config/translations/**/*.ts"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}

View file

@ -1,9 +0,0 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

View file

@ -1,38 +1,14 @@
import path, { resolve } from 'path';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';
import { defineConfig, createLogger } from 'vite';
import { defineConfig } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import compression from 'vite-plugin-compression';
import type { Plugin } from 'vite';
const logger = createLogger();
const originalWarning = logger.warn;
logger.warn = (msg, options) => {
/* Suppresses:
[vite:css] Complex selectors in '.group:focus-within .dark\:group-focus-within\:text-gray-300:is(.dark *)' can not be transformed to an equivalent selector without ':is()'.
*/
if (msg.includes('vite:css') && msg.includes('^^^^^^^')) {
return;
}
/* Suppresses:
(!) Some chunks are larger than 500 kB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
*/
if (msg.includes('Use build.rollupOptions.output.manualChunks')) {
return;
}
originalWarning(msg, options);
};
// https://vitejs.dev/config/
export default defineConfig({
customLogger: logger,
server: {
fs: {
cachedChecks: false,
},
host: 'localhost',
port: 3090,
strictPort: false,
@ -47,7 +23,7 @@ export default defineConfig({
},
},
},
// All other env variables are filtered out
// Set the directory where environment variables are loaded from and restrict prefixes
envDir: '../',
envPrefix: ['VITE_', 'SCRIPT_', 'DOMAIN_', 'ALLOW_'],
plugins: [
@ -57,14 +33,16 @@ export default defineConfig({
injectRegister: 'auto', // 'auto' | 'manual' | 'disabled'
registerType: 'autoUpdate', // 'prompt' | 'autoUpdate'
devOptions: {
enabled: false, // enable/disable registering SW in development mode
enabled: false, // disable service worker registration in development mode
},
useCredentials: true,
workbox: {
globPatterns: ['assets/**/*.{png,jpg,svg,ico}', '**/*.{js,css,html,ico,woff2}'],
globPatterns: ['**/*'],
globIgnores: ['images/**/*'],
maximumFileSizeToCacheInBytes: 4 * 1024 * 1024,
navigateFallbackDenylist: [/^\/oauth/],
},
includeAssets: ['**/*'],
manifest: {
name: 'LibreChat',
short_name: 'LibreChat',
@ -88,6 +66,11 @@ export default defineConfig({
sizes: '180x180',
type: 'image/png',
},
{
src: '/assets/icon-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/assets/maskable-icon.png',
sizes: '512x512',
@ -98,33 +81,64 @@ export default defineConfig({
},
}),
sourcemapExclude({ excludeNodeModules: true }),
compression({
verbose: true,
disable: false,
threshold: 10240, // compress files larger than 10KB
algorithm: 'gzip',
ext: '.gz',
}),
],
publicDir: './public',
build: {
sourcemap: process.env.NODE_ENV === 'development',
outDir: './dist',
minify: 'terser',
rollupOptions: {
preserveEntrySignatures: 'strict',
// external: ['uuid'],
output: {
manualChunks: (id) => {
if (id.includes('node_modules/highlight.js')) {
return 'markdown_highlight';
}
if (id.includes('node_modules/hast-util-raw')) {
return 'markdown_large';
}
if (id.includes('node_modules/katex')) {
return 'markdown_large';
}
manualChunks(id: string) {
if (id.includes('node_modules')) {
// Group Radix UI libraries together.
if (id.includes('@radix-ui')) {
return 'radix-ui';
}
// Group framer-motion separately.
if (id.includes('framer-motion')) {
return 'framer-motion';
}
// Group markdown-related libraries.
if (id.includes('node_modules/highlight.js')) {
return 'markdown_highlight';
}
if (id.includes('node_modules/hast-util-raw') || id.includes('node_modules/katex')) {
return 'markdown_large';
}
// Group TanStack libraries together.
if (id.includes('@tanstack')) {
return 'tanstack-vendor';
}
// Additional grouping for other node_modules:
if (id.includes('@headlessui')) {
return 'headlessui';
}
// Everything else falls into a generic vendor chunk.
return 'vendor';
}
// Create a separate chunk for all locale files under src/locales.
if (id.includes(path.join('src', 'locales'))) {
return 'locales';
}
// Let Rollup decide automatically for any other files.
return null;
},
entryFileNames: 'assets/[name].[hash].js',
chunkFileNames: 'assets/[name].[hash].js',
assetFileNames: (assetInfo) => {
if (assetInfo.name && /\.(woff|woff2|eot|ttf|otf)$/.test(assetInfo.name)) {
return 'assets/[name][extname]';
if (assetInfo.names && /\.(woff|woff2|eot|ttf|otf)$/.test(assetInfo.names)) {
return 'assets/fonts/[name][extname]';
}
return 'assets/[name].[hash][extname]';
},
@ -134,15 +148,13 @@ export default defineConfig({
* @see {@link https://github.com/TanStack/query/pull/5161#issuecomment-1477389761 Preserve 'use client' directives TanStack/query#5161}
*/
onwarn(warning, warn) {
if (
// warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
warning.message.includes('Error when using sourcemap')
) {
if (warning.message.includes('Error when using sourcemap')) {
return;
}
warn(warning);
},
},
chunkSizeWarningLimit: 1200,
},
resolve: {
alias: {