mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 18:00:15 +01:00
📥 feat: Import Conversations from LibreChat, ChatGPT, Chatbot UI (#2355)
* Basic implementation of ChatGPT conversation import * remove debug code * Handle citations * Fix updatedAt in import * update default model * Use job scheduler to handle import requests * import job status endpoint * Add wrapper around Agenda * Rate limits for import endpoint * rename import api path * Batch save import to mongo * Improve naming * Add documenting comments * Test for importers * Change button for importing conversations * Frontend changes * Import job status endpoint * Import endpoint response * Add translations to new phrases * Fix conversations refreshing * cleanup unused functions * set timeout for import job status polling * Add documentation * get extra spaces back * Improve error message * Fix translation files after merge * fix translation files 2 * Add zh translation for import functionality * Sync mailisearch index after import * chore: add dummy uri for jest tests, as MONGO_URI should only be real for E2E tests * docs: fix links * docs: fix conversationsImport section * fix: user role issue for librechat imports * refactor: import conversations from json - organize imports - add additional jsdocs - use multer with diskStorage to avoid loading file into memory outside of job - use filepath instead of loading data string for imports - replace console logs and some logger.info() with logger.debug - only use multer for import route * fix: undefined metadata edge case and replace ChatGtp -> ChatGpt * Refactor importChatGptConvo function to handle undefined metadata edge case and replace ChatGtp with ChatGpt * fix: chatgpt importer * feat: maintain tree relationship for librechat messages * chore: use enum * refactor: saveMessage to use single object arg, replace console logs, add userId to log message * chore: additional comment * chore: multer edge case * feat: first pass, maintain tree relationship * chore: organize * chore: remove log * ci: add heirarchy test for chatgpt * ci: test maintaining of heirarchy for librechat * wip: allow non-text content type messages * refactor: import content part object json string * refactor: more content types to format * chore: consolidate messageText formatting * docs: update on changes, bump data-provider/config versions, update readme * refactor(indexSync): singleton pattern for MeiliSearchClient * refactor: debug log after batch is done * chore: add back indexSync error handling --------- Co-authored-by: jakubmieszczak <jakub.mieszczak@zendesk.com> Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
3b44741cf9
commit
ab6fbe48f1
64 changed files with 3795 additions and 98 deletions
|
|
@ -7,6 +7,7 @@ import { SettingsTabValues } from 'librechat-data-provider';
|
|||
import React, { useState, useCallback, useRef } from 'react';
|
||||
import { useOnClickOutside } from '~/hooks';
|
||||
import DangerButton from '../DangerButton';
|
||||
import ImportConversations from './ImportConversations';
|
||||
|
||||
export const RevokeKeysButton = ({
|
||||
showText = true,
|
||||
|
|
@ -76,6 +77,9 @@ function Data() {
|
|||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
||||
<RevokeKeysButton all={true} />
|
||||
</div>
|
||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
||||
<ImportConversations />
|
||||
</div>
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
import { Import } from 'lucide-react';
|
||||
import { cn } from '~/utils';
|
||||
import { useUploadConversationsMutation } from '~/data-provider';
|
||||
import { useLocalize, useConversations } from '~/hooks';
|
||||
import { useState } from 'react';
|
||||
import { useToastContext } from '~/Providers';
|
||||
|
||||
function ImportConversations() {
|
||||
const localize = useLocalize();
|
||||
|
||||
const { showToast } = useToastContext();
|
||||
const [, setErrors] = useState<string[]>([]);
|
||||
const setError = (error: string) => setErrors((prevErrors) => [...prevErrors, error]);
|
||||
const { refreshConversations } = useConversations();
|
||||
|
||||
const uploadFile = useUploadConversationsMutation({
|
||||
onSuccess: () => {
|
||||
refreshConversations();
|
||||
showToast({ message: localize('com_ui_import_conversation_success') });
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('Error: ', error);
|
||||
setError(
|
||||
(error as { response: { data: { message?: string } } })?.response?.data?.message ??
|
||||
'An error occurred while uploading the file.',
|
||||
);
|
||||
if (error?.toString().includes('Unsupported import type')) {
|
||||
showToast({
|
||||
message: localize('com_ui_import_conversation_file_type_error'),
|
||||
status: 'error',
|
||||
});
|
||||
} else {
|
||||
showToast({ message: localize('com_ui_import_conversation_error'), status: 'error' });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const startUpload = async (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file, encodeURIComponent(file?.name || 'File'));
|
||||
|
||||
uploadFile.mutate(formData);
|
||||
};
|
||||
|
||||
const handleFiles = async (_file: File) => {
|
||||
console.log('Handling files...');
|
||||
|
||||
/* Process files */
|
||||
try {
|
||||
await startUpload(_file);
|
||||
} catch (error) {
|
||||
console.log('file handling error', error);
|
||||
setError('An error occurred while processing the file.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileChange = (event) => {
|
||||
console.log('file change');
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
handleFiles(file);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<span>{localize('com_ui_import_conversation_info')}</span>
|
||||
<label
|
||||
htmlFor={'import-conversations-file'}
|
||||
className="flex h-auto cursor-pointer items-center rounded bg-transparent px-2 py-1 text-xs font-medium font-normal transition-colors hover:bg-gray-100 hover:text-green-700 dark:bg-transparent dark:text-white dark:hover:bg-gray-600 dark:hover:text-green-500"
|
||||
>
|
||||
<Import className="mr-1 flex w-[22px] items-center stroke-1" />
|
||||
<span>{localize('com_ui_import_conversation')}</span>
|
||||
<input
|
||||
id={'import-conversations-file'}
|
||||
value=""
|
||||
type="file"
|
||||
className={cn('hidden')}
|
||||
accept=".json"
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ImportConversations;
|
||||
|
|
@ -6,8 +6,10 @@ import type {
|
|||
TFile,
|
||||
BatchFile,
|
||||
TFileUpload,
|
||||
TImportStartResponse,
|
||||
AssistantListResponse,
|
||||
UploadMutationOptions,
|
||||
UploadConversationsMutationOptions,
|
||||
DeleteFilesResponse,
|
||||
DeleteFilesBody,
|
||||
DeleteMutationOptions,
|
||||
|
|
@ -131,6 +133,89 @@ export const useDeleteConversationMutation = (
|
|||
);
|
||||
};
|
||||
|
||||
export const useUploadConversationsMutation = (_options?: UploadConversationsMutationOptions) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { onSuccess, onError } = _options || {};
|
||||
|
||||
// returns the job status or reason of failure
|
||||
const checkJobStatus = async (jobId) => {
|
||||
try {
|
||||
const response = await dataService.queryImportConversationJobStatus(jobId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw new Error('Failed to check job status');
|
||||
}
|
||||
};
|
||||
|
||||
// Polls the job status until it is completed, failed, or timed out
|
||||
const pollJobStatus = (jobId, onSuccess, onError) => {
|
||||
let timeElapsed = 0;
|
||||
const timeout = 60000; // Timeout after a minute
|
||||
const pollInterval = 500; // Poll every 500ms
|
||||
const intervalId = setInterval(async () => {
|
||||
try {
|
||||
const statusResponse = await checkJobStatus(jobId);
|
||||
console.log('Polling job status', statusResponse);
|
||||
if (statusResponse.status === 'completed' || statusResponse.status === 'failed') {
|
||||
clearInterval(intervalId);
|
||||
if (statusResponse.status === 'completed') {
|
||||
onSuccess && onSuccess(statusResponse);
|
||||
} else {
|
||||
onError &&
|
||||
onError(
|
||||
new Error(
|
||||
statusResponse.failReason
|
||||
? statusResponse.failReason
|
||||
: 'Failed to import conversations',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
timeElapsed += pollInterval; // Increment time elapsed by polling interval
|
||||
if (timeElapsed >= timeout) {
|
||||
clearInterval(intervalId);
|
||||
onError && onError(new Error('Polling timed out'));
|
||||
}
|
||||
} catch (error) {
|
||||
clearInterval(intervalId);
|
||||
onError && onError(error);
|
||||
}
|
||||
}, pollInterval);
|
||||
};
|
||||
return useMutation<TImportStartResponse, unknown, FormData>({
|
||||
mutationFn: (formData: FormData) => dataService.importConversationsFile(formData),
|
||||
onSuccess: (data, variables, context) => {
|
||||
queryClient.invalidateQueries([QueryKeys.allConversations]);
|
||||
// Assuming the job ID is in the response data
|
||||
const jobId = data.jobId;
|
||||
if (jobId) {
|
||||
// Start polling for job status
|
||||
pollJobStatus(
|
||||
jobId,
|
||||
(statusResponse) => {
|
||||
// This is the final success callback when the job is completed
|
||||
queryClient.invalidateQueries([QueryKeys.allConversations]); // Optionally refresh conversations query
|
||||
if (onSuccess) {
|
||||
onSuccess(statusResponse, variables, context);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// This is the error callback for job failure or polling errors
|
||||
if (onError) {
|
||||
onError(error, variables, context);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
onError: (err, variables, context) => {
|
||||
if (onError) {
|
||||
onError(err, variables, context);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useUploadFileMutation = (
|
||||
_options?: UploadMutationOptions,
|
||||
): UseMutationResult<
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ export default {
|
|||
com_ui_clear: 'مسح',
|
||||
com_ui_revoke: 'إلغاء',
|
||||
com_ui_revoke_info: 'إلغاء جميع بيانات الاعتماد المقدمة من المستخدم.',
|
||||
com_ui_import_conversation: 'استيراد',
|
||||
com_ui_import_conversation_info: 'استيراد محادثات من ملف JSON',
|
||||
com_ui_import_conversation_success: 'تم استيراد المحادثات بنجاح',
|
||||
com_ui_import_conversation_error: 'حدث خطأ أثناء استيراد محادثاتك',
|
||||
com_ui_confirm_action: 'تأكيد الإجراء',
|
||||
com_ui_chats: 'الدردشات',
|
||||
com_ui_delete: 'حذف',
|
||||
|
|
|
|||
|
|
@ -119,6 +119,10 @@ export default {
|
|||
com_ui_clear: 'Limpar',
|
||||
com_ui_revoke: 'Revogar',
|
||||
com_ui_revoke_info: 'Revogar todas as credenciais fornecidas pelo usuário',
|
||||
com_ui_import_conversation: 'Importar',
|
||||
com_ui_import_conversation_info: 'Importe conversas de um arquivo JSON',
|
||||
com_ui_import_conversation_success: 'Conversas importadas com sucesso',
|
||||
com_ui_import_conversation_error: 'Houve um erro ao importar suas conversas',
|
||||
com_ui_confirm_action: 'Confirmar Ação',
|
||||
com_ui_chats: 'conversas',
|
||||
com_ui_avatar: 'Avatar',
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@ export default {
|
|||
com_ui_clear: 'Löschen',
|
||||
com_ui_revoke: 'Widerrufen',
|
||||
com_ui_revoke_info: 'Widerrufe alle vom Benutzer angegebenen Anmeldeinformationen',
|
||||
com_ui_import_conversation: 'Importieren',
|
||||
com_ui_import_conversation_info: 'Chats aus einer JSON-Datei importieren',
|
||||
com_ui_import_conversation_success: 'Chats erfolgreich importiert',
|
||||
com_ui_import_conversation_error: 'Beim Importieren Ihrer Chats ist ein Fehler aufgetreten',
|
||||
com_ui_confirm_action: 'Bestätige Aktion',
|
||||
com_ui_chats: 'Chats',
|
||||
com_ui_avatar: 'Avatar',
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@ export default {
|
|||
com_ui_clear: 'Clear',
|
||||
com_ui_revoke: 'Revoke',
|
||||
com_ui_revoke_info: 'Revoke all user provided credentials',
|
||||
com_ui_import_conversation: 'Import',
|
||||
com_ui_import_conversation_info: 'Import conversations from a JSON file',
|
||||
com_ui_import_conversation_success: 'Conversations imported successfully',
|
||||
com_ui_import_conversation_error: 'There was an error importing your conversations',
|
||||
com_ui_import_conversation_file_type_error: 'Unsupported import type',
|
||||
com_ui_confirm_action: 'Confirm Action',
|
||||
com_ui_chats: 'chats',
|
||||
com_ui_avatar: 'Avatar',
|
||||
|
|
|
|||
|
|
@ -121,6 +121,10 @@ export default {
|
|||
com_ui_clear: 'Limpiar',
|
||||
com_ui_revoke: 'Revocar',
|
||||
com_ui_revoke_info: 'Revocar todas las credenciales proporcionadas por el usuario',
|
||||
com_ui_import_conversation: 'Importar',
|
||||
com_ui_import_conversation_info: 'Importar chats de un archivo JSON',
|
||||
com_ui_import_conversation_success: 'Chats importados exitosamente',
|
||||
com_ui_import_conversation_error: 'Hubo un error al importar tus chats',
|
||||
com_ui_confirm_action: 'Confirmar Acción',
|
||||
com_ui_chats: 'conversaciones',
|
||||
com_ui_avatar: 'Avatar',
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@ export default {
|
|||
com_ui_revoke: 'Révoquer',
|
||||
com_ui_revoke_info:
|
||||
'Révoquer toutes les informations d\'identification fournies par l\'utilisateur',
|
||||
com_ui_import_conversation: 'Importer',
|
||||
com_ui_import_conversation_info: 'Importer des conversations à partir d’un fichier JSON',
|
||||
com_ui_import_conversation_success: 'Conversations importées avec succès',
|
||||
com_ui_import_conversation_error:
|
||||
'Une erreur s’est produite lors de l’importation de vos conversations',
|
||||
com_ui_confirm_action: 'Confirmer l\'action',
|
||||
com_ui_chats: 'discussions',
|
||||
com_ui_delete: 'Supprimer',
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ export default {
|
|||
com_ui_clear: 'נקה',
|
||||
com_ui_revoke: 'בטל',
|
||||
com_ui_revoke_info: 'בטל את כל האישורים שסופקו על ידי המשתמש',
|
||||
com_ui_import_conversation: 'יבוא',
|
||||
com_ui_import_conversation_info: 'ייבא שיחות מקובץ JSON',
|
||||
com_ui_import_conversation_success: 'השיחות יובאו בהצלחה',
|
||||
com_ui_import_conversation_error: 'אירעה שגיאה בעת ייבוא השיחות שלך',
|
||||
com_ui_confirm_action: 'אשר פעולה',
|
||||
com_ui_chats: 'צאטים',
|
||||
com_ui_assistant: 'סייען',
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ export default {
|
|||
com_ui_clear: 'Bersihkan',
|
||||
com_ui_revoke: 'Cabut',
|
||||
com_ui_revoke_info: 'Cabut semua kredensial yang diberikan pengguna',
|
||||
com_ui_import_conversation: 'Impor',
|
||||
com_ui_import_conversation_info: 'Impor percakapan dari file JSON',
|
||||
com_ui_import_conversation_success: 'Percakapan berhasil diimpor',
|
||||
com_ui_import_conversation_error: 'Terjadi kesalahan saat mengimpor percakapan Anda',
|
||||
com_ui_confirm_action: 'Konfirmasi Aksi',
|
||||
com_ui_chats: 'chat',
|
||||
com_ui_delete: 'Hapus',
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ export default {
|
|||
com_ui_clear: 'Pulisci',
|
||||
com_ui_revoke: 'Revoca',
|
||||
com_ui_revoke_info: 'Revoca tutte le credenziali fornite dall\'utente',
|
||||
com_ui_import_conversation: 'Importa',
|
||||
com_ui_import_conversation_info: 'Importa conversazioni da un file JSON',
|
||||
com_ui_import_conversation_success: 'Conversazioni importate con successo',
|
||||
com_ui_import_conversation_error:
|
||||
'Si è verificato un errore durante l’importazione delle tue conversazioni',
|
||||
com_ui_confirm_action: 'Conferma azione',
|
||||
com_ui_chats: 'chat',
|
||||
com_ui_delete: 'Elimina',
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ export default {
|
|||
com_ui_clear: '削除する',
|
||||
com_ui_revoke: '無効にする',
|
||||
com_ui_revoke_info: 'ユーザへ発行した認証情報をすべて無効にする。',
|
||||
com_ui_import_conversation: 'インポート',
|
||||
com_ui_import_conversation_info: 'JSONファイルから会話をインポートする',
|
||||
com_ui_import_conversation_success: '会話のインポートに成功しました',
|
||||
com_ui_import_conversation_error: '会話のインポート時にエラーが発生しました',
|
||||
com_ui_confirm_action: '実行する',
|
||||
com_ui_chats: 'チャット',
|
||||
com_ui_avatar: 'アバター',
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ export default {
|
|||
com_ui_clear: '지우기',
|
||||
com_ui_revoke: '취소',
|
||||
com_ui_revoke_info: '사용자가 제공한 자격 증명을 모두 취소합니다.',
|
||||
com_ui_import_conversation: '가져오기',
|
||||
com_ui_import_conversation_info: 'JSON 파일에서 대화 가져오기',
|
||||
com_ui_import_conversation_success: '대화가 성공적으로 가져와졌습니다',
|
||||
com_ui_import_conversation_error: '대화를 가져오는 동안 오류가 발생했습니다',
|
||||
com_ui_confirm_action: '작업 확인',
|
||||
com_ui_chats: '채팅',
|
||||
com_ui_delete: '삭제',
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ export default {
|
|||
com_ui_clear: 'Wissen',
|
||||
com_ui_revoke: 'Intrekken',
|
||||
com_ui_revoke_info: 'Trek alle door de gebruiker verstrekte referenties in',
|
||||
com_ui_import_conversation: 'Importeren',
|
||||
com_ui_import_conversation_info: 'Gesprekken importeren vanuit een JSON-bestand',
|
||||
com_ui_import_conversation_success: 'Gesprekken succesvol geïmporteerd',
|
||||
com_ui_import_conversation_error:
|
||||
'Er is een fout opgetreden bij het importeren van je gesprekken',
|
||||
com_ui_confirm_action: 'Bevestig actie',
|
||||
com_ui_chats: 'chats',
|
||||
com_ui_delete: 'Verwijderen',
|
||||
|
|
|
|||
|
|
@ -205,4 +205,8 @@ export default {
|
|||
com_nav_settings: 'Ustawienia',
|
||||
com_nav_search_placeholder: 'Szukaj wiadomości',
|
||||
com_nav_setting_general: 'Ogólne',
|
||||
com_ui_import_conversation: 'Importuj',
|
||||
com_ui_import_conversation_info: 'Importuj konwersacje z pliku JSON',
|
||||
com_ui_import_conversation_success: 'Konwersacje zostały pomyślnie zaimportowane',
|
||||
com_ui_import_conversation_error: 'Wystąpił błąd podczas importowania konwersacji',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ export default {
|
|||
com_ui_clear: 'Удалить',
|
||||
com_ui_revoke: 'Отозвать',
|
||||
com_ui_revoke_info: 'Отозвать все предоставленные пользователем учетные данные',
|
||||
com_ui_import_conversation: 'Импортировать',
|
||||
com_ui_import_conversation_info: 'Импортировать беседы из файла JSON',
|
||||
com_ui_import_conversation_success: 'Беседы успешно импортированы',
|
||||
com_ui_import_conversation_error: 'При импорте бесед произошла ошибка',
|
||||
com_ui_confirm_action: 'Подтвердить действие',
|
||||
com_ui_chats: 'чаты',
|
||||
com_ui_delete: 'Удалить',
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ export default {
|
|||
com_ui_clear: 'Rensa',
|
||||
com_ui_revoke: 'Återkalla',
|
||||
com_ui_revoke_info: 'Återkalla alla användaruppgifter.',
|
||||
com_ui_import_conversation: 'Importera',
|
||||
com_ui_import_conversation_info: 'Importera konversationer från en JSON-fil',
|
||||
com_ui_import_conversation_success: 'Konversationer har importerats framgångsrikt',
|
||||
com_ui_import_conversation_error: 'Det uppstod ett fel vid import av dina konversationer',
|
||||
com_ui_confirm_action: 'Bekräfta åtgärd',
|
||||
com_ui_chats: 'chattar',
|
||||
com_ui_delete: 'Radera',
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ export default {
|
|||
com_ui_clear: 'Temizle',
|
||||
com_ui_revoke: 'İptal et',
|
||||
com_ui_revoke_info: 'Tüm kullanıcı tarafından verilen kimlik bilgilerini iptal et.',
|
||||
com_ui_import_conversation: 'İçe Aktar',
|
||||
com_ui_import_conversation_info: 'Bir JSON dosyasından sohbetleri içe aktar',
|
||||
com_ui_import_conversation_success: 'Sohbetler başarıyla içe aktarıldı',
|
||||
com_ui_import_conversation_error: 'Sohbetlerinizi içe aktarırken bir hata oluştu',
|
||||
com_ui_confirm_action: 'İşlemi Onayla',
|
||||
com_ui_chats: 'sohbetler',
|
||||
com_ui_delete: 'Sil',
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ export default {
|
|||
com_ui_clear: 'Xóa',
|
||||
com_ui_revoke: 'Hủy bỏ',
|
||||
com_ui_revoke_info: 'Hủy bỏ tất cả các thông tin xác thực được cung cấp bởi người dùng.',
|
||||
com_ui_import_conversation: 'Nhập khẩu',
|
||||
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',
|
||||
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_confirm_action: 'Xác nhận hành động',
|
||||
com_ui_chats: 'cuộc trò chuyện',
|
||||
com_ui_delete: 'Xóa',
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ export default {
|
|||
com_sidepanel_manage_files: '管理文件',
|
||||
com_assistants_capabilities: '功能',
|
||||
com_assistants_knowledge: '知识',
|
||||
com_assistants_knowledge_info:
|
||||
'如果您在“知识”中上传文件,与助手的对话可能包括文件内容。',
|
||||
com_assistants_knowledge_info: '如果您在“知识”中上传文件,与助手的对话可能包括文件内容。',
|
||||
com_assistants_knowledge_disabled:
|
||||
'必须创建助手,且启用并保存代码解释器或检索,才能将文件作为知识上传。',
|
||||
com_assistants_image_vision: '识图',
|
||||
com_assistants_code_interpreter: '代码解释器',
|
||||
com_assistants_code_interpreter_files:
|
||||
'以下文件仅适用于代码解释器:',
|
||||
com_assistants_code_interpreter_files: '以下文件仅适用于代码解释器:',
|
||||
com_assistants_retrieval: '检索',
|
||||
com_assistants_search_name: '按名称搜索助手',
|
||||
com_assistants_tools: '工具',
|
||||
|
|
@ -50,8 +48,7 @@ export default {
|
|||
com_ui_download_error: '下载文件时出错,该文件可能已被删除。',
|
||||
com_ui_attach_error_type: '渠道不支持的文件类型:',
|
||||
com_ui_attach_error_size: '超出渠道规定的文件大小:',
|
||||
com_ui_attach_error:
|
||||
'无法附加文件,请创建或选择一个对话,或尝试刷新页面。',
|
||||
com_ui_attach_error: '无法附加文件,请创建或选择一个对话,或尝试刷新页面。',
|
||||
com_ui_examples: '示例',
|
||||
com_ui_new_chat: '创建新对话',
|
||||
com_ui_happy_birthday: '这是我的第一个生日!',
|
||||
|
|
@ -64,8 +61,7 @@ export default {
|
|||
com_ui_capability_decline_requests: '限制不当信息',
|
||||
com_ui_limitations: '局限性',
|
||||
com_ui_limitation_incorrect_info: '可能会不时出现错误信息',
|
||||
com_ui_limitation_harmful_biased:
|
||||
'可能会提供有害指示或者偏见',
|
||||
com_ui_limitation_harmful_biased: '可能会提供有害指示或者偏见',
|
||||
com_ui_limitation_limited_2021: '基于2021年以前信息训练',
|
||||
com_ui_experimental: '实验性',
|
||||
com_ui_ascending: '升序',
|
||||
|
|
@ -120,6 +116,10 @@ export default {
|
|||
com_ui_clear: '清除',
|
||||
com_ui_revoke: '撤销',
|
||||
com_ui_revoke_info: '撤销所有用户提供的凭据',
|
||||
com_ui_import_conversation: '导入',
|
||||
com_ui_import_conversation_info: '从JSON文件导入对话',
|
||||
com_ui_import_conversation_success: '对话导入成功',
|
||||
com_ui_import_conversation_error: '导入对话时发生错误',
|
||||
com_ui_confirm_action: '确认执行',
|
||||
com_ui_chats: '聊天',
|
||||
com_ui_avatar: '头像',
|
||||
|
|
@ -134,23 +134,17 @@ export default {
|
|||
com_ui_create: '创建',
|
||||
com_ui_delete_conversation: '删除对话?',
|
||||
com_ui_delete_conversation_confirm: '这将删除',
|
||||
com_ui_delete_assistant_confirm:
|
||||
'确定要删除此助手吗?该操作无法撤销。',
|
||||
com_ui_delete_assistant_confirm: '确定要删除此助手吗?该操作无法撤销。',
|
||||
com_ui_preview: '预览',
|
||||
com_ui_upload: '上传',
|
||||
com_ui_connect: '连接',
|
||||
com_ui_upload_delay:
|
||||
'上传 "{0}" 时比预期花了更长时间。 文件正在进行检索索引,请稍候。',
|
||||
com_ui_upload_delay: '上传 "{0}" 时比预期花了更长时间。 文件正在进行检索索引,请稍候。',
|
||||
com_ui_privacy_policy: '隐私政策',
|
||||
com_ui_terms_of_service: '服务政策',
|
||||
com_auth_error_login:
|
||||
'无法登录,请确认提供的账户密码正确,并重新尝试。',
|
||||
com_auth_error_login_rl:
|
||||
'尝试登录次数过多,请稍后再试。',
|
||||
com_auth_error_login_ban:
|
||||
'根据我们的服务规则,您的帐号被暂时禁用。',
|
||||
com_auth_error_login_server:
|
||||
'内部服务器错误,请稍后再试。',
|
||||
com_auth_error_login: '无法登录,请确认提供的账户密码正确,并重新尝试。',
|
||||
com_auth_error_login_rl: '尝试登录次数过多,请稍后再试。',
|
||||
com_auth_error_login_ban: '根据我们的服务规则,您的帐号被暂时禁用。',
|
||||
com_auth_error_login_server: '内部服务器错误,请稍后再试。',
|
||||
com_auth_no_account: '新用户注册',
|
||||
com_auth_sign_up: '注册',
|
||||
com_auth_sign_in: '登录',
|
||||
|
|
@ -173,8 +167,7 @@ export default {
|
|||
com_auth_password_not_match: '密码不一致',
|
||||
com_auth_continue: '继续',
|
||||
com_auth_create_account: '创建账号',
|
||||
com_auth_error_create:
|
||||
'注册账户过程中出现错误,请重试。',
|
||||
com_auth_error_create: '注册账户过程中出现错误,请重试。',
|
||||
com_auth_full_name: '姓名',
|
||||
com_auth_name_required: '姓名为必填项',
|
||||
com_auth_name_min_length: '姓名至少3个字符',
|
||||
|
|
@ -190,10 +183,8 @@ export default {
|
|||
com_auth_here: '这里',
|
||||
com_auth_to_reset_your_password: '重置密码。',
|
||||
com_auth_reset_password_link_sent: '重置密码链接已发送至邮箱',
|
||||
com_auth_reset_password_email_sent:
|
||||
'重置密码邮件已发送至邮箱',
|
||||
com_auth_error_reset_password:
|
||||
'重置密码出现错误,未找到对应的邮箱地址,请重新输入。',
|
||||
com_auth_reset_password_email_sent: '重置密码邮件已发送至邮箱',
|
||||
com_auth_error_reset_password: '重置密码出现错误,未找到对应的邮箱地址,请重新输入。',
|
||||
com_auth_reset_password_success: '密码重置成功',
|
||||
com_auth_login_with_new_password: '现在你可以使用你的新密码登录。',
|
||||
com_auth_error_invalid_reset_token: '重置密码的密钥已失效。',
|
||||
|
|
@ -247,8 +238,7 @@ export default {
|
|||
com_endpoint_max_output_tokens: '最大输出词元数',
|
||||
com_endpoint_openai_temp:
|
||||
'值越高表示输出越随机,值越低表示输出越确定。建议不要同时改变此值和Top P。',
|
||||
com_endpoint_openai_max:
|
||||
'最大生成词元数。输入词元长度由模型的上下文长度决定。',
|
||||
com_endpoint_openai_max: '最大生成词元数。输入词元长度由模型的上下文长度决定。',
|
||||
com_endpoint_openai_topp:
|
||||
'相较于随机性的另一个取样方法,称为核采样,模型选取输出词元中大于P值(概率密度在整个概率分布中的比例)的结果。比如 top_p=0.1 表示只有概率占比为前10%的词元才会被考虑作为输出。建议不要同时改变此值和随机性。',
|
||||
com_endpoint_openai_freq:
|
||||
|
|
@ -262,8 +252,7 @@ export default {
|
|||
com_endpoint_openai_detail:
|
||||
'发送给Vision的图像分辨率。 “Low”更便宜且更快,“High”更详细但更昂贵,“Auto”将基于图像分辨率自动在两者之间进行选择。',
|
||||
com_endpoint_openai_custom_name_placeholder: '为ChatGPT设置一个名称',
|
||||
com_endpoint_openai_prompt_prefix_placeholder:
|
||||
'在消息开头添加系统级提示词,默认为空',
|
||||
com_endpoint_openai_prompt_prefix_placeholder: '在消息开头添加系统级提示词,默认为空',
|
||||
com_endpoint_anthropic_temp:
|
||||
'值介于0到1之间。 对于分析性/选择性任务,值应更接近0;对于创造性和生成性任务,值应更接近1。我们建议更改该参数或Top-p,但不要同时更改这两个参数。',
|
||||
com_endpoint_anthropic_topp:
|
||||
|
|
@ -316,8 +305,7 @@ export default {
|
|||
com_endpoint_use_active_assistant: '使用激活的助手',
|
||||
com_endpoint_assistant_model: '助手模型',
|
||||
com_endpoint_save_as_preset: '保存为预设',
|
||||
com_endpoint_presets_clear_warning:
|
||||
'确定要清除所有预设吗?此操作不可逆。',
|
||||
com_endpoint_presets_clear_warning: '确定要清除所有预设吗?此操作不可逆。',
|
||||
com_endpoint_not_implemented: '未实现功能',
|
||||
com_endpoint_no_presets: '暂无预设,使用设置按钮创建一个。',
|
||||
com_endpoint_not_available: '无可用渠道',
|
||||
|
|
@ -327,8 +315,7 @@ export default {
|
|||
com_endpoint_agent_model: '代理模型 (推荐: GPT-3.5)',
|
||||
com_endpoint_completion_model: '补全模型 (推荐: GPT-4)',
|
||||
com_endpoint_func_hover: '将插件作为OpenAI函数使用',
|
||||
com_endpoint_skip_hover:
|
||||
'跳过补全步骤, 检查最终答案和生成步骤',
|
||||
com_endpoint_skip_hover: '跳过补全步骤, 检查最终答案和生成步骤',
|
||||
com_endpoint_config_key: '设置API Key',
|
||||
com_endpoint_assistant_placeholder: '请从右侧面板中选择助手',
|
||||
com_endpoint_config_placeholder: '在顶部菜单设置API KEY',
|
||||
|
|
@ -346,8 +333,7 @@ export default {
|
|||
com_endpoint_config_google_api_info: '获取您的生成式语言API密钥(Gemini),',
|
||||
com_endpoint_config_key_import_json_key: '导入服务账号JSON密钥',
|
||||
com_endpoint_config_key_import_json_key_success: '成功导入服务账号JSON密钥',
|
||||
com_endpoint_config_key_import_json_key_invalid:
|
||||
'无效的服务账号JSON密钥,您是否导入正确的文件?',
|
||||
com_endpoint_config_key_import_json_key_invalid: '无效的服务账号JSON密钥,您是否导入正确的文件?',
|
||||
com_endpoint_config_key_get_edge_key: '为获得Bing访问凭证(Access token),请登录:',
|
||||
com_endpoint_config_key_get_edge_key_dev_tool:
|
||||
'登录网站后,使用开发工具或扩展程序复制 _U cookie 的内容。如果失败,请按照以下步骤操作:',
|
||||
|
|
@ -383,8 +369,7 @@ export default {
|
|||
com_show_examples: '显示样例',
|
||||
com_nav_plugin_search: '搜索插件',
|
||||
com_nav_tool_search: '搜索工具',
|
||||
com_nav_plugin_auth_error:
|
||||
'尝试验证此插件时出错。请重试。',
|
||||
com_nav_plugin_auth_error: '尝试验证此插件时出错。请重试。',
|
||||
com_nav_export_filename: '文件名',
|
||||
com_nav_export_filename_placeholder: '设置文件名',
|
||||
com_nav_export_type: '类型',
|
||||
|
|
@ -410,8 +395,7 @@ export default {
|
|||
com_nav_log_out: '注销',
|
||||
com_nav_user: '默认用户',
|
||||
com_nav_clear_conversation: '清空对话',
|
||||
com_nav_clear_conversation_confirm_message:
|
||||
'请是否清空所有对话?该操作无法撤销',
|
||||
com_nav_clear_conversation_confirm_message: '请是否清空所有对话?该操作无法撤销',
|
||||
com_nav_help_faq: '帮助',
|
||||
com_nav_settings: '设置',
|
||||
com_nav_search_placeholder: '搜索对话及对话内容',
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ export default {
|
|||
com_ui_clear: '清除',
|
||||
com_ui_revoke: '撤銷',
|
||||
com_ui_revoke_info: '撤銷所有使用者提供的憑證。',
|
||||
com_ui_import_conversation: '導入',
|
||||
com_ui_import_conversation_info: '從JSON文件導入對話',
|
||||
com_ui_import_conversation_success: '對話導入成功',
|
||||
com_ui_import_conversation_error: '導入對話時發生錯誤',
|
||||
com_ui_confirm_action: '確認操作',
|
||||
com_ui_chats: '對話',
|
||||
com_ui_delete: '刪除',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue