🎨 style: update Assistants builder (#3397)

* style: update Assistant builder

* fix(Eng): re-introduce old file_search info message

* feat: new OGDialogTemplate; style: imporved tools + actions dialogs

* style: fix alignment issue for delete tool dialog

* chore: import order

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
Marco Beretta 2024-07-21 19:46:43 +02:00 committed by GitHub
parent 344297021f
commit 0bd59c0efe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 1115 additions and 916 deletions

View file

@ -2,7 +2,7 @@ export default function RemoveFile({ onRemove }: { onRemove: () => void }) {
return (
<button
type="button"
className="absolute right-1 top-1 -translate-y-1/2 translate-x-1/2 rounded-full border border-white bg-gray-500 p-0.5 text-white transition-colors hover:bg-black hover:opacity-100 group-hover:opacity-100 md:opacity-0"
className="absolute right-1 top-1 -translate-y-1/2 translate-x-1/2 rounded-full border border-gray-500 bg-gray-500 p-0.5 text-white transition-colors hover:bg-gray-700 hover:opacity-100 group-hover:opacity-100 md:opacity-0"
onClick={onRemove}
>
<span>
@ -15,6 +15,8 @@ export default function RemoveFile({ onRemove }: { onRemove: () => void }) {
strokeLinejoin="round"
className="icon-sm"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />

View file

@ -32,7 +32,7 @@ import {
DropdownMenuTrigger,
} from '~/components/ui';
import { useDeleteFilesFromTable } from '~/hooks/Files';
import { NewTrashIcon, Spinner } from '~/components/svg';
import { TrashIcon, Spinner } from '~/components/svg';
import useLocalize from '~/hooks/useLocalize';
interface DataTableProps<TData, TValue> {
@ -102,7 +102,7 @@ export default function DataTable<TData, TValue>({ columns, data }: DataTablePro
{isDeleting ? (
<Spinner className="h-4 w-4" />
) : (
<NewTrashIcon className="h-4 w-4 text-red-400" />
<TrashIcon className="h-4 w-4 text-red-400" />
)}
{localize('com_ui_delete')}
</Button>

View file

@ -1,5 +1,5 @@
import React from 'react';
import { CrossIcon, NewTrashIcon } from '~/components/svg';
import { CrossIcon, TrashIcon } from '~/components/svg';
import { Button } from '~/components/ui';
type DeleteIconButtonProps = {
@ -10,7 +10,7 @@ export default function DeleteIconButton({ onClick }: DeleteIconButtonProps) {
return (
<div className="w-fit">
<Button className="bg-red-400 p-3" onClick={onClick}>
<NewTrashIcon />
<TrashIcon />
</Button>
</div>
);

View file

@ -32,7 +32,7 @@ import {
DropdownMenuTrigger,
} from '~/components/ui';
import { useDeleteFilesFromTable } from '~/hooks/Files';
import { NewTrashIcon, Spinner } from '~/components/svg';
import { TrashIcon, Spinner } from '~/components/svg';
import useLocalize from '~/hooks/useLocalize';
import ActionButton from '../ActionButton';
import UploadFileButton from './UploadFileButton';
@ -112,7 +112,7 @@ export default function DataTableFile<TData, TValue>({
{isDeleting ? (
<Spinner className="h-4 w-4" />
) : (
<NewTrashIcon className="h-4 w-4 text-red-400" />
<TrashIcon className="h-4 w-4 text-red-400" />
)}
{localize('com_ui_delete')}
</Button>

View file

@ -1,6 +1,6 @@
import type { TFile } from 'librechat-data-provider';
import React from 'react';
import { NewTrashIcon } from '~/components/svg';
import { TrashIcon } from '~/components/svg';
import { Button } from '~/components/ui';
type FileListItemProps = {
@ -25,7 +25,7 @@ export default function FileListItem({ file, deleteFile, width = '400px' }: File
className="my-0 ml-3 bg-transparent p-0 text-[#666666] hover:bg-slate-200"
onClick={() => deleteFile(file._id)}
>
<NewTrashIcon className="m-0 p-0" />
<TrashIcon className="m-0 p-0" />
</Button>
</div>
</div>

View file

@ -2,7 +2,7 @@ import type { TFile } from 'librechat-data-provider';
import { FileIcon, PlusIcon } from 'lucide-react';
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { DotsIcon, NewTrashIcon } from '~/components/svg';
import { DotsIcon, TrashIcon } from '~/components/svg';
import { Button } from '~/components/ui';
type FileListItemProps = {
@ -68,7 +68,7 @@ export default function FileListItem2({
className="w-min bg-transparent text-[#666666] hover:bg-slate-200"
onClick={() => deleteFile(file._id)}
>
<NewTrashIcon className="" />
<TrashIcon className="" />
</Button>
</div>
</div>

View file

@ -1,7 +1,7 @@
import { TFile } from 'librechat-data-provider/dist/types';
import React, { useState } from 'react';
import { TThread, TVectorStore } from '~/common';
import { CheckMark, NewTrashIcon } from '~/components/svg';
import { CheckMark, TrashIcon } from '~/components/svg';
import { Button } from '~/components/ui';
import DeleteIconButton from '../DeleteIconButton';
import VectorStoreButton from '../VectorStore/VectorStoreButton';
@ -140,7 +140,7 @@ export default function FilePreview() {
}}
variant={'ghost'}
>
<NewTrashIcon className="m-0 p-0" />
<TrashIcon className="m-0 p-0" />
</Button>
</div>
</div>
@ -167,7 +167,7 @@ export default function FilePreview() {
console.log('Remove from thread');
}}
>
<NewTrashIcon className="m-0 p-0" />
<TrashIcon className="m-0 p-0" />
</Button>
</div>
</div>

View file

@ -1,7 +1,7 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { TVectorStore } from '~/common';
import { DotsIcon, NewTrashIcon, TrashIcon } from '~/components/svg';
import { DotsIcon, TrashIcon, TrashIcon } from '~/components/svg';
import { Button } from '~/components/ui';
type VectorStoreListItemProps = {
@ -39,7 +39,7 @@ export default function VectorStoreListItem({
className="m-0 w-full bg-transparent p-0 text-[#666666] hover:bg-slate-200 sm:w-fit"
onClick={() => deleteVectorStore(vectorStore._id)}
>
<NewTrashIcon className="m-0 p-0" />
<TrashIcon className="m-0 p-0" />
</Button>
</div>
</div>

View file

@ -1,7 +1,7 @@
import React, { useState } from 'react';
import DeleteIconButton from '../DeleteIconButton';
import { Button } from '~/components/ui';
import { NewTrashIcon } from '~/components/svg';
import { TrashIcon } from '~/components/svg';
import { TFile } from 'librechat-data-provider/dist/types';
import UploadFileButton from '../FileList/UploadFileButton';
import UploadFileModal from '../FileList/UploadFileModal';
@ -204,7 +204,7 @@ export default function VectorStorePreview() {
className="my-0 ml-3 h-min bg-transparent p-0 text-[#666666] hover:bg-slate-200"
onClick={() => console.log('click')}
>
<NewTrashIcon className="m-0 p-0" />
<TrashIcon className="m-0 p-0" />
</Button>
</div>
</div>

View file

@ -18,7 +18,7 @@ import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon';
import DialogTemplate from '~/components/ui/DialogTemplate';
import { RenameButton } from '~/components/Conversations';
import { useLocalize, useAuthContext } from '~/hooks';
import { NewTrashIcon } from '~/components/svg';
import { TrashIcon } from '~/components/svg';
import { cn } from '~/utils/';
export default function DashGroupItem({
@ -169,7 +169,7 @@ export default function DashGroupItem({
e.stopPropagation();
}}
>
<NewTrashIcon className="icon-md text-gray-600 dark:text-gray-300" />
<TrashIcon className="icon-md text-gray-600 dark:text-gray-300" />
</Button>
</DialogTrigger>
<DialogTemplate

View file

@ -7,9 +7,10 @@ import {
} from 'librechat-data-provider';
import type { AssistantPanelProps, ActionAuthForm } from '~/common';
import { useAssistantsMapContext, useToastContext } from '~/Providers';
import { Dialog, DialogTrigger } from '~/components/ui';
import { Dialog, DialogTrigger, OGDialog, OGDialogTrigger, Label } from '~/components/ui';
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
import { useDeleteAction } from '~/data-provider';
import { NewTrashIcon } from '~/components/svg';
import { TrashIcon } from '~/components/svg';
import useLocalize from '~/hooks/useLocalize';
import ActionsInput from './ActionsInput';
import ActionsAuth from './ActionsAuth';
@ -119,33 +120,52 @@ export default function ActionsPanel({
</div>
</button>
</div>
{!!action && (
<OGDialog>
<OGDialogTrigger asChild>
<div className="absolute right-0 top-6">
<button
type="button"
disabled={!assistant_id || !action.action_id}
className="btn relative bg-transparent text-red-500 hover:bg-gray-100 dark:hover:bg-gray-800"
onClick={() => {
if (!assistant_id) {
return prompt('No assistant_id found, is the assistant created?');
className="btn btn-neutral border-token-border-light relative h-9 rounded-lg font-medium"
>
<TrashIcon className="text-red-500" />
</button>
</div>
</OGDialogTrigger>
<OGDialogTemplate
showCloseButton={false}
title={localize('com_ui_delete_action')}
className="max-w-[450px]"
main={
<Label className="text-left text-sm font-medium">
{localize('com_ui_delete_action_confirm')}
</Label>
}
selection={{
selectHandler: () => {
if (!assistant_id) {
return showToast({
message: 'No assistant_id found, is the assistant created?',
status: 'error',
});
}
const confirmed = confirm('Are you sure you want to delete this action?');
if (confirmed) {
deleteAction.mutate({
model: assistantMap[endpoint][assistant_id].model,
action_id: action.action_id,
assistant_id,
endpoint,
});
}
},
selectClasses:
'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white',
selectText: localize('com_ui_delete'),
}}
>
<div className="flex w-full items-center justify-center gap-2">
<NewTrashIcon className="icon-md text-red-500" />
</div>
</button>
</div>
/>
</OGDialog>
)}
<div className="text-xl font-medium">{(action ? 'Edit' : 'Add') + ' ' + 'actions'}</div>
<div className="text-token-text-tertiary text-sm">
{localize('com_assistants_actions_info')}

View file

@ -1,3 +1,4 @@
import { useState } from 'react';
import type { Action } from 'librechat-data-provider';
import GearIcon from '~/components/svg/GearIcon';
@ -8,11 +9,15 @@ export default function AssistantAction({
action: Action;
onClick: () => void;
}) {
const [isHovering, setIsHovering] = useState(false);
return (
<div>
<div
onClick={onClick}
className="border-token-border-medium flex w-full rounded-lg border text-sm hover:cursor-pointer"
className="flex w-full rounded-lg text-sm hover:cursor-pointer"
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
>
<div
className="h-9 grow whitespace-nowrap px-3 py-2"
@ -20,13 +25,14 @@ export default function AssistantAction({
>
{action.metadata.domain}
</div>
<div className="w-px bg-gray-300 dark:bg-gray-600" />
{isHovering && (
<button
type="button"
className="flex h-9 w-9 min-w-9 items-center justify-center rounded-lg rounded-l-none"
className="transition-color flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
>
<GearIcon className="icon-sm" />
</button>
)}
</div>
</div>
);

View file

@ -13,6 +13,7 @@ import {
import type { FunctionTool, TConfig, TPlugin } from 'librechat-data-provider';
import type { AssistantForm, AssistantPanelProps } from '~/common';
import { useCreateAssistantMutation, useUpdateAssistantMutation } from '~/data-provider';
import { cn, cardStyle, defaultTextProps, removeFocusOutlines } from '~/utils';
import { useAssistantsMapContext, useToastContext } from '~/Providers';
import { useSelectAssistant, useLocalize } from '~/hooks';
import { ToolSelectDialog } from '~/components/Tools';
@ -24,13 +25,15 @@ import AssistantAction from './AssistantAction';
import ContextButton from './ContextButton';
import AssistantTool from './AssistantTool';
import { Spinner } from '~/components/svg';
import { cn, cardStyle } from '~/utils/';
import Knowledge from './Knowledge';
import { Panel } from '~/common';
const labelClass = 'mb-2 block text-xs font-bold text-gray-700 dark:text-gray-400';
const inputClass =
'focus:shadow-outline w-full appearance-none rounded-md border px-3 py-2 text-sm leading-tight text-gray-700 dark:text-white shadow focus:border-green-500 focus:outline-none focus:ring-0 dark:bg-gray-800 dark:border-gray-700/80';
const labelClass = 'mb-2 text-token-text-primary block font-medium';
const inputClass = cn(
defaultTextProps,
'flex w-full px-3 py-2 dark:border-gray-800 dark:bg-gray-800',
removeFocusOutlines,
);
export default function AssistantPanel({
// index = 0,
@ -297,7 +300,7 @@ export default function AssistantPanel({
{...field}
value={field.value ?? ''}
{...{ max: 32768 }}
className="focus:shadow-outline min-h-[150px] w-full resize-none resize-y appearance-none rounded-md border px-3 py-2 text-sm leading-tight text-gray-700 shadow focus:border-green-500 focus:outline-none focus:ring-0 dark:border-gray-700/80 dark:bg-gray-800 dark:text-white"
className={cn(inputClass, 'min-h-[100px] resize-none resize-y')}
id="instructions"
placeholder={localize('com_assistants_instructions_placeholder')}
rows={3}
@ -357,7 +360,7 @@ export default function AssistantPanel({
${toolsEnabled && actionsEnabled ? ' + ' : ''}
${actionsEnabled ? localize('com_assistants_actions') : ''}`}
</label>
<div className="space-y-1">
<div className="space-y-2">
{functions.map((func, i) => (
<AssistantTool
key={`${func}-${i}-${assistant_id}`}
@ -373,11 +376,12 @@ export default function AssistantPanel({
<AssistantAction key={i} action={action} onClick={() => setAction(action)} />
);
})}
<div className="flex space-x-2">
{toolsEnabled && (
<button
type="button"
onClick={() => setShowToolDialog(true)}
className="btn border-token-border-light relative mx-1 mt-2 h-8 rounded-lg bg-transparent font-medium hover:bg-gray-100 dark:hover:bg-gray-800"
className="btn btn-neutral border-token-border-light relative h-8 w-full rounded-lg font-medium"
>
<div className="flex w-full items-center justify-center gap-2">
{localize('com_assistants_add_tools')}
@ -397,7 +401,7 @@ export default function AssistantPanel({
}
setActivePanel(Panel.actions);
}}
className="btn border-token-border-light relative mt-2 h-8 rounded-lg bg-transparent font-medium hover:bg-gray-100 dark:hover:bg-gray-800"
className="btn btn-neutral border-token-border-light relative h-8 w-full rounded-lg font-medium"
>
<div className="flex w-full items-center justify-center gap-2">
{localize('com_assistants_add_actions')}
@ -406,6 +410,7 @@ export default function AssistantPanel({
)}
</div>
</div>
</div>
<div className="flex items-center justify-end gap-2">
{/* Context Button */}
<ContextButton
@ -415,23 +420,9 @@ export default function AssistantPanel({
createMutation={create}
endpoint={endpoint}
/>
{/* Secondary Select Button */}
{assistant_id && (
<button
className="btn btn-secondary"
type="button"
disabled={!assistant_id}
onClick={(e) => {
e.preventDefault();
onSelectAssistant(assistant_id);
}}
>
{localize('com_ui_select')}
</button>
)}
{/* Submit Button */}
<button
className="btn btn-primary focus:shadow-outline flex w-[90px] items-center justify-center px-4 py-2 font-semibold text-white hover:bg-green-600 focus:border-green-500"
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"
type="submit"
>
{create.isLoading || update.isLoading ? (

View file

@ -1,5 +1,12 @@
import React, { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import type { TPlugin } from 'librechat-data-provider';
import GearIcon from '~/components/svg/GearIcon';
import { useUpdateUserPluginsMutation } from 'librechat-data-provider/react-query';
import { OGDialog, OGDialogTrigger, Label } from '~/components/ui';
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
import { useToastContext } from '~/Providers';
import { TrashIcon } from '~/components/svg';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
export default function AssistantTool({
@ -11,20 +18,46 @@ export default function AssistantTool({
allTools: TPlugin[];
assistant_id?: string;
}) {
const [isHovering, setIsHovering] = useState(false);
const localize = useLocalize();
const { showToast } = useToastContext();
const updateUserPlugins = useUpdateUserPluginsMutation();
const { getValues, setValue } = useFormContext();
const currentTool = allTools.find((t) => t.pluginKey === tool);
const removeTool = (tool: string) => {
if (tool) {
updateUserPlugins.mutate(
{ pluginKey: tool, action: 'uninstall', auth: null, isAssistantTool: true },
{
onError: (error: unknown) => {
showToast({ message: `Error while deleting the tool: ${error}`, status: 'error' });
},
onSuccess: () => {
const fns = getValues('functions').filter((fn) => fn !== tool);
setValue('functions', fns);
showToast({ message: 'Tool deleted successfully', status: 'success' });
},
},
);
}
};
if (!currentTool) {
return null;
}
return (
<div>
<OGDialog>
<div
className={cn(
'border-token-border-medium flex w-full rounded-lg border text-sm hover:cursor-pointer',
'flex w-full items-center rounded-lg text-sm',
!assistant_id ? 'opacity-40' : '',
)}
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
>
<div className="flex grow items-center">
{currentTool.icon && (
<div className="flex h-9 w-9 items-center justify-center overflow-hidden rounded-full">
<div
@ -39,14 +72,36 @@ export default function AssistantTool({
>
{currentTool.name}
</div>
<div className="w-px bg-gray-300 dark:bg-gray-600" />
</div>
{isHovering && (
<OGDialogTrigger asChild>
<button
type="button"
className="flex h-9 w-9 min-w-9 items-center justify-center rounded-lg rounded-l-none"
className="transition-color flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
>
<GearIcon className="icon-sm" />
<TrashIcon />
</button>
</OGDialogTrigger>
)}
</div>
</div>
<OGDialogTemplate
showCloseButton={false}
title={localize('com_ui_delete_tool')}
mainClassName="px-0"
className="max-w-[450px]"
main={
<Label className="text-left text-sm font-medium">
{localize('com_ui_delete_tool_confirm')}
</Label>
}
selection={{
selectHandler: () => removeTool(currentTool.pluginKey),
selectClasses:
'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white',
selectText: localize('com_ui_delete'),
}}
/>
</OGDialog>
);
}

View file

@ -1,9 +1,12 @@
import { useMemo } from 'react';
import { Capabilities } from 'librechat-data-provider';
import { useFormContext, useWatch } from 'react-hook-form';
import type { TConfig, AssistantsEndpoint } from 'librechat-data-provider';
import type { AssistantForm } from '~/common';
import ImageVision from './ImageVision';
import { useLocalize } from '~/hooks';
import Retrieval from './Retrieval';
import CodeFiles from './CodeFiles';
import Code from './Code';
export default function CapabilitiesForm({
@ -21,6 +24,17 @@ export default function CapabilitiesForm({
}) {
const localize = useLocalize();
const methods = useFormContext<AssistantForm>();
const { control } = methods;
const assistant = useWatch({ control, name: 'assistant' });
const assistant_id = useWatch({ control, name: 'id' });
const files = useMemo(() => {
if (typeof assistant === 'string') {
return [];
}
return assistant.code_files;
}, [assistant]);
const retrievalModels = useMemo(
() => new Set(assistantsConfig?.retrievalModels ?? []),
[assistantsConfig],
@ -31,7 +45,7 @@ export default function CapabilitiesForm({
);
return (
<div className="mb-6">
<div className="mb-4">
<div className="mb-1.5 flex items-center">
<span>
<label className="text-token-text-primary block font-medium">
@ -40,11 +54,19 @@ export default function CapabilitiesForm({
</span>
</div>
<div className="flex flex-col items-start gap-2">
{codeEnabled && <Code endpoint={endpoint} version={version} />}
{imageVisionEnabled && version == 1 && <ImageVision />}
{codeEnabled && <Code version={version} />}
{retrievalEnabled && (
<Retrieval endpoint={endpoint} version={version} retrievalModels={retrievalModels} />
)}
{imageVisionEnabled && version == 1 && <ImageVision />}
{codeEnabled && version && (
<CodeFiles
assistant_id={assistant_id}
version={version}
endpoint={endpoint}
files={files}
/>
)}
</div>
</div>
);

View file

@ -1,33 +1,25 @@
import { useMemo } from 'react';
import { Capabilities } from 'librechat-data-provider';
import { useFormContext, Controller, useWatch } from 'react-hook-form';
import type { AssistantsEndpoint } from 'librechat-data-provider';
import { useFormContext, Controller } from 'react-hook-form';
import type { AssistantForm } from '~/common';
import { Checkbox, QuestionMark } from '~/components/ui';
import {
Checkbox,
HoverCard,
HoverCardContent,
HoverCardPortal,
HoverCardTrigger,
} from '~/components/ui';
import { CircleHelpIcon } from '~/components/svg';
import { useLocalize } from '~/hooks';
import CodeFiles from './CodeFiles';
import { ESide } from '~/common';
export default function Code({
version,
endpoint,
}: {
version: number | string;
endpoint: AssistantsEndpoint;
}) {
export default function Code({ version }: { version: number | string }) {
const localize = useLocalize();
const methods = useFormContext<AssistantForm>();
const { control, setValue, getValues } = methods;
const assistant = useWatch({ control, name: 'assistant' });
const assistant_id = useWatch({ control, name: 'id' });
const files = useMemo(() => {
if (typeof assistant === 'string') {
return [];
}
return assistant.code_files;
}, [assistant]);
return (
<>
<HoverCard openDelay={50}>
<div className="flex items-center">
<Controller
name={Capabilities.code_interpreter}
@ -42,6 +34,7 @@ export default function Code({
/>
)}
/>
<div className="flex items-center space-x-2">
<label
className="form-check-label text-token-text-primary w-full cursor-pointer"
htmlFor={Capabilities.code_interpreter}
@ -51,20 +44,23 @@ export default function Code({
})
}
>
<div className="flex select-none items-center">
{localize('com_assistants_code_interpreter')}
<QuestionMark />
</div>
</label>
<HoverCardTrigger>
<CircleHelpIcon className="h-5 w-5 text-gray-500" />
</HoverCardTrigger>
</div>
{version == 2 && (
<CodeFiles
assistant_id={assistant_id}
version={version}
endpoint={endpoint}
files={files}
/>
)}
<HoverCardPortal>
<HoverCardContent side={ESide.Top} className="w-80">
<div className="space-y-2">
<p className="text-sm text-gray-600 dark:text-gray-300">
{version == 2 && localize('com_assistants_code_interpreter_info')}
</p>
</div>
</HoverCardContent>
</HoverCardPortal>
</div>
</HoverCard>
</>
);
}

View file

@ -58,7 +58,7 @@ export default function CodeFiles({
};
return (
<div className={'mb-2'}>
<div className="mb-2 w-full">
<div className="flex flex-col gap-4">
<div className="text-token-text-tertiary rounded-lg text-xs">
{localize('com_assistants_code_interpreter_files')}
@ -75,7 +75,7 @@ export default function CodeFiles({
<button
type="button"
disabled={!assistant_id}
className="btn btn-neutral border-token-border-light relative h-8 rounded-lg font-medium"
className="btn btn-neutral border-token-border-light relative h-8 w-full rounded-lg font-medium"
onClick={handleButtonClick}
>
<div className="flex w-full items-center justify-center gap-2">

View file

@ -1,4 +1,3 @@
import * as Popover from '@radix-ui/react-popover';
import type { Assistant, AssistantCreateParams, AssistantsEndpoint } from 'librechat-data-provider';
import type { UseMutationResult } from '@tanstack/react-query';
import { Dialog, DialogTrigger, Label } from '~/components/ui';
@ -7,7 +6,7 @@ import { useDeleteAssistantMutation } from '~/data-provider';
import DialogTemplate from '~/components/ui/DialogTemplate';
import { useLocalize, useSetIndexOptions } from '~/hooks';
import { cn, removeFocusOutlines } from '~/utils/';
import { NewTrashIcon } from '~/components/svg';
import { TrashIcon } from '~/components/svg';
export default function ContextButton({
activeModel,
@ -78,66 +77,19 @@ export default function ContextButton({
return (
<Dialog>
<Popover.Root>
<Popover.Trigger asChild>
<DialogTrigger asChild>
<button
className={cn(
'btn border-token-border-light relative h-9 rounded-lg bg-transparent font-medium hover:bg-gray-100 dark:hover:bg-gray-800',
'btn btn-neutral border-token-border-light relative h-9 rounded-lg font-medium',
removeFocusOutlines,
)}
type="button"
>
<div className="flex w-full items-center justify-center gap-2">
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="icon-md"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3 12C3 10.8954 3.89543 10 5 10C6.10457 10 7 10.8954 7 12C7 13.1046 6.10457 14 5 14C3.89543 14 3 13.1046 3 12ZM10 12C10 10.8954 10.8954 10 12 10C13.1046 10 14 10.8954 14 12C14 13.1046 13.1046 14 12 14C10.8954 14 10 13.1046 10 12ZM17 12C17 10.8954 17.8954 10 19 10C20.1046 10 21 10.8954 21 12C21 13.1046 20.1046 14 19 14C17.8954 14 17 13.1046 17 12Z"
fill="currentColor"
/>
</svg>
<div className="flex w-full items-center justify-center gap-2 text-red-500">
<TrashIcon />
</div>
</button>
</Popover.Trigger>
<div
style={{
position: 'fixed',
left: ' 0px',
top: ' 0px',
transform: 'translate(1772.8px, 49.6px)',
minWidth: 'max-content',
zIndex: 'auto',
}}
dir="ltr"
>
<Popover.Content
side="top"
role="menu"
className="bg-token-surface-primary min-w-[180px] max-w-xs rounded-lg border border-gray-100 bg-white shadow-lg dark:border-gray-900 dark:bg-gray-850"
style={{ outline: 'none', pointerEvents: 'auto' }}
sideOffset={8}
tabIndex={-1}
align="end"
>
<DialogTrigger asChild>
<Popover.Close
role="menuitem"
className="group m-1.5 flex w-full cursor-pointer gap-2 rounded p-2.5 text-sm text-red-500 hover:bg-black/5 focus:ring-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-white/5"
tabIndex={-1}
>
<NewTrashIcon />
{localize('com_ui_delete') + ' ' + localize('com_ui_assistant')}
</Popover.Close>
</DialogTrigger>
</Popover.Content>
</div>
<DialogTemplate
title={localize('com_ui_delete') + ' ' + localize('com_ui_assistant')}
className="max-w-[450px]"
@ -159,7 +111,6 @@ export default function ContextButton({
selectText: localize('com_ui_delete'),
}}
/>
</Popover.Root>
</Dialog>
);
}

View file

@ -33,10 +33,7 @@ export default function ImageVision() {
})
}
>
<div className="flex items-center">
{localize('com_assistants_image_vision')}
<QuestionMark />
</div>
<div className="flex items-center">{localize('com_assistants_image_vision')}</div>
</label>
</div>
);

View file

@ -1,10 +1,17 @@
import { useEffect, useMemo } from 'react';
import { useFormContext, Controller, useWatch } from 'react-hook-form';
import { Capabilities } from 'librechat-data-provider';
import type { AssistantsEndpoint } from 'librechat-data-provider';
import type { AssistantForm } from '~/common';
import { useFormContext, Controller, useWatch } from 'react-hook-form';
import {
Checkbox,
HoverCard,
HoverCardContent,
HoverCardPortal,
HoverCardTrigger,
} from '~/components/ui';
import OptionHover from '~/components/SidePanel/Parameters/OptionHover';
import { Checkbox, HoverCard, HoverCardTrigger } from '~/components/ui';
import { CircleHelpIcon } from '~/components/svg';
import type { AssistantForm } from '~/common';
import { useLocalize } from '~/hooks';
import { ESide } from '~/common';
import { cn } from '~/utils/';
@ -40,6 +47,7 @@ export default function Retrieval({
return (
<>
<HoverCard openDelay={50}>
<div className="flex items-center">
<Controller
name={Capabilities.retrieval}
@ -55,8 +63,7 @@ export default function Retrieval({
/>
)}
/>
<HoverCard openDelay={50}>
<HoverCardTrigger asChild>
<div className="flex items-center space-x-2">
<label
className={cn(
'form-check-label text-token-text-primary w-full select-none',
@ -74,21 +81,29 @@ export default function Retrieval({
? localize('com_assistants_retrieval')
: localize('com_assistants_file_search')}
</label>
<HoverCardTrigger>
<CircleHelpIcon className="h-5 w-5 text-gray-500" />
</HoverCardTrigger>
</div>
<HoverCardPortal>
<HoverCardContent side={ESide.Top} disabled={isDisabled} className="ml-16 w-80">
<div className="space-y-2">
<p className="text-sm text-gray-600 dark:text-gray-300">
{version == 2 && localize('com_assistants_file_search_info')}
</p>
</div>
</HoverCardContent>
</HoverCardPortal>
<OptionHover
side={ESide.Top}
disabled={!isDisabled}
description="com_assistants_non_retrieval_model"
langCode={true}
sideOffset={20}
className="ml-16"
/>
</div>
</HoverCard>
</div>
{version == 2 && (
<div className="text-token-text-tertiary rounded-lg text-xs">
{localize('com_assistants_file_search_info')}
</div>
)}
</>
);
}

View file

@ -9,6 +9,7 @@ type TOptionHoverProps = {
sideOffset?: number;
disabled?: boolean;
side: ESide;
className?: string;
};
function OptionHover({
@ -17,6 +18,7 @@ function OptionHover({
disabled,
langCode,
sideOffset = 30,
className,
}: TOptionHoverProps) {
const localize = useLocalize();
if (disabled) {
@ -25,11 +27,7 @@ function OptionHover({
const text = langCode ? localize(description) : description;
return (
<HoverCardPortal>
<HoverCardContent
side={side}
className="z-[999] w-80 dark:bg-gray-700"
sideOffset={sideOffset}
>
<HoverCardContent side={side} className={`z-[999] w-80 ${className}`} sideOffset={sideOffset}>
<div className="space-y-2">
<p className="text-sm text-gray-600 dark:text-gray-300">{text}</p>
</div>

View file

@ -1,19 +0,0 @@
export default function NewTrashIcon({ className = 'icon-md' }) {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.5555 4C10.099 4 9.70052 4.30906 9.58693 4.75114L9.29382 5.8919H14.715L14.4219 4.75114C14.3083 4.30906 13.9098 4 13.4533 4H10.5555ZM16.7799 5.8919L16.3589 4.25342C16.0182 2.92719 14.8226 2 13.4533 2H10.5555C9.18616 2 7.99062 2.92719 7.64985 4.25342L7.22886 5.8919H4C3.44772 5.8919 3 6.33961 3 6.8919C3 7.44418 3.44772 7.8919 4 7.8919H4.10069L5.31544 19.3172C5.47763 20.8427 6.76455 22 8.29863 22H15.7014C17.2354 22 18.5224 20.8427 18.6846 19.3172L19.8993 7.8919H20C20.5523 7.8919 21 7.44418 21 6.8919C21 6.33961 20.5523 5.8919 20 5.8919H16.7799ZM17.888 7.8919H6.11196L7.30423 19.1057C7.3583 19.6142 7.78727 20 8.29863 20H15.7014C16.2127 20 16.6417 19.6142 16.6958 19.1057L17.888 7.8919ZM10 10C10.5523 10 11 10.4477 11 11V16C11 16.5523 10.5523 17 10 17C9.44772 17 9 16.5523 9 16V11C9 10.4477 9.44772 10 10 10ZM14 10C14.5523 10 15 10.4477 15 11V16C15 16.5523 14.5523 17 14 17C13.4477 17 13 16.5523 13 16V11C13 10.4477 13.4477 10 14 10Z"
fill="currentColor"
/>
</svg>
);
}

View file

@ -1,6 +1,10 @@
import { cn } from '~/utils';
export default function TrashIcon({ className = '' }) {
type TrashIconProps = {
className?: string;
};
export default function TrashIcon({ className = '' }: TrashIconProps) {
return (
<svg
fill="none"
@ -8,7 +12,7 @@ export default function TrashIcon({ className = '' }) {
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className={cn('icon-md', className)}
className={cn('icon-md h-4 w-4', className)}
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"

View file

@ -29,7 +29,6 @@ export { default as DotsIcon } from './DotsIcon';
export { default as GearIcon } from './GearIcon';
export { default as PinIcon } from './PinIcon';
export { default as TrashIcon } from './TrashIcon';
export { default as NewTrashIcon } from './NewTrashIcon';
export { default as MinimalPlugin } from './MinimalPlugin';
export { default as AzureMinimalIcon } from './AzureMinimalIcon';
export { default as OpenAIMinimalIcon } from './OpenAIMinimalIcon';

View file

@ -11,8 +11,13 @@ const HoverCardPortal = HoverCardPrimitive.Portal;
const HoverCardContent = React.forwardRef<
React.ElementRef<typeof HoverCardPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
>(({ className = '', align = 'center', sideOffset = 6, ...props }, ref) => (
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content> & { disabled?: boolean }
>(({ className = '', align = 'center', sideOffset = 6, disabled = false, ...props }, ref) => {
if (disabled) {
return null;
}
return (
<HoverCardPrimitive.Content
ref={ref}
align={align}
@ -23,7 +28,8 @@ const HoverCardContent = React.forwardRef<
)}
{...props}
/>
));
);
});
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
export { HoverCard, HoverCardTrigger, HoverCardContent, HoverCardPortal };

View file

@ -0,0 +1,95 @@
import { forwardRef, ReactNode, Ref } from 'react';
import {
OGDialogTitle,
OGDialogClose,
OGDialogFooter,
OGDialogHeader,
OGDialogContent,
OGDialogDescription,
} from './';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils/';
type SelectionProps = {
selectHandler?: () => void;
selectClasses?: string;
selectText?: string;
};
type DialogTemplateProps = {
title: string;
description?: string;
main?: ReactNode;
buttons?: ReactNode;
leftButtons?: ReactNode;
selection?: SelectionProps;
className?: string;
headerClassName?: string;
mainClassName?: string;
footerClassName?: string;
showCloseButton?: boolean;
showCancelButton?: boolean;
};
const OGDialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDivElement>) => {
const localize = useLocalize();
const {
title,
main,
buttons,
selection,
className,
leftButtons,
description,
mainClassName,
headerClassName,
footerClassName,
showCloseButton,
showCancelButton = true,
} = props;
const { selectHandler, selectClasses, selectText } = selection || {};
const Cancel = localize('com_ui_cancel');
const defaultSelect =
'bg-gray-800 text-white transition-colors hover:bg-gray-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-200 dark:text-gray-800 dark:hover:bg-gray-200';
return (
<OGDialogContent
showCloseButton={showCloseButton}
ref={ref}
className={cn(
'bg-white dark:border-gray-700 dark:bg-gray-850 dark:text-gray-300',
className || '',
)}
onClick={(e) => e.stopPropagation()}
>
<OGDialogHeader className={cn(headerClassName ?? '')}>
<OGDialogTitle>{title}</OGDialogTitle>
{description && <OGDialogDescription className="">{description}</OGDialogDescription>}
</OGDialogHeader>
<div className={cn('px-6', mainClassName)}>{main ? main : null}</div>
<OGDialogFooter className={footerClassName}>
<div>{leftButtons ? leftButtons : null}</div>
<div className="flex h-auto gap-3">
{showCancelButton && (
<OGDialogClose className="btn btn-neutral border-token-border-light relative rounded-lg text-sm">
{Cancel}
</OGDialogClose>
)}
{buttons ? buttons : null}
{selection ? (
<OGDialogClose
onClick={selectHandler}
className={`${
selectClasses || defaultSelect
} inline-flex h-10 items-center justify-center rounded-lg border-none px-4 py-2 text-sm`}
>
{selectText}
</OGDialogClose>
) : null}
</div>
</OGDialogFooter>
</OGDialogContent>
);
});
export default OGDialogTemplate;

View file

@ -26,10 +26,15 @@ const DialogOverlay = React.forwardRef<
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
type DialogContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
showCloseButton?: boolean;
disableScroll?: boolean;
};
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
DialogContentProps
>(({ className, showCloseButton = true, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
@ -41,10 +46,12 @@ const DialogContent = React.forwardRef<
{...props}
>
{children}
{showCloseButton && (
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
)}
</DialogPrimitive.Content>
</DialogPortal>
));

View file

@ -22,7 +22,9 @@ export default {
com_assistants_capabilities: 'Capabilities',
com_assistants_file_search: 'File Search',
com_assistants_file_search_info:
'Attaching vector stores for File Search is not yet supported. You can attach them from the Provider Playground or attach files to messages for file search on a thread basis.',
'File search enables the assistant with knowledge from files that you or your users upload. Once a file is uploaded, the assistant automatically decides when to retrieve content based on user requests. Attaching vector stores for File Search is not yet supported. You can attach them from the Provider Playground or attach files to messages for file search on a thread basis.',
com_assistants_code_interpreter_info:
'Code Interpreter enables the assistant to write and run code. This tool can process files with diverse data and formatting, and generate files such as graphs.',
com_assistants_knowledge: 'Knowledge',
com_assistants_knowledge_info:
'If you upload files under Knowledge, conversations with your Assistant may include file contents.',
@ -30,8 +32,7 @@ export default {
'Assistant must be created, and Code Interpreter or Retrieval must be enabled and saved before uploading files as Knowledge.',
com_assistants_image_vision: 'Image Vision',
com_assistants_code_interpreter: 'Code Interpreter',
com_assistants_code_interpreter_files:
'The following files are only available for Code Interpreter:',
com_assistants_code_interpreter_files: 'Files below are for Code Interpreter only:',
com_assistants_retrieval: 'Retrieval',
com_assistants_search_name: 'Search assistants by name',
com_assistants_tools: 'Tools',
@ -266,6 +267,10 @@ export default {
com_ui_shared_link_not_found: 'Shared link not found',
com_ui_delete_conversation: 'Delete chat?',
com_ui_delete_confirm: 'This will delete',
com_ui_delete_tool: 'Delete Tool',
com_ui_delete_tool_confirm: 'Are you sure you want to delete this tool?',
com_ui_delete_action: 'Delete Action',
com_ui_delete_action_confirm: 'Are you sure you want to delete this action?',
com_ui_delete_confirm_prompt_version_var:
'This will delete the selected version for "{0}." If no other versions exist, the prompt will be deleted.',
com_ui_delete_assistant_confirm:

View file

@ -7,7 +7,8 @@ com_error_moderation:
'Gönderdiğiniz içerik, topluluk kurallarımıza uymadığı için moderasyon sistemimiz tarafından işaretlenmiş görünüyor. Bu belirli konu ile devam edemiyoruz. Başka sorularınız veya incelemek istediğiniz başka konular varsa, mesajınızı düzenleyin veya yeni bir konuşma başlatın.',
com_error_no_user_key: 'Anahtar bulunamadı. Lütfen bir anahtar sağlayın ve tekrar deneyin.',
com_error_no_base_url: 'Temel URL bulunamadı. Lütfen bir tane sağlayın ve tekrar deneyin.',
com_error_invalid_user_key: 'Sağlanan anahtar geçersiz. Lütfen bir anahtar sağlayın ve tekrar deneyin.',
com_error_invalid_user_key:
'Sağlanan anahtar geçersiz. Lütfen bir anahtar sağlayın ve tekrar deneyin.',
com_error_expired_user_key:
'Belirtilen {0} anahtarı {1} tarihinde süresi dolmuş. Lütfen bir anahtar sağlayın ve tekrar deneyin.',
com_files_no_results: 'Sonuç bulunamadı.',
@ -50,7 +51,8 @@ com_assistants_delete_actions_success: 'Asistandan Eylem başarıyla silindi',
com_assistants_update_actions_success: 'Eylem başarıyla oluşturuldu veya güncellendi',
com_assistants_update_actions_error: 'Eylem oluşturma veya güncelleme sırasında bir hata oluştu.',
com_assistants_delete_actions_error: 'Eylem silme sırasında bir hata oluştu.',
com_assistants_actions_info: 'Asistanın API\'leri kullanarak bilgi getirmesine veya eylem gerçekleştirmesine izin ver',
com_assistants_actions_info:
'Asistanın API\'leri kullanarak bilgi getirmesine veya eylem gerçekleştirmesine izin ver',
com_assistants_name_placeholder: 'Seçmeli: asistanın adı',
com_assistants_instructions_placeholder: 'Asistanın kullandığı sistem talimatları',
com_assistants_description_placeholder: 'Seçmeli: Asistanınızın açıklamasını buraya yazın',
@ -79,7 +81,8 @@ com_ui_field_required: 'Bu alan gereklidir',
com_ui_download_error: 'Dosya indirme hatası. Dosya silinmiş olabilir.',
com_ui_attach_error_type: 'Uç nokta için desteklenmeyen dosya türü:',
com_ui_attach_error_openai: 'Asistan dosyalarını diğer uç noktalara ekleyemezsiniz',
com_ui_attach_warn_endpoint: 'Asistan olmayan dosyalar uyumlu bir araç olmadan göz ardı edilebilir',
com_ui_attach_warn_endpoint:
'Asistan olmayan dosyalar uyumlu bir araç olmadan göz ardı edilebilir',
com_ui_attach_error_size: 'Uç nokta için dosya boyutu sınırııldı:',
com_ui_attach_error:
'Dosya eklenemiyor. Bir konuşma oluşturun veya seçin ya da sayfayı yenilemeyi deneyin.',
@ -87,7 +90,8 @@ com_ui_examples: 'Örnekler',
com_ui_new_chat: 'Yeni sohbet',
com_ui_happy_birthday: '1. doğum günüm kutlu olsun!',
com_ui_example_quantum_computing: 'Kuantum hesaplamayı basit terimlerle açıkla',
com_ui_example_10_year_old_b_day: '10 yaşındaki bir çocuğun doğum günü için yaratıcı fikirleriniz var mı?',
com_ui_example_10_year_old_b_day:
'10 yaşındaki bir çocuğun doğum günü için yaratıcı fikirleriniz var mı?',
com_ui_example_http_in_js: 'JavaScript\'te nasıl HTTP isteği yaparım?',
com_ui_capabilities: 'Yetenekler',
com_ui_capability_remember: 'Kullanıcının önceki konuşmalarını hatırlar',
@ -221,12 +225,14 @@ com_ui_share_error: 'Sohbet bağlantısını paylaşırken bir hata oluştu',
com_ui_share_create_message: 'Adınız ve paylaşım sonrasında eklediğiniz mesajlar gizli kalır.',
com_ui_share_created_message:
'Sohbetinize paylaşılan bir bağlantı oluşturuldu. Daha önce paylaşılan sohbetleri istediğiniz zaman Ayarlar aracılığıyla yönetin.',
com_ui_share_update_message: 'Adınız, özel talimatlarınız ve paylaşım sonrasında eklediğiniz mesajlar gizli kalır.',
com_ui_share_updated_message: 'Sohbetinize paylaşılan bir bağlantı güncellendi. Daha önce paylaşılan sohbetleri istediğiniz zaman Ayarlar aracılığıyla yönetin.',
com_ui_share_update_message:
'Adınız, özel talimatlarınız ve paylaşım sonrasında eklediğiniz mesajlar gizli kalır.',
com_ui_share_updated_message:
'Sohbetinize paylaşılan bir bağlantı güncellendi. Daha önce paylaşılan sohbetleri istediğiniz zaman Ayarlar aracılığıyla yönetin.',
com_ui_shared_link_not_found: 'Paylaşılan bağlantı bulunamadı',
com_ui_delete_conversation: 'Sohbeti sil?',
com_ui_delete_conversation_confirm: 'Bu silinecek',
com_ui_delete_assistant_confirm: 'Bu Asistanı gerçekten silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.',
com_ui_delete_assistant_confirm:
'Bu Asistanı gerçekten silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.',
com_ui_rename: 'Yeniden adlandır',
com_ui_archive: 'Arşivle',
com_ui_archive_error: 'Konuşmayı arşivleyemedi',
@ -237,7 +243,8 @@ com_ui_preview: 'Önizleme',
com_ui_upload: 'Yükle',
com_ui_connect: 'Bağlan',
com_ui_locked: 'Kilitli',
com_ui_upload_delay: '"{0}" yüklenmesi beklenenden daha uzun sürüyor. Lütfen dosyanın alma işlemini tamamlamasını bekleyin.',
com_ui_upload_delay:
'"{0}" yüklenmesi beklenenden daha uzun sürüyor. Lütfen dosyanın alma işlemini tamamlamasını bekleyin.',
com_ui_privacy_policy: 'Gizlilik Politikası',
com_ui_terms_of_service: 'Hizmet Şartları',
com_ui_use_micrphone: 'Mikrofon kullan',
@ -287,14 +294,17 @@ com_auth_username_max_length: 'Kullanıcı adı en fazla 20 karakter olmalıdır
com_auth_already_have_account: 'Zaten bir hesabınız var mı?',
com_auth_login: 'Giriş yap',
com_auth_registration_success_insecure: 'Kayıt başarıyla tamamlandı.',
com_auth_registration_success_generic: 'E-posta adresinizi doğrulamak için lütfen e-postanızı kontrol edin.',
com_auth_registration_success_generic:
'E-posta adresinizi doğrulamak için lütfen e-postanızı kontrol edin.',
com_auth_reset_password: 'Şifrenizi sıfırlayın',
com_auth_click: 'Tıklayın',
com_auth_here: 'BURAYA',
com_auth_to_reset_your_password: 'şifrenizi sıfırlamak için.',
com_auth_reset_password_link_sent: 'E-posta gönderildi',
com_auth_reset_password_if_email_exists: 'Bu e-postaya sahip bir hesap varsa, e-posta ile şifre sıfırlama talimatları gönderilmiştir. Lütfen spam klasörünüzü kontrol edin.',
com_auth_reset_password_email_sent: 'Kullanıcı kayıtlıysa, posta kutusuna bir e-posta gönderilecektir.',
com_auth_reset_password_if_email_exists:
'Bu e-postaya sahip bir hesap varsa, e-posta ile şifre sıfırlama talimatları gönderilmiştir. Lütfen spam klasörünüzü kontrol edin.',
com_auth_reset_password_email_sent:
'Kullanıcı kayıtlıysa, posta kutusuna bir e-posta gönderilecektir.',
com_auth_reset_password_success: 'Şifre başarıyla sıfırlandı',
com_auth_login_with_new_password: 'Şimdi yeni şifreniz ile giriş yapabilirsiniz.',
com_auth_error_invalid_reset_token: 'Bu şifre sıfırlama jetonu artık geçerli değil.',
@ -318,8 +328,10 @@ com_endpoint_open_menu: 'Menüyü Aç',
com_endpoint_bing_enable_sydney: 'Sydney\'i Etkinleştir',
com_endpoint_bing_to_enable_sydney: 'Sydney\'i etkinleştirmek için',
com_endpoint_bing_jailbreak: 'Jailbreak',
com_endpoint_bing_context_placeholder: 'Bing, konuşma için referans olarak kullanabileceği \'bağlam\' için 7 bin tokene kadar kullanabilir. Belirli limit bilinmemektedir ancak 7 bin tokenden fazla olması durumunda hatalar oluşabilir',
com_endpoint_bing_system_message_placeholder: 'UYARI: Bu özelliği kötüye kullanmak Bing kullanımınız için YASAKLANMANIZA sebep olabilir! Varsayılan mesajı görebilir veya eklenmiş olan Sistem Mesajı\'nı kullanabilirsiniz.',
com_endpoint_bing_context_placeholder:
'Bing, konuşma için referans olarak kullanabileceği \'bağlam\' için 7 bin tokene kadar kullanabilir. Belirli limit bilinmemektedir ancak 7 bin tokenden fazla olması durumunda hatalar oluşabilir',
com_endpoint_bing_system_message_placeholder:
'UYARI: Bu özelliği kötüye kullanmak Bing kullanımınız için YASAKLANMANIZA sebep olabilir! Varsayılan mesajı görebilir veya eklenmiş olan Sistem Mesajı\'nı kullanabilirsiniz.',
com_endpoint_system_message: 'Sistem Mesajı',
com_endpoint_message: 'Mesaj',
com_endpoint_messages: 'Mesajlar',
@ -334,15 +346,23 @@ com_endpoint_tone_style: 'Ton Tarzı',
com_endpoint_token_count: 'Token sayısı',
com_endpoint_output: ıktı',
com_endpoint_context_tokens: 'Maksimum Bağlam Tokenleri',
com_endpoint_context_info: 'Bağlam için kullanılabilecek maksimum token sayısı. Bu, her istek için kaç token gönderileceğini kontrol etmek içindir. Belirtilmezse, bilinen modellerin bağlam boyutuna göre sistem varsayılanları kullanılacaktır. Daha yüksek değerler belirlemek hatalara ve/veya daha yüksek token maliyetine neden olabilir.',
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_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_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_maxoutputtokens: 'Yanıttaki maksimum token sayısı. Daha kısa yanıtlar için düşük bir değer, daha uzun yanıtlar için yüksek bir değer belirtin.',
com_endpoint_context_info:
'Bağlam için kullanılabilecek maksimum token sayısı. Bu, her istek için kaç token gönderileceğini kontrol etmek içindir. Belirtilmezse, bilinen modellerin bağlam boyutuna göre sistem varsayılanları kullanılacaktır. Daha yüksek değerler belirlemek hatalara ve/veya daha yüksek token maliyetine neden olabilir.',
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_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_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_maxoutputtokens:
'Yanıttaki maksimum token sayısı. Daha kısa yanıtlar için düşük bir değer, daha uzun yanıtlar için yüksek bir değer belirtin.',
com_endpoint_google_custom_name_placeholder: 'Google için özel bir ad ayarlayın',
com_endpoint_prompt_prefix_placeholder: 'Özel talimatlar veya bağlam ayarlayın. Boşsa yok sayılır.',
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_prompt_prefix_assistants_placeholder: 'Asistanın ana talimatlarının üzerine ek talimatlar veya bağlam ekleyin. Boşsa yok sayılır.',
com_endpoint_prompt_prefix_placeholder:
'Özel talimatlar veya bağlam ayarlayın. Boşsa yok sayılır.',
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_prompt_prefix_assistants_placeholder:
'Asistanın ana talimatlarının üzerine ek talimatlar veya bağlam ekleyin. Boşsa yok sayılır.',
com_endpoint_custom_name: 'Özel Ad',
com_endpoint_prompt_prefix: 'Özel Talimatlar',
com_endpoint_prompt_prefix_assistants: 'Ek Talimatlar',
@ -354,22 +374,36 @@ com_endpoint_top_k: 'Top K',
com_endpoint_max_output_tokens: 'Maksimum Çıktı Tokenleri',
com_endpoint_stop: 'Durdurma Sıraları',
com_endpoint_stop_placeholder: 'Değerleri ayırmak için `Enter` tuşuna basın',
com_endpoint_openai_max_tokens: 'İsteğe bağlı `max_tokens` alanı, sohbet tamamlamalarında üretilebilecek maksimum token sayısını temsil eder. Giriş tokenlarının ve üretilen tokenların toplam uzunluğu, modellerin bağlam uzunluğu ile sınırlıdır. Bu sayının maksimum bağlam tokenlarını aşması durumunda hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_temp: 'Yüksek değerler = daha rastgele, düşük değerler = daha odaklı ve belirleyici. Bu parametre ile Olasılık Kütüphanesi (top-p) değiştirmeyi öneririz (ikisini birden değiştirmemek).',
com_endpoint_openai_max: 'Üretilecek maksimum token sayısı. Giriş tokenlarının ve üretilen tokenların toplam uzunluğu modelin bağlam uzunluğu ile sınırlıdır.',
com_endpoint_openai_topp: 'Sıcaklıkla örneklemenin bir alternatifi olan, çekirdek örnekleme olarak adlandırılır, model top_p olasılık kütlesine sahip tokenların sonuçlarını dikkate alır. Yani 0.1, sadece top 10% olasılık kütlesine sahip tokenların dikkate alındığı anlamına gelir. Sıcaklık (temperature) ile değil bu parametre ile değiştirmenizi öneririz.',
com_endpoint_openai_freq: ' -2.0 ile 2.0 arasında bir değer. Pozitif değerler, metinde daha önceki sıklığa bağlı olarak yeni tokenları cezalandırır, bu da modelin aynı hattı kelimesi kelimesine tekrar etme olasılığını azaltır.',
com_endpoint_openai_pres: ' -2.0 ile 2.0 arasında bir değer. Pozitif değerler, metinde daha önceki varlıklarına dayalı olarak yeni tokenları cezalandırır, bu da modelin yeni konular hakkında konuşma olasılığını artırır.',
com_endpoint_openai_resend: 'Daha önce eklenmiş tüm görüntüleri yeniden gönderin. Not: Bu, token maliyetinizi önemli ölçüde artırabilir ve birden çok görüntü eklenmişse hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_resend_files: 'Daha önce eklenmiş tüm dosyaları yeniden gönderin. Not: Bu, token maliyetinizi artıracaktır ve birden çok eklenmiş dosya ile hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_detail: 'Görsel istekleri için çözünürlük. "Düşük" daha ucuz ve hızlıdır, "Yüksek" daha detaylı ve pahalıdır, "Otomatik" ise görüntü çözünürlüğüne göre ikisi arasında otomatik olarak bir seçim yapar.',
com_endpoint_openai_max_tokens:
'İsteğe bağlı `max_tokens` alanı, sohbet tamamlamalarında üretilebilecek maksimum token sayısını temsil eder. Giriş tokenlarının ve üretilen tokenların toplam uzunluğu, modellerin bağlam uzunluğu ile sınırlıdır. Bu sayının maksimum bağlam tokenlarını aşması durumunda hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_temp:
'Yüksek değerler = daha rastgele, düşük değerler = daha odaklı ve belirleyici. Bu parametre ile Olasılık Kütüphanesi (top-p) değiştirmeyi öneririz (ikisini birden değiştirmemek).',
com_endpoint_openai_max:
'Üretilecek maksimum token sayısı. Giriş tokenlarının ve üretilen tokenların toplam uzunluğu modelin bağlam uzunluğu ile sınırlıdır.',
com_endpoint_openai_topp:
'Sıcaklıkla örneklemenin bir alternatifi olan, çekirdek örnekleme olarak adlandırılır, model top_p olasılık kütlesine sahip tokenların sonuçlarını dikkate alır. Yani 0.1, sadece top 10% olasılık kütlesine sahip tokenların dikkate alındığı anlamına gelir. Sıcaklık (temperature) ile değil bu parametre ile değiştirmenizi öneririz.',
com_endpoint_openai_freq:
' -2.0 ile 2.0 arasında bir değer. Pozitif değerler, metinde daha önceki sıklığa bağlı olarak yeni tokenları cezalandırır, bu da modelin aynı hattı kelimesi kelimesine tekrar etme olasılığını azaltır.',
com_endpoint_openai_pres:
' -2.0 ile 2.0 arasında bir değer. Pozitif değerler, metinde daha önceki varlıklarına dayalı olarak yeni tokenları cezalandırır, bu da modelin yeni konular hakkında konuşma olasılığını artırır.',
com_endpoint_openai_resend:
'Daha önce eklenmiş tüm görüntüleri yeniden gönderin. Not: Bu, token maliyetinizi önemli ölçüde artırabilir ve birden çok görüntü eklenmişse hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_resend_files:
'Daha önce eklenmiş tüm dosyaları yeniden gönderin. Not: Bu, token maliyetinizi artıracaktır ve birden çok eklenmiş dosya ile hatalarla karşılaşabilirsiniz.',
com_endpoint_openai_detail:
'Görsel istekleri için çözünürlük. "Düşük" daha ucuz ve hızlıdır, "Yüksek" daha detaylı ve pahalıdır, "Otomatik" ise görüntü çözünürlüğüne göre ikisi arasında otomatik olarak bir seçim yapar.',
com_endpoint_openai_stop: 'API\'nin ek tokenlar üretmeyi durduracağı en fazla 4 sıra.',
com_endpoint_openai_custom_name_placeholder: 'AI için özel bir ad ayarlayın',
com_endpoint_openai_prompt_prefix_placeholder: 'Sistem Mesajına dahil edilecek özel talimatlar ayarlayın. Varsayılan: yok',
com_endpoint_anthropic_temp: '0 ile 1 arasında değişir. Analitik / çoktan seçmeli sorular için 0\'a yakın, yaratıcı ve üretken görevler için 1\'e yakın bir sıcaklık kullanın. Bu parametre ile Olasılık Kütüphanesini değiştirmeyi öneririz (ikisini birden değiştirmemek).',
com_endpoint_anthropic_topp: 'Modelin çıktı için token seçim şeklini değiştirir. Tokenlar, 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_anthropic_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_anthropic_maxoutputtokens: 'Yanıttaki maksimum token sayısı. Daha kısa yanıtlar için düşük bir değer, daha uzun yanıtlar için yüksek bir değer belirtin.',
com_endpoint_openai_prompt_prefix_placeholder:
'Sistem Mesajına dahil edilecek özel talimatlar ayarlayın. Varsayılan: yok',
com_endpoint_anthropic_temp:
'0 ile 1 arasında değişir. Analitik / çoktan seçmeli sorular için 0\'a yakın, yaratıcı ve üretken görevler için 1\'e yakın bir sıcaklık kullanın. Bu parametre ile Olasılık Kütüphanesini değiştirmeyi öneririz (ikisini birden değiştirmemek).',
com_endpoint_anthropic_topp:
'Modelin çıktı için token seçim şeklini değiştirir. Tokenlar, 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_anthropic_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_anthropic_maxoutputtokens:
'Yanıttaki maksimum token sayısı. Daha kısa yanıtlar için düşük bir değer, daha uzun yanıtlar için yüksek bir değer belirtin.',
com_endpoint_anthropic_custom_name_placeholder: 'Anthropic için özel bir ad ayarlayın',
com_endpoint_frequency_penalty: 'Sıklık Cezası',
com_endpoint_presence_penalty: 'Varlık Cezası',
@ -380,15 +414,20 @@ com_endpoint_plug_image_detail: 'Görüntü Detayı',
com_endpoint_plug_skip_completion: 'Tamamlamayı Atla',
com_endpoint_disabled_with_tools: 'Araçlar ile devre dışı',
com_endpoint_disabled_with_tools_placeholder: 'Araçlar ile Devre Dışı Bırakılmış',
com_endpoint_plug_set_custom_instructions_for_gpt_placeholder: 'Sistem Mesajına dahil edilecek özel talimatlar ayarlayın. Varsayılan: yok',
com_endpoint_plug_set_custom_instructions_for_gpt_placeholder:
'Sistem Mesajına dahil edilecek özel talimatlar ayarlayın. Varsayılan: yok',
com_endpoint_import: 'İthal et',
com_endpoint_set_custom_name: 'Özelleştirmenizi adlandırın, böylece bu ayarlanabilir',
com_endpoint_preset_delete_confirm: 'Bu hazır ayarı silmek istediğinizden emin misiniz?',
com_endpoint_preset_clear_all_confirm: 'Tüm hazır ayarlarınızı silmek istediğinizden emin misiniz?',
com_endpoint_preset_clear_all_confirm:
'Tüm hazır ayarlarınızı silmek istediğinizden emin misiniz?',
com_endpoint_preset_import: 'Hazır Ayar İthal Edildi!',
com_endpoint_preset_import_error: 'Hazır ayarınızı ithal ederken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_save_error: 'Hazır ayarınızı kaydederken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_delete_error: 'Hazır ayarınızı silerken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_import_error:
'Hazır ayarınızı ithal ederken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_save_error:
'Hazır ayarınızı kaydederken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_delete_error:
'Hazır ayarınızı silerken bir hata oluştu. Lütfen tekrar deneyin.',
com_endpoint_preset_default_removed: 'Artık varsayılan hazır ayar değil.',
com_endpoint_preset_default_item: 'Varsayılan:',
com_endpoint_preset_default_none: 'Aktif varsayılan hazır ayar yok.',
@ -414,7 +453,8 @@ com_endpoint_assistant: 'Asistan',
com_endpoint_use_active_assistant: 'Etkin Asistanı Kullan',
com_endpoint_assistant_model: 'Asistan Modeli',
com_endpoint_save_as_preset: 'Hazır Olarak Kaydet',
com_endpoint_presets_clear_warning: 'Tüm hazır ayarları temizlemek istediğinizden emin misiniz? Bu geri alınamaz.',
com_endpoint_presets_clear_warning:
'Tüm hazır ayarları temizlemek istediğinizden emin misiniz? Bu geri alınamaz.',
com_endpoint_not_implemented: 'Uygulanmadı',
com_endpoint_no_presets: 'Henüz hazır ayar yok, birini oluşturmak için ayar düğmesini kullanın',
com_endpoint_not_available: 'Kullanılabilir uç nokta yok',
@ -424,7 +464,8 @@ com_endpoint_my_preset: 'Benim Hazırım',
com_endpoint_agent_model: 'Temsilci Modeli (Önerilen: GPT-3.5)',
com_endpoint_completion_model: 'Tamamlanma Modeli (Önerilen: GPT-4)',
com_endpoint_func_hover: 'Eklentilerin OpenAI Fonksiyonları olarak kullanılmasını etkinleştir',
com_endpoint_skip_hover: 'Tamamlama adımını atlamayı etkinleştir, bu adım nihai yanıtı ve oluşturulan adımları gözden geçirir',
com_endpoint_skip_hover:
'Tamamlama adımını atlamayı etkinleştir, bu adım nihai yanıtı ve oluşturulan adımları gözden geçirir',
com_endpoint_config_key: 'API Anahtarını Ayarla',
com_endpoint_assistant_placeholder: 'Lütfen sağ tarafta bir Asistan seçin',
com_endpoint_config_placeholder: 'Sohbet etmek için Anahtarınızı Başlık menüsünde ayarlayın.',
@ -441,13 +482,18 @@ com_endpoint_config_google_api_key: 'Google API Anahtarı',
com_endpoint_config_google_gemini_api: '(Gemini API)',
com_endpoint_config_google_api_info: 'Gemini için Yapay Zeka Dil API Anahtarınızı almak için,',
com_endpoint_config_key_import_json_key: 'Hizmet Hesabı JSON Anahtarını İçe Aktar.',
com_endpoint_config_key_import_json_key_success: 'Hizmet Hesabı JSON Anahtarı Başarıyla İthal Edildi',
com_endpoint_config_key_import_json_key_invalid: 'Geçersiz Hizmet Hesabı JSON Anahtarı, doğru dosyayı ithal ettiniz mi?',
com_endpoint_config_key_get_edge_key: 'Bing için Erişim anahtarınızı almak için, şuraya giriş yapın',
com_endpoint_config_key_get_edge_key_dev_tool: 'Siteye giriş yaptıktan sonra geliştirici araçlarını veya uzantısını kullanarak _U çerezi içeriğini kopyalayın. Bu başarısız olursa, bu',
com_endpoint_config_key_import_json_key_success:
'Hizmet Hesabı JSON Anahtarı Başarıyla İthal Edildi',
com_endpoint_config_key_import_json_key_invalid:
'Geçersiz Hizmet Hesabı JSON Anahtarı, doğru dosyayı ithal ettiniz mi?',
com_endpoint_config_key_get_edge_key:
'Bing için Erişim anahtarınızı almak için, şuraya giriş yapın',
com_endpoint_config_key_get_edge_key_dev_tool:
'Siteye giriş yaptıktan sonra geliştirici araçlarını veya uzantısını kullanarak _U çerezi içeriğini kopyalayın. Bu başarısız olursa, bu',
com_endpoint_config_key_edge_instructions: 'talimatları takip edin',
com_endpoint_config_key_edge_full_key_string: 'tam çerez dizelerini sağlamak için',
com_endpoint_config_key_chatgpt: 'ChatGPT \'Ücretsiz Sürüm\' için Erişim anahtarınızı almak için, şuraya giriş yapın',
com_endpoint_config_key_chatgpt:
'ChatGPT \'Ücretsiz Sürüm\' için Erişim anahtarınızı almak için, şuraya giriş yapın',
com_endpoint_config_key_chatgpt_then_visit: 'sonra burayı ziyaret edin',
com_endpoint_config_key_chatgpt_copy_token: 'Erişim anahtarını kopyalayın.',
com_endpoint_config_key_google_need_to: 'Şu işlemi yapmanız gerekiyor',
@ -480,7 +526,8 @@ com_hide_examples: 'Örnekleri Gizle',
com_show_examples: 'Örnekleri Göster',
com_nav_plugin_search: 'Eklentileri Ara',
com_nav_tool_search: 'Araçları Ara',
com_nav_plugin_auth_error: 'Bu eklenti ile kimlik doğrulama işlemi sırasında bir hata oluştu. Lütfen tekrar deneyin.',
com_nav_plugin_auth_error:
'Bu eklenti ile kimlik doğrulama işlemi sırasında bir hata oluştu. Lütfen tekrar deneyin.',
com_nav_export_filename: 'Dosya adı',
com_nav_export_filename_placeholder: 'Dosya adını belirle',
com_nav_export_type: 'Tür',
@ -522,7 +569,8 @@ com_nav_archive_all: 'Hepsini arşivle',
com_nav_archive_name: 'Ad',
com_nav_archive_created_at: 'Oluşturulma Tarihi',
com_nav_clear_conversation: 'Sohbetleri temizle',
com_nav_clear_conversation_confirm_message: 'Tüm konuşmaları temizlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.',
com_nav_clear_conversation_confirm_message:
'Tüm konuşmaları temizlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.',
com_nav_help_faq: 'Yardım & SS',
com_nav_settings: 'Ayarlar',
com_nav_search_placeholder: 'Mesajları ara',
@ -530,7 +578,8 @@ com_nav_delete_account: 'Hesabı sil',
com_nav_delete_account_confirm: 'Hesabı silmek istediğinizden emin misiniz?',
com_nav_delete_account_button: 'Hesabımı kalıcı olarak sil',
com_nav_delete_account_email_placeholder: 'Lütfen hesap e-postanızı girin',
com_nav_delete_account_confirm_placeholder: 'Devam etmek için, aşağıdaki giriş alanında "SİL" yazın',
com_nav_delete_account_confirm_placeholder:
'Devam etmek için, aşağıdaki giriş alanında "SİL" yazın',
com_nav_delete_warning: 'UYARI: Bu işlem hesabınızı kalıcı olarak silecektir.',
com_nav_delete_data_info: 'Tüm verileriniz silinecektir.',
com_nav_conversation_mode: 'Konuşma Modu',