diff --git a/api/app/clients/tools/util/fileSearch.js b/api/app/clients/tools/util/fileSearch.js index 23ba58bb5a0..c48adc2eb4a 100644 --- a/api/app/clients/tools/util/fileSearch.js +++ b/api/app/clients/tools/util/fileSearch.js @@ -112,7 +112,8 @@ const createFileSearchTool = async ({ req, files, entity_id }) => { relevanceScore, })), ) - .sort((a, b) => b.relevanceScore - a.relevanceScore); + .sort((a, b) => b.relevanceScore - a.relevanceScore) + .slice(0, 5); const formattedString = formattedResults .map( diff --git a/api/models/Agent.js b/api/models/Agent.js index 6fa00f56bcb..6ea203113c0 100644 --- a/api/models/Agent.js +++ b/api/models/Agent.js @@ -97,11 +97,22 @@ const updateAgent = async (searchParameter, updateData) => { const addAgentResourceFile = async ({ agent_id, tool_resource, file_id }) => { const searchParameter = { id: agent_id }; - // build the update to push or create the file ids set const fileIdsPath = `tool_resources.${tool_resource}.file_ids`; + + await Agent.updateOne( + { + id: agent_id, + [`${fileIdsPath}`]: { $exists: false }, + }, + { + $set: { + [`${fileIdsPath}`]: [], + }, + }, + ); + const updateData = { $addToSet: { [fileIdsPath]: file_id } }; - // return the updated agent or throw if no agent matches const updatedAgent = await updateAgent(searchParameter, updateData); if (updatedAgent) { return updatedAgent; @@ -290,6 +301,7 @@ const updateAgentProjects = async ({ user, agentId, projectIds, removeProjectIds }; module.exports = { + Agent, getAgent, loadAgent, createAgent, diff --git a/api/models/Agent.spec.js b/api/models/Agent.spec.js new file mode 100644 index 00000000000..769eda2bb7f --- /dev/null +++ b/api/models/Agent.spec.js @@ -0,0 +1,160 @@ +const mongoose = require('mongoose'); +const { v4: uuidv4 } = require('uuid'); +const { MongoMemoryServer } = require('mongodb-memory-server'); +const { Agent, addAgentResourceFile, removeAgentResourceFiles } = require('./Agent'); + +describe('Agent Resource File Operations', () => { + let mongoServer; + + beforeAll(async () => { + mongoServer = await MongoMemoryServer.create(); + const mongoUri = mongoServer.getUri(); + await mongoose.connect(mongoUri); + }); + + afterAll(async () => { + await mongoose.disconnect(); + await mongoServer.stop(); + }); + + beforeEach(async () => { + await Agent.deleteMany({}); + }); + + const createBasicAgent = async () => { + const agentId = `agent_${uuidv4()}`; + const agent = await Agent.create({ + id: agentId, + name: 'Test Agent', + provider: 'test', + model: 'test-model', + author: new mongoose.Types.ObjectId(), + }); + return agent; + }; + + test('should handle concurrent file additions', async () => { + const agent = await createBasicAgent(); + const fileIds = Array.from({ length: 10 }, () => uuidv4()); + + // Concurrent additions + const additionPromises = fileIds.map((fileId) => + addAgentResourceFile({ + agent_id: agent.id, + tool_resource: 'test_tool', + file_id: fileId, + }), + ); + + await Promise.all(additionPromises); + + const updatedAgent = await Agent.findOne({ id: agent.id }); + expect(updatedAgent.tool_resources.test_tool.file_ids).toBeDefined(); + expect(updatedAgent.tool_resources.test_tool.file_ids).toHaveLength(10); + expect(new Set(updatedAgent.tool_resources.test_tool.file_ids).size).toBe(10); + }); + + test('should handle concurrent additions and removals', async () => { + const agent = await createBasicAgent(); + const initialFileIds = Array.from({ length: 5 }, () => uuidv4()); + + await Promise.all( + initialFileIds.map((fileId) => + addAgentResourceFile({ + agent_id: agent.id, + tool_resource: 'test_tool', + file_id: fileId, + }), + ), + ); + + const newFileIds = Array.from({ length: 5 }, () => uuidv4()); + const operations = [ + ...newFileIds.map((fileId) => + addAgentResourceFile({ + agent_id: agent.id, + tool_resource: 'test_tool', + file_id: fileId, + }), + ), + ...initialFileIds.map((fileId) => + removeAgentResourceFiles({ + agent_id: agent.id, + files: [{ tool_resource: 'test_tool', file_id: fileId }], + }), + ), + ]; + + await Promise.all(operations); + + const updatedAgent = await Agent.findOne({ id: agent.id }); + expect(updatedAgent.tool_resources.test_tool.file_ids).toBeDefined(); + expect(updatedAgent.tool_resources.test_tool.file_ids).toHaveLength(5); + }); + + test('should initialize array when adding to non-existent tool resource', async () => { + const agent = await createBasicAgent(); + const fileId = uuidv4(); + + const updatedAgent = await addAgentResourceFile({ + agent_id: agent.id, + tool_resource: 'new_tool', + file_id: fileId, + }); + + expect(updatedAgent.tool_resources.new_tool.file_ids).toBeDefined(); + expect(updatedAgent.tool_resources.new_tool.file_ids).toHaveLength(1); + expect(updatedAgent.tool_resources.new_tool.file_ids[0]).toBe(fileId); + }); + + test('should handle rapid sequential modifications to same tool resource', async () => { + const agent = await createBasicAgent(); + const fileId = uuidv4(); + + for (let i = 0; i < 10; i++) { + await addAgentResourceFile({ + agent_id: agent.id, + tool_resource: 'test_tool', + file_id: `${fileId}_${i}`, + }); + + if (i % 2 === 0) { + await removeAgentResourceFiles({ + agent_id: agent.id, + files: [{ tool_resource: 'test_tool', file_id: `${fileId}_${i}` }], + }); + } + } + + const updatedAgent = await Agent.findOne({ id: agent.id }); + expect(updatedAgent.tool_resources.test_tool.file_ids).toBeDefined(); + expect(Array.isArray(updatedAgent.tool_resources.test_tool.file_ids)).toBe(true); + }); + + test('should handle multiple tool resources concurrently', async () => { + const agent = await createBasicAgent(); + const toolResources = ['tool1', 'tool2', 'tool3']; + const operations = []; + + toolResources.forEach((tool) => { + const fileIds = Array.from({ length: 5 }, () => uuidv4()); + fileIds.forEach((fileId) => { + operations.push( + addAgentResourceFile({ + agent_id: agent.id, + tool_resource: tool, + file_id: fileId, + }), + ); + }); + }); + + await Promise.all(operations); + + const updatedAgent = await Agent.findOne({ id: agent.id }); + toolResources.forEach((tool) => { + expect(updatedAgent.tool_resources[tool].file_ids).toBeDefined(); + expect(updatedAgent.tool_resources[tool].file_ids).toHaveLength(5); + }); + }); +}); diff --git a/api/server/services/Files/Code/crud.js b/api/server/services/Files/Code/crud.js index 076a4d9f13b..7b26093d62d 100644 --- a/api/server/services/Files/Code/crud.js +++ b/api/server/services/Files/Code/crud.js @@ -2,6 +2,7 @@ const axios = require('axios'); const FormData = require('form-data'); const { getCodeBaseURL } = require('@librechat/agents'); +const { logAxiosError } = require('~/utils'); const MAX_FILE_SIZE = 150 * 1024 * 1024; @@ -78,7 +79,11 @@ async function uploadCodeEnvFile({ req, stream, filename, apiKey, entity_id = '' return `${fileIdentifier}?entity_id=${entity_id}`; } catch (error) { - throw new Error(`Error uploading file: ${error.message}`); + logAxiosError({ + message: `Error uploading code environment file: ${error.message}`, + error, + }); + throw new Error(`Error uploading code environment file: ${error.message}`); } } diff --git a/api/server/services/Files/Code/process.js b/api/server/services/Files/Code/process.js index 2a941a46472..ce8acf4ad31 100644 --- a/api/server/services/Files/Code/process.js +++ b/api/server/services/Files/Code/process.js @@ -12,6 +12,7 @@ const { const { getStrategyFunctions } = require('~/server/services/Files/strategies'); const { convertImage } = require('~/server/services/Files/images/convert'); const { createFile, getFiles, updateFile } = require('~/models/File'); +const { logAxiosError } = require('~/utils'); const { logger } = require('~/config'); /** @@ -85,7 +86,10 @@ const processCodeOutput = async ({ /** Note: `messageId` & `toolCallId` are not part of file DB schema; message object records associated file ID */ return Object.assign(file, { messageId, toolCallId }); } catch (error) { - logger.error('Error downloading file:', error); + logAxiosError({ + message: 'Error downloading code environment file', + error, + }); } }; @@ -135,7 +139,10 @@ async function getSessionInfo(fileIdentifier, apiKey) { return response.data.find((file) => file.name.startsWith(path))?.lastModified; } catch (error) { - logger.error(`Error fetching session info: ${error.message}`, error); + logAxiosError({ + message: `Error fetching session info: ${error.message}`, + error, + }); return null; } } diff --git a/api/server/services/Files/VectorDB/crud.js b/api/server/services/Files/VectorDB/crud.js index d290eea4b1b..37a1e814870 100644 --- a/api/server/services/Files/VectorDB/crud.js +++ b/api/server/services/Files/VectorDB/crud.js @@ -37,7 +37,14 @@ const deleteVectors = async (req, file) => { error, message: 'Error deleting vectors', }); - throw new Error(error.message || 'An error occurred during file deletion.'); + if ( + error.response && + error.response.status !== 404 && + (error.response.status < 200 || error.response.status >= 300) + ) { + logger.warn('Error deleting vectors, file will not be deleted'); + throw new Error(error.message || 'An error occurred during file deletion.'); + } } }; diff --git a/api/server/services/Files/process.js b/api/server/services/Files/process.js index a5d9c8c1e05..8744eb409b8 100644 --- a/api/server/services/Files/process.js +++ b/api/server/services/Files/process.js @@ -347,8 +347,8 @@ const uploadImageBuffer = async ({ req, context, metadata = {}, resize = true }) req.app.locals.imageOutputType }`; } - - const filepath = await saveBuffer({ userId: req.user.id, fileName: filename, buffer }); + const fileName = `${file_id}-${filename}`; + const filepath = await saveBuffer({ userId: req.user.id, fileName, buffer }); return await createFile( { user: req.user.id, @@ -801,8 +801,7 @@ async function saveBase64Image( { req, file_id: _file_id, filename: _filename, endpoint, context, resolution = 'high' }, ) { const file_id = _file_id ?? v4(); - - let filename = _filename; + let filename = `${file_id}-${_filename}`; const { buffer: inputBuffer, type } = base64ToBuffer(url); if (!path.extname(_filename)) { const extension = mime.getExtension(type); diff --git a/client/src/locales/ar/translation.json b/client/src/locales/ar/translation.json index f0f9f25ebde..cfee8924836 100644 --- a/client/src/locales/ar/translation.json +++ b/client/src/locales/ar/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "إنه عيد ميلادي الأول!", "com_ui_host": "مُضيف", "com_ui_image_gen": "توليد الصور", - "com_ui_import": "استيراد", "com_ui_import_conversation_error": "حدث خطأ أثناء استيراد محادثاتك", "com_ui_import_conversation_file_type_error": "نوع الملف غير مدعوم للاستيراد", "com_ui_import_conversation_info": "استيراد محادثات من ملف JSON", @@ -716,4 +715,4 @@ "com_ui_zoom": "تكبير", "com_user_message": "أنت", "com_warning_resubmit_unsupported": "إعادة إرسال رسالة الذكاء الاصطناعي غير مدعومة لنقطة النهاية هذه" -} +} \ No newline at end of file diff --git a/client/src/locales/de/translation.json b/client/src/locales/de/translation.json index 98cd14b8650..de986df0b01 100644 --- a/client/src/locales/de/translation.json +++ b/client/src/locales/de/translation.json @@ -614,7 +614,6 @@ "com_ui_hide_qr": "QR-Code ausblenden", "com_ui_host": "Host", "com_ui_image_gen": "Bildgenerierung", - "com_ui_import": "Importieren", "com_ui_import_conversation_error": "Beim Importieren Ihrer Konversationen ist ein Fehler aufgetreten", "com_ui_import_conversation_file_type_error": "Nicht unterstützter Importtyp", "com_ui_import_conversation_info": "Konversationen aus einer JSON-Datei importieren", @@ -764,4 +763,4 @@ "com_ui_zoom": "Zoom", "com_user_message": "Du", "com_warning_resubmit_unsupported": "Das erneute Senden der KI-Nachricht wird für diesen Endpunkt nicht unterstützt." -} +} \ No newline at end of file diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json index 63272a54f44..caa14969690 100644 --- a/client/src/locales/en/translation.json +++ b/client/src/locales/en/translation.json @@ -1,6 +1,6 @@ { - "chat_direction_left_to_right": "Chat direction is now left to right", - "chat_direction_right_to_left": "Chat direction is now right to left", + "chat_direction_left_to_right": "something needs to go here. was empty", + "chat_direction_right_to_left": "something needs to go here. was empty", "com_a11y_ai_composing": "The AI is still composing.", "com_a11y_end": "The AI has finished their reply.", "com_a11y_start": "The AI has started their reply.", @@ -124,9 +124,11 @@ "com_auth_submit_registration": "Submit registration", "com_auth_to_reset_your_password": "to reset your password.", "com_auth_to_try_again": "to try again.", + "com_auth_two_factor": "Check your preferred one-time password application for a code", "com_auth_username": "Username (optional)", "com_auth_username_max_length": "Username must be less than 20 characters", "com_auth_username_min_length": "Username must be at least 2 characters", + "com_auth_verify_your_identity": "Verify Your Identity", "com_auth_welcome_back": "Welcome back", "com_click_to_download": "(click here to download)", "com_download_expired": "(download expired)", @@ -263,9 +265,10 @@ "com_files_filter": "Filter files...", "com_files_no_results": "No results.", "com_files_number_selected": "{{0}} of {{1}} items(s) selected", - "com_files_table": "Files Table", + "com_files_table": "something needs to go here. was empty", "com_generated_files": "Generated files:", "com_hide_examples": "Hide Examples", + "com_nav_2fa": "Two-Factor Authentication (2FA)", "com_nav_account_settings": "Account Settings", "com_nav_always_make_prod": "Always make new versions production", "com_nav_archive_created_at": "Date Archived", @@ -435,9 +438,16 @@ "com_sidepanel_parameters": "Parameters", "com_sidepanel_select_agent": "Select an Agent", "com_sidepanel_select_assistant": "Select an Assistant", - "com_nav_2fa": "Two-Factor Authentication (2FA)", - "com_auth_verify_your_identity": "Verify Your Identity", - "com_auth_two_factor": "Check your preferred one-time password application for a code", + "com_ui_2fa_account_security": "Two-factor authentication adds an extra layer of security to your account", + "com_ui_2fa_disable": "Disable 2FA", + "com_ui_2fa_disable_error": "There was an error disabling two-factor authentication", + "com_ui_2fa_disabled": "2FA has been disabled", + "com_ui_2fa_enable": "Enable 2FA", + "com_ui_2fa_enabled": "2FA has been enabled", + "com_ui_2fa_generate_error": "There was an error generating two-factor authentication settings", + "com_ui_2fa_invalid": "Invalid two-factor authentication code", + "com_ui_2fa_setup": "Setup 2FA", + "com_ui_2fa_verified": "Successfully verified Two-Factor Authentication", "com_ui_accept": "I accept", "com_ui_add": "Add", "com_ui_add_model_preset": "Add a model or preset for an additional response", @@ -488,6 +498,9 @@ "com_ui_azure": "Azure", "com_ui_back_to_chat": "Back to Chat", "com_ui_back_to_prompts": "Back to Prompts", + "com_ui_backup_codes": "Backup Codes", + "com_ui_backup_codes_regenerate_error": "There was an error regenerating backup codes", + "com_ui_backup_codes_regenerated": "Backup codes have been regenerated successfully", "com_ui_basic": "Basic", "com_ui_basic_auth_header": "Basic authorization header", "com_ui_bearer": "Bearer", @@ -524,6 +537,7 @@ "com_ui_collapse_chat": "Collapse Chat", "com_ui_command_placeholder": "Optional: Enter a command for the prompt or name will be used", "com_ui_command_usage_placeholder": "Select a Prompt by command or name", + "com_ui_complete_setup": "Complete Setup", "com_ui_confirm_action": "Confirm Action", "com_ui_confirm_admin_use_change": "Changing this setting will block access for admins, including yourself. Are you sure you want to proceed?", "com_ui_confirm_change": "Confirm Change", @@ -577,8 +591,11 @@ "com_ui_descending": "Desc", "com_ui_description": "Description", "com_ui_description_placeholder": "Optional: Enter a description to display for the prompt", + "com_ui_disabling": "Disabling...", "com_ui_download": "Download", "com_ui_download_artifact": "Download Artifact", + "com_ui_download_backup": "Download Backup Codes", + "com_ui_download_backup_tooltip": "Before you continue, download your backup codes. You will need them to regain access if you lose your authenticator device", "com_ui_download_error": "Error downloading file. The file may have been deleted.", "com_ui_drag_drop": "something needs to go here. was empty", "com_ui_dropdown_variables": "Dropdown variables:", @@ -627,7 +644,10 @@ "com_ui_fork_split_target_setting": "Start fork from target message by default", "com_ui_fork_success": "Successfully forked conversation", "com_ui_fork_visible": "Visible messages only", - "com_ui_global_group": "Global Group", + "com_ui_generate_backup": "Generate Backup Codes", + "com_ui_generate_qrcode": "Generate QR Code", + "com_ui_generating": "Generating...", + "com_ui_global_group": "something needs to go here. was empty", "com_ui_go_back": "Go back", "com_ui_go_to_conversation": "Go to conversation", "com_ui_happy_birthday": "It's my 1st birthday!", @@ -668,14 +688,16 @@ "com_ui_new_chat": "New chat", "com_ui_next": "Next", "com_ui_no": "No", + "com_ui_no_backup_codes": "No backup codes available. Please generate new ones", "com_ui_no_bookmarks": "it seems like you have no bookmarks yet. Click on a chat and add a new one", "com_ui_no_category": "No category", "com_ui_no_changes": "No changes to update", - "com_ui_no_data": "No data", + "com_ui_no_data": "something needs to go here. was empty", "com_ui_no_terms_content": "No terms and conditions content to display", - "com_ui_no_valid_items": "No valid items", + "com_ui_no_valid_items": "something needs to go here. was empty", "com_ui_none": "None", "com_ui_none_selected": "None selected", + "com_ui_not_used": "Not Used", "com_ui_nothing_found": "Nothing found", "com_ui_oauth": "OAuth", "com_ui_of": "of", @@ -703,6 +725,8 @@ "com_ui_read_aloud": "Read aloud", "com_ui_refresh_link": "Refresh link", "com_ui_regenerate": "Regenerate", + "com_ui_regenerate_backup": "Regenerate Backup Codes", + "com_ui_regenerating": "Regenerating...", "com_ui_region": "Region", "com_ui_rename": "Rename", "com_ui_rename_prompt": "Rename Prompt", @@ -725,6 +749,7 @@ "com_ui_schema": "Schema", "com_ui_scope": "Scope", "com_ui_search": "Search", + "com_ui_secret_key": "Secret Key", "com_ui_select": "Select", "com_ui_select_file": "Select a file", "com_ui_select_model": "Select a model", @@ -749,6 +774,7 @@ "com_ui_shared_link_not_found": "Shared link not found", "com_ui_shared_prompts": "Shared Prompts", "com_ui_shop": "Shopping", + "com_ui_show": "Show", "com_ui_show_all": "Show All", "com_ui_show_qr": "Show QR Code", "com_ui_sign_in_to_domain": "Sign-in to {{0}}", @@ -786,46 +812,20 @@ "com_ui_upload_invalid_var": "Invalid file for upload. Must be an image not exceeding {{0}} MB", "com_ui_upload_success": "Successfully uploaded file", "com_ui_upload_type": "Select Upload Type", + "com_ui_use_2fa_code": "Use 2FA Code Instead", + "com_ui_use_backup_code": "Use Backup Code Instead", "com_ui_use_micrphone": "Use microphone", "com_ui_use_prompt": "Use prompt", + "com_ui_used": "Used", "com_ui_variables": "Variables", "com_ui_variables_info": "Use double braces in your text to create variables, e.g. `{{example variable}}`, to later fill when using the prompt.", + "com_ui_verify": "Verify", "com_ui_version_var": "Version {{0}}", "com_ui_versions": "Versions", "com_ui_view_source": "View source chat", "com_ui_write": "Writing", "com_ui_yes": "Yes", "com_ui_zoom": "Zoom", - "com_ui_secret_key": "Secret Key", - "com_ui_2fa_account_security": "Two-factor authentication adds an extra layer of security to your account", - "com_ui_2fa_generate_error": "There was an error generating two-factor authentication settings", - "com_ui_backup_codes": "Backup Codes", - "com_ui_2fa_invalid": "Invalid two-factor authentication code", - "com_ui_2fa_setup": "Setup 2FA", - "com_ui_2fa_enable": "Enable 2FA", - "com_ui_2fa_disable": "Disable 2FA", - "com_ui_disabling": "Disabling...", - "com_ui_2fa_enabled": "2FA has been enabled", - "com_ui_2fa_disabled": "2FA has been disabled", - "com_ui_download_backup": "Download Backup Codes", - "com_ui_use_backup_code": "Use Backup Code Instead", - "com_ui_use_2fa_code": "Use 2FA Code Instead", - "com_ui_verify": "Verify", - "com_ui_2fa_disable_error": "There was an error disabling two-factor authentication", - "com_ui_2fa_verified": "Successfully verified Two-Factor Authentication", - "com_ui_generate_backup": "Generate Backup Codes", - "com_ui_regenerate_backup": "Regenerate Backup Codes", - "com_ui_regenerating": "Regenerating...", - "com_ui_used": "Used", - "com_ui_not_used": "Not Used", - "com_ui_backup_codes_regenerated": "Backup codes have been regenerated successfully", - "com_ui_backup_codes_regenerate_error": "There was an error regenerating backup codes", - "com_ui_no_backup_codes": "No backup codes available. Please generate new ones", - "com_ui_generating": "Generating...", - "com_ui_generate_qrcode": "Generate QR Code", - "com_ui_complete_setup": "Complete Setup", - "com_ui_download_backup_tooltip": "Before you continue, download your backup codes. You will need them to regain access if you lose your authenticator device", - "com_ui_show": "Show", "com_user_message": "You", "com_warning_resubmit_unsupported": "Resubmitting the AI message is not supported for this endpoint." -} +} \ No newline at end of file diff --git a/client/src/locales/es/translation.json b/client/src/locales/es/translation.json index 3355d79df4c..fb1e0220d3c 100644 --- a/client/src/locales/es/translation.json +++ b/client/src/locales/es/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "¡Es mi primer cumpleaños!", "com_ui_host": "Host", "com_ui_image_gen": "Gen Imágenes", - "com_ui_import": "Importar", "com_ui_import_conversation_error": "Hubo un error al importar tus chats", "com_ui_import_conversation_file_type_error": "com_ui_import_conversation_file_type_error: Tipo de archivo no compatible para importar", "com_ui_import_conversation_info": "Importar chats de un archivo JSON", @@ -716,4 +715,4 @@ "com_ui_zoom": "Zoom", "com_user_message": "Usted", "com_warning_resubmit_unsupported": "No se admite el reenvío del mensaje de IA para este punto de conexión." -} +} \ No newline at end of file diff --git a/client/src/locales/et/translation.json b/client/src/locales/et/translation.json index 84d40e80f67..6eec2e89563 100644 --- a/client/src/locales/et/translation.json +++ b/client/src/locales/et/translation.json @@ -184,7 +184,6 @@ "com_endpoint_google_temp": "Kõrgemad väärtused = juhuslikum, samas kui madalamad väärtused = keskendunum ja deterministlikum. Soovitame muuta kas seda või Top P-d, aga mitte mõlemat.", "com_endpoint_google_topk": "Top-k muudab seda, kuidas mudel valib väljundi jaoks märgid. Top-k väärtus 1 tähendab, et valitud märk on kõige tõenäolisem kõigi mudeli sõnavaras olevate märkide seas (nimetatakse ka ahneks dekodeerimiseks), samas kui top-k väärtus 3 tähendab, et järgmine märk valitakse 3 kõige tõenäolisema märgi seast (kasutades temperatuuri).", "com_endpoint_google_topp": "Top-p muudab seda, kuidas mudel valib väljundi jaoks märgid. Märgid valitakse kõige tõenäolisemast K (vt parameetrit topK) kuni vähim tõenäoliseni, kuni nende tõenäosuste summa on võrdne top-p väärtusega.", - "com_endpoint_import": "Impordi", "com_endpoint_instructions_assistants": "Tühista juhised", "com_endpoint_instructions_assistants_placeholder": "Tühistab assistendi juhised. See on kasulik käitumise muutmiseks käivituse kohta.", "com_endpoint_max_output_tokens": "Maksimaalsed väljundmärgid", @@ -272,7 +271,6 @@ "com_nav_archive_name": "Nimi", "com_nav_archived_chats": "Arhiveeritud vestlused", "com_nav_archived_chats_empty": "Sul ei ole arhiveeritud vestlusi.", - "com_nav_archived_chats_manage": "Halda", "com_nav_at_command": "@-käsk", "com_nav_at_command_description": "Lülita käsk \"@\" sisse/välja lõpp-punktide, mudelite, eelseadistuste jms vahetamiseks.", "com_nav_audio_play_error": "Viga heli esitamisel: {{0}}", @@ -630,7 +628,6 @@ "com_ui_hide_qr": "Peida QR-kood", "com_ui_host": "Host", "com_ui_image_gen": "Pildi genereerimine", - "com_ui_import_conversation": "Impordi", "com_ui_import_conversation_error": "Vestluste importimisel tekkis viga", "com_ui_import_conversation_file_type_error": "Toetamatu imporditüüp", "com_ui_import_conversation_info": "Impordi vestlused JSON-failist", @@ -786,4 +783,4 @@ "com_ui_zoom": "Suumi", "com_user_message": "Sina", "com_warning_resubmit_unsupported": "AI sõnumi uuesti esitamine pole selle otspunkti jaoks toetatud." -} +} \ No newline at end of file diff --git a/client/src/locales/fi/translation.json b/client/src/locales/fi/translation.json index 190d3440265..270672475be 100644 --- a/client/src/locales/fi/translation.json +++ b/client/src/locales/fi/translation.json @@ -458,7 +458,6 @@ "com_ui_happy_birthday": "On 1. syntymäpäiväni!", "com_ui_host": "Host", "com_ui_image_gen": "Kuvanluonti", - "com_ui_import": "Tuo", "com_ui_import_conversation_error": "Keskustelujesi tuonnissa tapahtui virhe", "com_ui_import_conversation_file_type_error": "Tiedostotyyppi ei ole tuettu tuonnissa", "com_ui_import_conversation_info": "Tuo keskusteluja JSON-tiedostosta", @@ -551,4 +550,4 @@ "com_ui_versions": "Versiot", "com_ui_yes": "Kyllä", "com_user_message": "Sinä" -} +} \ No newline at end of file diff --git a/client/src/locales/fr/translation.json b/client/src/locales/fr/translation.json index b1bd434c9d7..b06cb11e50e 100644 --- a/client/src/locales/fr/translation.json +++ b/client/src/locales/fr/translation.json @@ -599,7 +599,6 @@ "com_ui_hide_qr": "Cacher le code QR", "com_ui_host": "Hôte", "com_ui_image_gen": "Génération d'image", - "com_ui_import": "Importer", "com_ui_import_conversation_error": "Une erreur s'est produite lors de l'importation de vos conversations", "com_ui_import_conversation_file_type_error": "Type de fichier non pris en charge pour l'importation", "com_ui_import_conversation_info": "Importer des conversations à partir d'un fichier JSON", @@ -733,4 +732,4 @@ "com_ui_zoom": "Zoom", "com_user_message": "Vous", "com_warning_resubmit_unsupported": "La resoumission du message IA n'est pas prise en charge pour ce point de terminaison." -} +} \ No newline at end of file diff --git a/client/src/locales/he/translation.json b/client/src/locales/he/translation.json index 456d3d33e05..4f8afc7b1d6 100644 --- a/client/src/locales/he/translation.json +++ b/client/src/locales/he/translation.json @@ -291,7 +291,6 @@ "com_ui_error": "שגיאה", "com_ui_examples": "דוגמאות", "com_ui_happy_birthday": "זה יום ההולדת הראשון שלי!", - "com_ui_import": "יבוא", "com_ui_import_conversation_error": "אירעה שגיאה בעת ייבוא השיחות שלך", "com_ui_import_conversation_info": "ייבא שיחות מקובץ JSON", "com_ui_import_conversation_success": "השיחות יובאו בהצלחה", @@ -331,4 +330,4 @@ "com_ui_upload_success": "קובץ שהועלה בהצלחה", "com_ui_use_prompt": "השתמש בהודעת", "com_user_message": "אתה" -} +} \ No newline at end of file diff --git a/client/src/locales/id/translation.json b/client/src/locales/id/translation.json index b6d7d572372..7caba4d0ae5 100644 --- a/client/src/locales/id/translation.json +++ b/client/src/locales/id/translation.json @@ -247,7 +247,6 @@ "com_ui_enter": "Masuk", "com_ui_examples": "Contoh", "com_ui_happy_birthday": "Ini ulang tahun pertamaku!", - "com_ui_import": "Impor", "com_ui_import_conversation_error": "Terjadi kesalahan saat mengimpor percakapan Anda", "com_ui_import_conversation_info": "Impor percakapan dari file JSON", "com_ui_import_conversation_success": "Percakapan berhasil diimpor", @@ -284,4 +283,4 @@ "com_ui_upload_success": "Berhasil mengunggah file", "com_ui_use_prompt": "Gunakan petunjuk", "com_user_message": "Kamu" -} +} \ No newline at end of file diff --git a/client/src/locales/it/translation.json b/client/src/locales/it/translation.json index d64fca28e55..062209cce9a 100644 --- a/client/src/locales/it/translation.json +++ b/client/src/locales/it/translation.json @@ -600,7 +600,6 @@ "com_ui_hide_qr": "Nascondi codice QR", "com_ui_host": "Host", "com_ui_image_gen": "Generazione immagine", - "com_ui_import": "Importa", "com_ui_import_conversation_error": "Si è verificato un errore durante l'importazione delle conversazioni", "com_ui_import_conversation_file_type_error": "Tipo di importazione non supportato", "com_ui_import_conversation_info": "Importa conversazioni da un file JSON", @@ -744,4 +743,4 @@ "com_ui_zoom": "Zoom", "com_user_message": "Mostra nome utente nei messaggi", "com_warning_resubmit_unsupported": "Il reinvio del messaggio AI non è supportato per questo endpoint." -} +} \ No newline at end of file diff --git a/client/src/locales/ja/translation.json b/client/src/locales/ja/translation.json index 965ca5699d5..a63fc802548 100644 --- a/client/src/locales/ja/translation.json +++ b/client/src/locales/ja/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "初めての誕生日です!", "com_ui_host": "ホスト", "com_ui_image_gen": "画像生成", - "com_ui_import": "インポート", "com_ui_import_conversation_error": "会話のインポート時にエラーが発生しました", "com_ui_import_conversation_file_type_error": "サポートされていないインポート形式です", "com_ui_import_conversation_info": "JSONファイルから会話をインポートする", @@ -716,4 +715,4 @@ "com_ui_zoom": "ズーム", "com_user_message": "あなた", "com_warning_resubmit_unsupported": "このエンドポイントではAIメッセージの再送信はサポートされていません" -} +} \ No newline at end of file diff --git a/client/src/locales/ko/translation.json b/client/src/locales/ko/translation.json index 46eda9f9dec..0bfb21452e4 100644 --- a/client/src/locales/ko/translation.json +++ b/client/src/locales/ko/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "내 첫 생일이야!", "com_ui_host": "호스트", "com_ui_image_gen": "이미지 생성", - "com_ui_import": "가져오기", "com_ui_import_conversation_error": "대화를 가져오는 동안 오류가 발생했습니다", "com_ui_import_conversation_file_type_error": "가져올 수 없는 파일 형식입니다", "com_ui_import_conversation_info": "JSON 파일에서 대화 가져오기", @@ -716,4 +715,4 @@ "com_ui_zoom": "확대/축소", "com_user_message": "당신", "com_warning_resubmit_unsupported": "이 엔드포인트에서는 AI 메시지 재전송이 지원되지 않습니다" -} +} \ No newline at end of file diff --git a/client/src/locales/nl/translation.json b/client/src/locales/nl/translation.json index f6c99423fb4..35fec8640e3 100644 --- a/client/src/locales/nl/translation.json +++ b/client/src/locales/nl/translation.json @@ -219,7 +219,6 @@ "com_ui_enter": "Invoeren", "com_ui_examples": "Voorbeelden", "com_ui_happy_birthday": "Het is mijn eerste verjaardag!", - "com_ui_import": "Importeren", "com_ui_import_conversation_error": "Er is een fout opgetreden bij het importeren van je gesprekken", "com_ui_import_conversation_info": "Gesprekken importeren vanuit een JSON-bestand", "com_ui_import_conversation_success": "Gesprekken succesvol geïmporteerd", @@ -250,4 +249,4 @@ "com_ui_unarchive_error": "Kan conversatie niet uit archiveren", "com_ui_upload_success": "Bestand succesvol geüpload", "com_ui_use_prompt": "Gebruik prompt" -} +} \ No newline at end of file diff --git a/client/src/locales/pl/translation.json b/client/src/locales/pl/translation.json index 30483ba8b3d..24fd96a70cf 100644 --- a/client/src/locales/pl/translation.json +++ b/client/src/locales/pl/translation.json @@ -562,7 +562,6 @@ "com_ui_hide_qr": "Ukryj kod QR", "com_ui_host": "Host", "com_ui_image_gen": "Generowanie obrazu", - "com_ui_import": "Importuj", "com_ui_import_conversation_error": "Wystąpił błąd podczas importowania konwersacji", "com_ui_import_conversation_file_type_error": "Nieobsługiwany typ importu", "com_ui_import_conversation_info": "Importuj konwersacje z pliku JSON", @@ -704,4 +703,4 @@ "com_ui_zoom": "Powiększ", "com_user_message": "Ty", "com_warning_resubmit_unsupported": "Ponowne przesyłanie wiadomości AI nie jest obsługiwane dla tego punktu końcowego." -} +} \ No newline at end of file diff --git a/client/src/locales/pt-BR/translation.json b/client/src/locales/pt-BR/translation.json index 06a22184c56..a1e37608ffe 100644 --- a/client/src/locales/pt-BR/translation.json +++ b/client/src/locales/pt-BR/translation.json @@ -163,7 +163,6 @@ "com_endpoint_google_temp": "Valores mais altos = mais aleatório, enquanto valores mais baixos = mais focado e determinístico. Recomendamos alterar isso ou Top P, mas não ambos.", "com_endpoint_google_topk": "Top-k altera como o modelo seleciona tokens para saída. Um top-k de 1 significa que o token selecionado é o mais provável entre todos os tokens no vocabulário do modelo (também chamado de decodificação gananciosa), enquanto um top-k de 3 significa que o próximo token é selecionado entre os 3 tokens mais prováveis (usando temperatura).", "com_endpoint_google_topp": "Top-p altera como o modelo seleciona tokens para saída. Os tokens são selecionados dos mais prováveis (veja o parâmetro topK) até os menos prováveis até que a soma de suas probabilidades atinja o valor top-p.", - "com_endpoint_import": "Importar", "com_endpoint_instructions_assistants": "Substituir Instruções", "com_endpoint_instructions_assistants_placeholder": "Substitui as instruções do assistente. Isso é útil para modificar o comportamento em uma base por execução.", "com_endpoint_max_output_tokens": "Máximo de Tokens de Saída", @@ -237,7 +236,6 @@ "com_nav_archive_name": "Nome", "com_nav_archived_chats": "Chats Arquivados", "com_nav_archived_chats_empty": "Você não tem conversas arquivadas.", - "com_nav_archived_chats_manage": "Gerenciar", "com_nav_at_command": "Comando @", "com_nav_at_command_description": "Alternar comando \"@\" para alternar endpoints, modelos, predefinições, etc.", "com_nav_audio_play_error": "Erro ao reproduzir áudio: {{0}}", @@ -353,7 +351,6 @@ "com_nav_setting_speech": "Fala", "com_nav_settings": "Configurações", "com_nav_shared_links": "Links compartilhados", - "com_nav_shared_links_manage": "Gerenciar", "com_nav_show_code": "Sempre mostrar código ao usar o interpretador de código", "com_nav_slash_command": "Comando /", "com_nav_slash_command_description": "Alternar comando \"/\" para selecionar um prompt via teclado", @@ -530,7 +527,6 @@ "com_ui_happy_birthday": "É meu 1º aniversário!", "com_ui_host": "Host", "com_ui_image_gen": "Geração de Imagem", - "com_ui_import_conversation": "Importar", "com_ui_import_conversation_error": "Houve um erro ao importar suas conversas", "com_ui_import_conversation_file_type_error": "Tipo de importação não suportado", "com_ui_import_conversation_info": "Importar conversas de um arquivo JSON", diff --git a/client/src/locales/pt-PT/translation.json b/client/src/locales/pt-PT/translation.json index c687f7b2e0a..730ce2ac2f6 100644 --- a/client/src/locales/pt-PT/translation.json +++ b/client/src/locales/pt-PT/translation.json @@ -182,7 +182,6 @@ "com_endpoint_google_temp": "Valores mais altos = mais aleatório, enquanto valores mais baixos = mais focado e determinístico. Recomendamos alterar isso ou Top P, mas não ambos.", "com_endpoint_google_topk": "Top-k altera como o modelo seleciona tokens para saída. Um top-k de 1 significa que o token selecionado é o mais provável entre todos os tokens no vocabulário do modelo (também chamado de decodificação gananciosa), enquanto um top-k de 3 significa que o próximo token é selecionado entre os 3 tokens mais prováveis (usando temperatura).", "com_endpoint_google_topp": "Top-p altera como o modelo seleciona tokens para saída. Os tokens são selecionados dos mais prováveis (veja o parâmetro topK) até os menos prováveis até que a soma de suas probabilidades atinja o valor top-p.", - "com_endpoint_import": "Importar", "com_endpoint_instructions_assistants": "Substituir Instruções", "com_endpoint_instructions_assistants_placeholder": "Substitui as instruções do assistente. Isso é útil para modificar o comportamento em uma base por execução.", "com_endpoint_max_output_tokens": "Máximo de Tokens de Saída", @@ -268,7 +267,6 @@ "com_nav_archive_name": "Nome", "com_nav_archived_chats": "Chats Arquivados", "com_nav_archived_chats_empty": "Você não tem conversas arquivadas.", - "com_nav_archived_chats_manage": "Gerenciar", "com_nav_at_command": "Comando @", "com_nav_at_command_description": "Alternar comando \"@\" para alternar endpoints, modelos, predefinições, etc.", "com_nav_audio_play_error": "Erro ao reproduzir áudio: {{0}}", @@ -391,7 +389,6 @@ "com_nav_setting_speech": "Fala", "com_nav_settings": "Configurações", "com_nav_shared_links": "Links compartilhados", - "com_nav_shared_links_manage": "Gerenciar", "com_nav_show_code": "Sempre mostrar código ao usar o interpretador de código", "com_nav_show_thinking": "Abrir Dropdown de lógica por defeito.", "com_nav_slash_command": "Comando /", @@ -626,7 +623,6 @@ "com_ui_host": "Host", "com_ui_idea": "Ideias", "com_ui_image_gen": "Geração de Imagem", - "com_ui_import_conversation": "Importar", "com_ui_import_conversation_error": "Houve um erro ao importar suas conversas", "com_ui_import_conversation_file_type_error": "Tipo de importação não suportado", "com_ui_import_conversation_info": "Importar conversas de um arquivo JSON", diff --git a/client/src/locales/ru/translation.json b/client/src/locales/ru/translation.json index ee5e4d0e29a..76962c09b2c 100644 --- a/client/src/locales/ru/translation.json +++ b/client/src/locales/ru/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "Это мой первый день рождения!", "com_ui_host": "Хост", "com_ui_image_gen": "Генератор изображений", - "com_ui_import": "Импортировать", "com_ui_import_conversation_error": "При импорте бесед произошла ошибка", "com_ui_import_conversation_file_type_error": "Неподдерживаемый тип импорта", "com_ui_import_conversation_info": "Импортировать беседы из файла JSON", @@ -716,4 +715,4 @@ "com_ui_zoom": "Масштаб", "com_user_message": "Вы", "com_warning_resubmit_unsupported": "Повторная отправка сообщения ИИ не поддерживается для данной конечной точки" -} +} \ No newline at end of file diff --git a/client/src/locales/sv/translation.json b/client/src/locales/sv/translation.json index 26c8cc0c55b..4497ecc8579 100644 --- a/client/src/locales/sv/translation.json +++ b/client/src/locales/sv/translation.json @@ -206,7 +206,6 @@ "com_ui_enter": "Ange", "com_ui_examples": "Exempel", "com_ui_happy_birthday": "Det är min första födelsedag!", - "com_ui_import": "Importera", "com_ui_import_conversation_error": "Det uppstod ett fel vid import av dina konversationer", "com_ui_import_conversation_info": "Importera konversationer från en JSON-fil", "com_ui_import_conversation_success": "Konversationer har importerats framgångsrikt", @@ -236,4 +235,4 @@ "com_ui_unarchive_error": "Kunde inte avarkivera chatt", "com_ui_upload_success": "Uppladdningen av filen lyckades", "com_ui_use_prompt": "Använd prompt" -} +} \ No newline at end of file diff --git a/client/src/locales/tr/translation.json b/client/src/locales/tr/translation.json index a75a5422ea3..e4b7bd8ce5c 100644 --- a/client/src/locales/tr/translation.json +++ b/client/src/locales/tr/translation.json @@ -602,7 +602,6 @@ "com_ui_hide_qr": "QR Kodunu Gizle", "com_ui_host": "Host", "com_ui_image_gen": "Görüntü Oluştur", - "com_ui_import": "İçe Aktar", "com_ui_import_conversation_error": "Konuşmalarınızı içe aktarma sırasında bir hata oluştu", "com_ui_import_conversation_file_type_error": "Desteklenmeyen içe aktarma türü", "com_ui_import_conversation_info": "JSON dosyasından konuşmaları içe aktar", @@ -747,4 +746,4 @@ "com_ui_zoom": "Yakınlaştır", "com_user_message": "Sen", "com_warning_resubmit_unsupported": "Bu uç nokta için yapay zeka mesajını yeniden gönderme desteklenmiyor." -} +} \ No newline at end of file diff --git a/client/src/locales/vi/translation.json b/client/src/locales/vi/translation.json index 57f34eef0be..d4cff9b40e2 100644 --- a/client/src/locales/vi/translation.json +++ b/client/src/locales/vi/translation.json @@ -205,7 +205,6 @@ "com_ui_enter": "Nhập", "com_ui_examples": "Ví dụ", "com_ui_happy_birthday": "Đây là sinh nhật đầu tiên của tôi!", - "com_ui_import": "Nhập khẩu", "com_ui_import_conversation_error": "Đã xảy ra lỗi khi nhập khẩu cuộc trò chuyện của bạn", "com_ui_import_conversation_info": "Nhập khẩu cuộc trò chuyện từ một tệp JSON", "com_ui_import_conversation_success": "Đã nhập khẩu cuộc trò chuyện thành công", @@ -235,4 +234,4 @@ "com_ui_unarchive_error": "Không thể bỏ lưu trữ cuộc trò chuyện", "com_ui_upload_success": "Tải tệp thành công", "com_ui_use_prompt": "Sử dụng gợi ý" -} +} \ No newline at end of file diff --git a/client/src/locales/zh-Hans/translation.json b/client/src/locales/zh-Hans/translation.json index 6570bf1ae50..cca6ac9b8e3 100644 --- a/client/src/locales/zh-Hans/translation.json +++ b/client/src/locales/zh-Hans/translation.json @@ -182,7 +182,6 @@ "com_endpoint_google_temp": "值越高表示输出越随机,值越低表示输出越确定。建议不要同时改变此值和 Top-p。", "com_endpoint_google_topk": "top-k 会改变模型选择输出词的方式。top-k 为 1 意味着所选词是模型词汇中概率最大的(也称为贪心解码),而 top-k 为 3 意味着下一个词是从 3 个概率最大的词中选出的(使用随机性)。", "com_endpoint_google_topp": "top-p(核采样)会改变模型选择输出词的方式。从概率最大的 K(参见topK参数)向最小的 K 选择,直到它们的概率之和等于 top-p 值。", - "com_endpoint_import": "导入", "com_endpoint_instructions_assistants": "覆写指令", "com_endpoint_instructions_assistants_placeholder": "覆盖助手的指令。这对于需要逐次修改行为非常有用。", "com_endpoint_max_output_tokens": "最大输出词元数", @@ -267,7 +266,6 @@ "com_nav_archive_name": "名称", "com_nav_archived_chats": "归档的对话", "com_nav_archived_chats_empty": "您没有归档的对话。", - "com_nav_archived_chats_manage": "管理", "com_nav_at_command": "@-命令", "com_nav_at_command_description": "切换至命令 “@” 以更改端点、模型、预设等", "com_nav_audio_play_error": "播放音频时发生错误:{{0}}", @@ -390,7 +388,6 @@ "com_nav_setting_speech": "语音", "com_nav_settings": "设置", "com_nav_shared_links": "共享链接", - "com_nav_shared_links_manage": "管理", "com_nav_show_code": "使用代码解释器时始终显示代码", "com_nav_slash_command": "/-命令", "com_nav_slash_command_description": "切换至命令 “/” 以通过键盘选择提示词", @@ -611,7 +608,6 @@ "com_ui_hide_qr": "隐藏二维码", "com_ui_host": "主机", "com_ui_image_gen": "图片生成", - "com_ui_import_conversation": "导入", "com_ui_import_conversation_error": "导入对话时发生错误", "com_ui_import_conversation_file_type_error": "不支持的导入类型", "com_ui_import_conversation_info": "从 JSON 文件导入对话", diff --git a/client/src/locales/zh-Hant/translation.json b/client/src/locales/zh-Hant/translation.json index f46d94af2db..0aaf22594dd 100644 --- a/client/src/locales/zh-Hant/translation.json +++ b/client/src/locales/zh-Hant/translation.json @@ -584,7 +584,6 @@ "com_ui_happy_birthday": "這是我的第一個生日!", "com_ui_host": "主機", "com_ui_image_gen": "影像生成", - "com_ui_import": "匯入", "com_ui_import_conversation_error": "匯入對話時發生錯誤", "com_ui_import_conversation_file_type_error": "不支援的匯入檔案類型", "com_ui_import_conversation_info": "從 JSON 文件匯入對話", @@ -716,4 +715,4 @@ "com_ui_zoom": "縮放", "com_user_message": "您", "com_warning_resubmit_unsupported": "此端點不支援重新送出 AI 訊息。" -} +} \ No newline at end of file diff --git a/deploy-compose.yml b/deploy-compose.yml index 3f1e14ee54e..ae61265a050 100644 --- a/deploy-compose.yml +++ b/deploy-compose.yml @@ -1,4 +1,3 @@ -version: "3.8" services: api: # build: @@ -29,6 +28,7 @@ services: source: ./librechat.yaml target: /app/librechat.yaml - ./images:/app/client/public/images + - ./uploads:/app/uploads - ./logs:/app/api/logs client: diff --git a/docker-compose.yml b/docker-compose.yml index e863965342c..e16f93f4c04 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: source: ./.env target: /app/.env - ./images:/app/client/public/images + - ./uploads:/app/uploads - ./logs:/app/api/logs mongodb: container_name: chat-mongodb