🛠 refactor: Ensure File Deletions, File Naming, and Agent Resource Updates (#5928)

* refactor: Improve error logging for file upload and processing functions to prevent verbosity

* refactor: Add uploads directory to Docker Compose to persist file uploads

* refactor: `addAgentResourceFile` to handle edge case of non-existing `tool_resource` array

* refactor: Remove version specification from deploy-compose.yml

* refactor: Prefix filenames with file_id to ensure uniqueness in file uploads

* refactor: Enhance error handling in deleteVectors to log warnings for non-404 errors

* refactor: Limit file search results to top 5 based on relevance score

* 🌍 i18n: Update translation.json with latest translations

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Danny Avila 2025-02-17 19:37:03 -05:00 committed by GitHub
parent f0f09138bd
commit 964a74c73b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 262 additions and 102 deletions

View file

@ -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(

View file

@ -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,

160
api/models/Agent.spec.js Normal file
View file

@ -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);
});
});
});

View file

@ -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}`);
}
}

View file

@ -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;
}
}

View file

@ -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.');
}
}
};

View file

@ -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);

View file

@ -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",

View file

@ -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",

View file

@ -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."
}

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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": "השיחות יובאו בהצלחה",

View file

@ -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",

View file

@ -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",

View file

@ -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ファイルから会話をインポートする",

View file

@ -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 파일에서 대화 가져오기",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

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

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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 文件导入对话",

View file

@ -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 文件匯入對話",

View file

@ -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:

View file

@ -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