Merge branch 'main' into feat/user-groups

This commit is contained in:
Ruben Talstra 2025-02-22 10:08:12 +01:00 committed by GitHub
commit 0cdccb617c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1016 additions and 369 deletions

View file

@ -20,6 +20,11 @@ DOMAIN_CLIENT=http://localhost:3080
DOMAIN_SERVER=http://localhost:3080 DOMAIN_SERVER=http://localhost:3080
NO_INDEX=true NO_INDEX=true
# Use the address that is at most n number of hops away from the Express application.
# req.socket.remoteAddress is the first hop, and the rest are looked for in the X-Forwarded-For header from right to left.
# A value of 0 means that the first untrusted address would be req.socket.remoteAddress, i.e. there is no reverse proxy.
# Defaulted to 1.
TRUST_PROXY=1
#===============# #===============#
# JSON Logging # # JSON Logging #
@ -292,6 +297,10 @@ MEILI_NO_ANALYTICS=true
MEILI_HOST=http://0.0.0.0:7700 MEILI_HOST=http://0.0.0.0:7700
MEILI_MASTER_KEY=DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt MEILI_MASTER_KEY=DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt
# Optional: Disable indexing, useful in a multi-node setup
# where only one instance should perform an index sync.
# MEILI_NO_SYNC=true
#==================================================# #==================================================#
# Speech to Text & Text to Speech # # Speech to Text & Text to Speech #
#==================================================# #==================================================#
@ -495,6 +504,16 @@ HELP_AND_FAQ_URL=https://librechat.ai
# Google tag manager id # Google tag manager id
#ANALYTICS_GTM_ID=user provided google tag manager id #ANALYTICS_GTM_ID=user provided google tag manager id
#===============#
# REDIS Options #
#===============#
# REDIS_URI=10.10.10.10:6379
# USE_REDIS=true
# USE_REDIS_CLUSTER=true
# REDIS_CA=/path/to/ca.crt
#==================================================# #==================================================#
# Others # # Others #
#==================================================# #==================================================#
@ -502,9 +521,6 @@ HELP_AND_FAQ_URL=https://librechat.ai
# NODE_ENV= # NODE_ENV=
# REDIS_URI=
# USE_REDIS=
# E2E_USER_EMAIL= # E2E_USER_EMAIL=
# E2E_USER_PASSWORD= # E2E_USER_PASSWORD=

View file

@ -1,50 +0,0 @@
name: Question
description: Ask your question
title: "[Question]: "
labels: ["❓ question"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill this!
- type: textarea
id: what-is-your-question
attributes:
label: What is your question?
description: Please give as many details as possible
placeholder: Please give as many details as possible
validations:
required: true
- type: textarea
id: more-details
attributes:
label: More Details
description: Please provide more details if needed.
placeholder: Please provide more details if needed.
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What is the main subject of your question?
multiple: true
options:
- Documentation
- Installation
- UI
- Endpoints
- User System/OAuth
- Other
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem. You can drag and drop, paste images directly here or link to them.
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/danny-avila/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true

View file

@ -51,7 +51,7 @@ class GoogleClient extends BaseClient {
const serviceKey = creds[AuthKeys.GOOGLE_SERVICE_KEY] ?? {}; const serviceKey = creds[AuthKeys.GOOGLE_SERVICE_KEY] ?? {};
this.serviceKey = this.serviceKey =
serviceKey && typeof serviceKey === 'string' ? JSON.parse(serviceKey) : serviceKey ?? {}; serviceKey && typeof serviceKey === 'string' ? JSON.parse(serviceKey) : (serviceKey ?? {});
/** @type {string | null | undefined} */ /** @type {string | null | undefined} */
this.project_id = this.serviceKey.project_id; this.project_id = this.serviceKey.project_id;
this.client_email = this.serviceKey.client_email; this.client_email = this.serviceKey.client_email;
@ -73,6 +73,8 @@ class GoogleClient extends BaseClient {
* @type {string} */ * @type {string} */
this.outputTokensKey = 'output_tokens'; this.outputTokensKey = 'output_tokens';
this.visionMode = VisionModes.generative; this.visionMode = VisionModes.generative;
/** @type {string} */
this.systemMessage;
if (options.skipSetOptions) { if (options.skipSetOptions) {
return; return;
} }
@ -184,7 +186,7 @@ class GoogleClient extends BaseClient {
if (typeof this.options.artifactsPrompt === 'string' && this.options.artifactsPrompt) { if (typeof this.options.artifactsPrompt === 'string' && this.options.artifactsPrompt) {
promptPrefix = `${promptPrefix ?? ''}\n${this.options.artifactsPrompt}`.trim(); promptPrefix = `${promptPrefix ?? ''}\n${this.options.artifactsPrompt}`.trim();
} }
this.options.promptPrefix = promptPrefix; this.systemMessage = promptPrefix;
this.initializeClient(); this.initializeClient();
return this; return this;
} }
@ -314,7 +316,7 @@ class GoogleClient extends BaseClient {
} }
this.augmentedPrompt = await this.contextHandlers.createContext(); this.augmentedPrompt = await this.contextHandlers.createContext();
this.options.promptPrefix = this.augmentedPrompt + this.options.promptPrefix; this.systemMessage = this.augmentedPrompt + this.systemMessage;
} }
} }
@ -361,8 +363,8 @@ class GoogleClient extends BaseClient {
throw new Error('[GoogleClient] PaLM 2 and Codey models are no longer supported.'); throw new Error('[GoogleClient] PaLM 2 and Codey models are no longer supported.');
} }
if (this.options.promptPrefix) { if (this.systemMessage) {
const instructionsTokenCount = this.getTokenCount(this.options.promptPrefix); const instructionsTokenCount = this.getTokenCount(this.systemMessage);
this.maxContextTokens = this.maxContextTokens - instructionsTokenCount; this.maxContextTokens = this.maxContextTokens - instructionsTokenCount;
if (this.maxContextTokens < 0) { if (this.maxContextTokens < 0) {
@ -417,8 +419,8 @@ class GoogleClient extends BaseClient {
], ],
}; };
if (this.options.promptPrefix) { if (this.systemMessage) {
payload.instances[0].context = this.options.promptPrefix; payload.instances[0].context = this.systemMessage;
} }
logger.debug('[GoogleClient] buildMessages', payload); logger.debug('[GoogleClient] buildMessages', payload);
@ -464,7 +466,7 @@ class GoogleClient extends BaseClient {
identityPrefix = `${identityPrefix}\nYou are ${this.options.modelLabel}`; identityPrefix = `${identityPrefix}\nYou are ${this.options.modelLabel}`;
} }
let promptPrefix = (this.options.promptPrefix ?? '').trim(); let promptPrefix = (this.systemMessage ?? '').trim();
if (identityPrefix) { if (identityPrefix) {
promptPrefix = `${identityPrefix}${promptPrefix}`; promptPrefix = `${identityPrefix}${promptPrefix}`;
@ -639,7 +641,7 @@ class GoogleClient extends BaseClient {
let error; let error;
try { try {
if (!EXCLUDED_GENAI_MODELS.test(modelName) && !this.project_id) { if (!EXCLUDED_GENAI_MODELS.test(modelName) && !this.project_id) {
/** @type {GenAI} */ /** @type {GenerativeModel} */
const client = this.client; const client = this.client;
/** @type {GenerateContentRequest} */ /** @type {GenerateContentRequest} */
const requestOptions = { const requestOptions = {
@ -648,7 +650,7 @@ class GoogleClient extends BaseClient {
generationConfig: googleGenConfigSchema.parse(this.modelOptions), generationConfig: googleGenConfigSchema.parse(this.modelOptions),
}; };
const promptPrefix = (this.options.promptPrefix ?? '').trim(); const promptPrefix = (this.systemMessage ?? '').trim();
if (promptPrefix.length) { if (promptPrefix.length) {
requestOptions.systemInstruction = { requestOptions.systemInstruction = {
parts: [ parts: [
@ -663,7 +665,17 @@ class GoogleClient extends BaseClient {
/** @type {GenAIUsageMetadata} */ /** @type {GenAIUsageMetadata} */
let usageMetadata; let usageMetadata;
const result = await client.generateContentStream(requestOptions); abortController.signal.addEventListener(
'abort',
() => {
logger.warn('[GoogleClient] Request was aborted', abortController.signal.reason);
},
{ once: true },
);
const result = await client.generateContentStream(requestOptions, {
signal: abortController.signal,
});
for await (const chunk of result.stream) { for await (const chunk of result.stream) {
usageMetadata = !usageMetadata usageMetadata = !usageMetadata
? chunk?.usageMetadata ? chunk?.usageMetadata

View file

@ -1,15 +1,81 @@
const fs = require('fs');
const ioredis = require('ioredis');
const KeyvRedis = require('@keyv/redis'); const KeyvRedis = require('@keyv/redis');
const { isEnabled } = require('~/server/utils'); const { isEnabled } = require('~/server/utils');
const logger = require('~/config/winston'); const logger = require('~/config/winston');
const { REDIS_URI, USE_REDIS } = process.env; const { REDIS_URI, USE_REDIS, USE_REDIS_CLUSTER, REDIS_CA, REDIS_KEY_PREFIX, REDIS_MAX_LISTENERS } =
process.env;
let keyvRedis; let keyvRedis;
const redis_prefix = REDIS_KEY_PREFIX || '';
const redis_max_listeners = REDIS_MAX_LISTENERS || 10;
function mapURI(uri) {
const regex =
/^(?:(?<scheme>\w+):\/\/)?(?:(?<user>[^:@]+)(?::(?<password>[^@]+))?@)?(?<host>[\w.-]+)(?::(?<port>\d{1,5}))?$/;
const match = uri.match(regex);
if (match) {
const { scheme, user, password, host, port } = match.groups;
return {
scheme: scheme || 'none',
user: user || null,
password: password || null,
host: host || null,
port: port || null,
};
} else {
const parts = uri.split(':');
if (parts.length === 2) {
return {
scheme: 'none',
user: null,
password: null,
host: parts[0],
port: parts[1],
};
}
return {
scheme: 'none',
user: null,
password: null,
host: uri,
port: null,
};
}
}
if (REDIS_URI && isEnabled(USE_REDIS)) { if (REDIS_URI && isEnabled(USE_REDIS)) {
keyvRedis = new KeyvRedis(REDIS_URI, { useRedisSets: false }); let redisOptions = null;
let keyvOpts = {
useRedisSets: false,
keyPrefix: redis_prefix,
};
if (REDIS_CA) {
const ca = fs.readFileSync(REDIS_CA);
redisOptions = { tls: { ca } };
}
if (isEnabled(USE_REDIS_CLUSTER)) {
const hosts = REDIS_URI.split(',').map((item) => {
var value = mapURI(item);
return {
host: value.host,
port: value.port,
};
});
const cluster = new ioredis.Cluster(hosts, { redisOptions });
keyvRedis = new KeyvRedis(cluster, keyvOpts);
} else {
keyvRedis = new KeyvRedis(REDIS_URI, keyvOpts);
}
keyvRedis.on('error', (err) => logger.error('KeyvRedis connection error:', err)); keyvRedis.on('error', (err) => logger.error('KeyvRedis connection error:', err));
keyvRedis.setMaxListeners(20); keyvRedis.setMaxListeners(redis_max_listeners);
logger.info( logger.info(
'[Optional] Redis initialized. Note: Redis support is experimental. If you have issues, disable it. Cache needs to be flushed for values to refresh.', '[Optional] Redis initialized. Note: Redis support is experimental. If you have issues, disable it. Cache needs to be flushed for values to refresh.',
); );

View file

@ -1,9 +1,11 @@
const { MeiliSearch } = require('meilisearch'); const { MeiliSearch } = require('meilisearch');
const Conversation = require('~/models/schema/convoSchema'); const Conversation = require('~/models/schema/convoSchema');
const Message = require('~/models/schema/messageSchema'); const Message = require('~/models/schema/messageSchema');
const { isEnabled } = require('~/server/utils');
const { logger } = require('~/config'); const { logger } = require('~/config');
const searchEnabled = process.env?.SEARCH?.toLowerCase() === 'true'; const searchEnabled = isEnabled(process.env.SEARCH);
const indexingDisabled = isEnabled(process.env.MEILI_NO_SYNC);
let currentTimeout = null; let currentTimeout = null;
class MeiliSearchClient { class MeiliSearchClient {
@ -23,8 +25,7 @@ class MeiliSearchClient {
} }
} }
// eslint-disable-next-line no-unused-vars async function indexSync() {
async function indexSync(req, res, next) {
if (!searchEnabled) { if (!searchEnabled) {
return; return;
} }
@ -33,10 +34,15 @@ async function indexSync(req, res, next) {
const client = MeiliSearchClient.getInstance(); const client = MeiliSearchClient.getInstance();
const { status } = await client.health(); const { status } = await client.health();
if (status !== 'available' || !process.env.SEARCH) { if (status !== 'available') {
throw new Error('Meilisearch not available'); throw new Error('Meilisearch not available');
} }
if (indexingDisabled === true) {
logger.info('[indexSync] Indexing is disabled, skipping...');
return;
}
const messageCount = await Message.countDocuments(); const messageCount = await Message.countDocuments();
const convoCount = await Conversation.countDocuments(); const convoCount = await Conversation.countDocuments();
const messages = await client.index('messages').getStats(); const messages = await client.index('messages').getStats();
@ -71,7 +77,6 @@ async function indexSync(req, res, next) {
logger.info('[indexSync] Meilisearch not configured, search will be disabled.'); logger.info('[indexSync] Meilisearch not configured, search will be disabled.');
} else { } else {
logger.error('[indexSync] error', err); logger.error('[indexSync] error', err);
// res.status(500).json({ error: 'Server error' });
} }
} }
} }

View file

@ -3,40 +3,40 @@ const { logger } = require('~/config');
const options = [ const options = [
{ {
label: 'idea', label: 'com_ui_idea',
value: 'com_ui_idea', value: 'idea',
}, },
{ {
label: 'travel', label: 'com_ui_travel',
value: 'com_ui_travel', value: 'travel',
}, },
{ {
label: 'teach_or_explain', label: 'com_ui_teach_or_explain',
value: 'com_ui_teach_or_explain', value: 'teach_or_explain',
}, },
{ {
label: 'write', label: 'com_ui_write',
value: 'com_ui_write', value: 'write',
}, },
{ {
label: 'shop', label: 'com_ui_shop',
value: 'com_ui_shop', value: 'shop',
}, },
{ {
label: 'code', label: 'com_ui_code',
value: 'com_ui_code', value: 'code',
}, },
{ {
label: 'misc', label: 'com_ui_misc',
value: 'com_ui_misc', value: 'misc',
}, },
{ {
label: 'roleplay', label: 'com_ui_roleplay',
value: 'com_ui_roleplay', value: 'roleplay',
}, },
{ {
label: 'finance', label: 'com_ui_finance',
value: 'com_ui_finance', value: 'finance',
}, },
]; ];

View file

@ -3,9 +3,11 @@ const {
verifyBackupCode, verifyBackupCode,
generateTOTPSecret, generateTOTPSecret,
generateBackupCodes, generateBackupCodes,
getTOTPSecret,
} = require('~/server/services/twoFactorService'); } = require('~/server/services/twoFactorService');
const { updateUser, getUserById } = require('~/models'); const { updateUser, getUserById } = require('~/models');
const { logger } = require('~/config'); const { logger } = require('~/config');
const { encryptV2 } = require('~/server/utils/crypto');
const enable2FAController = async (req, res) => { const enable2FAController = async (req, res) => {
const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, ''); const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
@ -15,7 +17,8 @@ const enable2FAController = async (req, res) => {
const secret = generateTOTPSecret(); const secret = generateTOTPSecret();
const { plainCodes, codeObjects } = await generateBackupCodes(); const { plainCodes, codeObjects } = await generateBackupCodes();
const user = await updateUser(userId, { totpSecret: secret, backupCodes: codeObjects }); const encryptedSecret = await encryptV2(secret);
const user = await updateUser(userId, { totpSecret: encryptedSecret, backupCodes: codeObjects });
const otpauthUrl = `otpauth://totp/${safeAppTitle}:${user.email}?secret=${secret}&issuer=${safeAppTitle}`; const otpauthUrl = `otpauth://totp/${safeAppTitle}:${user.email}?secret=${secret}&issuer=${safeAppTitle}`;
@ -38,14 +41,16 @@ const verify2FAController = async (req, res) => {
return res.status(400).json({ message: '2FA not initiated' }); return res.status(400).json({ message: '2FA not initiated' });
} }
let verified = false; // Retrieve the plain TOTP secret using getTOTPSecret.
if (token && (await verifyTOTP(user.totpSecret, token))) { const secret = await getTOTPSecret(user.totpSecret);
if (token && (await verifyTOTP(secret, token))) {
return res.status(200).json(); return res.status(200).json();
} else if (backupCode) { } else if (backupCode) {
verified = await verifyBackupCode({ user, backupCode }); const verified = await verifyBackupCode({ user, backupCode });
} if (verified) {
if (verified) { return res.status(200).json();
return res.status(200).json(); }
} }
return res.status(400).json({ message: 'Invalid token.' }); return res.status(400).json({ message: 'Invalid token.' });
@ -65,7 +70,10 @@ const confirm2FAController = async (req, res) => {
return res.status(400).json({ message: '2FA not initiated' }); return res.status(400).json({ message: '2FA not initiated' });
} }
if (await verifyTOTP(user.totpSecret, token)) { // Retrieve the plain TOTP secret using getTOTPSecret.
const secret = await getTOTPSecret(user.totpSecret);
if (await verifyTOTP(secret, token)) {
return res.status(200).json(); return res.status(200).json();
} }

View file

@ -1,5 +1,5 @@
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const { verifyTOTP, verifyBackupCode } = require('~/server/services/twoFactorService'); const { verifyTOTP, verifyBackupCode, getTOTPSecret } = require('~/server/services/twoFactorService');
const { setAuthTokens } = require('~/server/services/AuthService'); const { setAuthTokens } = require('~/server/services/AuthService');
const { getUserById } = require('~/models/userMethods'); const { getUserById } = require('~/models/userMethods');
const { logger } = require('~/config'); const { logger } = require('~/config');
@ -24,9 +24,11 @@ const verify2FA = async (req, res) => {
return res.status(400).json({ message: '2FA is not enabled for this user' }); return res.status(400).json({ message: '2FA is not enabled for this user' });
} }
let verified = false; // Use the new getTOTPSecret function to retrieve (and decrypt if necessary) the TOTP secret.
const secret = await getTOTPSecret(user.totpSecret);
if (token && (await verifyTOTP(user.totpSecret, token))) { let verified = false;
if (token && (await verifyTOTP(secret, token))) {
verified = true; verified = true;
} else if (backupCode) { } else if (backupCode) {
verified = await verifyBackupCode({ user, backupCode }); verified = await verifyBackupCode({ user, backupCode });
@ -39,7 +41,7 @@ const verify2FA = async (req, res) => {
// Prepare user data for response. // Prepare user data for response.
// If the user is a plain object (from lean queries), we create a shallow copy. // If the user is a plain object (from lean queries), we create a shallow copy.
const userData = user.toObject ? user.toObject() : { ...user }; const userData = user.toObject ? user.toObject() : { ...user };
// Remove sensitive fields // Remove sensitive fields.
delete userData.password; delete userData.password;
delete userData.__v; delete userData.__v;
delete userData.totpSecret; delete userData.totpSecret;

View file

@ -22,10 +22,11 @@ const staticCache = require('./utils/staticCache');
const noIndex = require('./middleware/noIndex'); const noIndex = require('./middleware/noIndex');
const routes = require('./routes'); const routes = require('./routes');
const { PORT, HOST, ALLOW_SOCIAL_LOGIN, DISABLE_COMPRESSION } = process.env ?? {}; const { PORT, HOST, ALLOW_SOCIAL_LOGIN, DISABLE_COMPRESSION, TRUST_PROXY } = process.env ?? {};
const port = Number(PORT) || 3080; const port = Number(PORT) || 3080;
const host = HOST || 'localhost'; const host = HOST || 'localhost';
const trusted_proxy = Number(TRUST_PROXY) || 1; /* trust first proxy by default */
const startServer = async () => { const startServer = async () => {
if (typeof Bun !== 'undefined') { if (typeof Bun !== 'undefined') {
@ -53,7 +54,7 @@ const startServer = async () => {
app.use(staticCache(app.locals.paths.dist)); app.use(staticCache(app.locals.paths.dist));
app.use(staticCache(app.locals.paths.fonts)); app.use(staticCache(app.locals.paths.fonts));
app.use(staticCache(app.locals.paths.assets)); app.use(staticCache(app.locals.paths.assets));
app.set('trust proxy', 1); /* trust first proxy */ app.set('trust proxy', trusted_proxy);
app.use(cors()); app.use(cors());
app.use(cookieParser()); app.use(cookieParser());
@ -145,6 +146,18 @@ process.on('uncaughtException', (err) => {
logger.error('There was an uncaught error:', err); logger.error('There was an uncaught error:', err);
} }
if (err.message.includes('abort')) {
logger.warn('There was an uncatchable AbortController error.');
return;
}
if (err.message.includes('GoogleGenerativeAI')) {
logger.warn(
'\n\n`GoogleGenerativeAI` errors cannot be caught due to an upstream issue, see: https://github.com/google-gemini/generative-ai-js/issues/303',
);
return;
}
if (err.message.includes('fetch failed')) { if (err.message.includes('fetch failed')) {
if (messageCount === 0) { if (messageCount === 0) {
logger.warn('Meilisearch error, search will be disabled'); logger.warn('Meilisearch error, search will be disabled');

View file

@ -209,7 +209,7 @@ const primeFiles = async (options, apiKey) => {
const { handleFileUpload: uploadCodeEnvFile } = getStrategyFunctions( const { handleFileUpload: uploadCodeEnvFile } = getStrategyFunctions(
FileSources.execute_code, FileSources.execute_code,
); );
const stream = await getDownloadStream(file.filepath); const stream = await getDownloadStream(options.req, file.filepath);
const fileIdentifier = await uploadCodeEnvFile({ const fileIdentifier = await uploadCodeEnvFile({
req: options.req, req: options.req,
stream, stream,

View file

@ -224,10 +224,11 @@ async function uploadFileToFirebase({ req, file, file_id }) {
/** /**
* Retrieves a readable stream for a file from Firebase storage. * Retrieves a readable stream for a file from Firebase storage.
* *
* @param {ServerRequest} _req
* @param {string} filepath - The filepath. * @param {string} filepath - The filepath.
* @returns {Promise<ReadableStream>} A readable stream of the file. * @returns {Promise<ReadableStream>} A readable stream of the file.
*/ */
async function getFirebaseFileStream(filepath) { async function getFirebaseFileStream(_req, filepath) {
try { try {
const storage = getFirebaseStorage(); const storage = getFirebaseStorage();
if (!storage) { if (!storage) {

View file

@ -286,11 +286,31 @@ async function uploadLocalFile({ req, file, file_id }) {
/** /**
* Retrieves a readable stream for a file from local storage. * Retrieves a readable stream for a file from local storage.
* *
* @param {ServerRequest} req - The request object from Express
* @param {string} filepath - The filepath. * @param {string} filepath - The filepath.
* @returns {ReadableStream} A readable stream of the file. * @returns {ReadableStream} A readable stream of the file.
*/ */
function getLocalFileStream(filepath) { function getLocalFileStream(req, filepath) {
try { try {
if (filepath.includes('/uploads/')) {
const basePath = filepath.split('/uploads/')[1];
if (!basePath) {
logger.warn(`Invalid base path: ${filepath}`);
throw new Error(`Invalid file path: ${filepath}`);
}
const fullPath = path.join(req.app.locals.paths.uploads, basePath);
const uploadsDir = req.app.locals.paths.uploads;
const rel = path.relative(uploadsDir, fullPath);
if (rel.startsWith('..') || path.isAbsolute(rel) || rel.includes(`..${path.sep}`)) {
logger.warn(`Invalid relative file path: ${filepath}`);
throw new Error(`Invalid file path: ${filepath}`);
}
return fs.createReadStream(fullPath);
}
return fs.createReadStream(filepath); return fs.createReadStream(filepath);
} catch (error) { } catch (error) {
logger.error('Error getting local file stream:', error); logger.error('Error getting local file stream:', error);

View file

@ -1,14 +1,15 @@
const { sign } = require('jsonwebtoken'); const { sign } = require('jsonwebtoken');
const { webcrypto } = require('node:crypto'); const { webcrypto } = require('node:crypto');
const { hashBackupCode } = require('~/server/utils/crypto'); const { hashBackupCode, decryptV2 } = require('~/server/utils/crypto');
const { updateUser } = require('~/models/userMethods'); const { updateUser } = require('~/models/userMethods');
const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
/** /**
* Encodes a Buffer into a Base32 string using RFC 4648 alphabet. * Encodes a Buffer into a Base32 string using the RFC 4648 alphabet.
*
* @param {Buffer} buffer - The buffer to encode. * @param {Buffer} buffer - The buffer to encode.
* @returns {string} - The Base32 encoded string. * @returns {string} The Base32 encoded string.
*/ */
const encodeBase32 = (buffer) => { const encodeBase32 = (buffer) => {
let bits = 0; let bits = 0;
@ -30,8 +31,9 @@ const encodeBase32 = (buffer) => {
/** /**
* Decodes a Base32-encoded string back into a Buffer. * Decodes a Base32-encoded string back into a Buffer.
* @param {string} base32Str *
* @returns {Buffer} * @param {string} base32Str - The Base32-encoded string.
* @returns {Buffer} The decoded buffer.
*/ */
const decodeBase32 = (base32Str) => { const decodeBase32 = (base32Str) => {
const cleaned = base32Str.replace(/=+$/, '').toUpperCase(); const cleaned = base32Str.replace(/=+$/, '').toUpperCase();
@ -54,15 +56,20 @@ const decodeBase32 = (base32Str) => {
}; };
/** /**
* Generate a temporary token for 2FA verification. * Generates a temporary token for 2FA verification.
* This token is signed with JWT_SECRET and expires in 5 minutes. * The token is signed with the JWT_SECRET and expires in 5 minutes.
*
* @param {string} userId - The unique identifier of the user.
* @returns {string} The signed JWT token.
*/ */
const generate2FATempToken = (userId) => const generate2FATempToken = (userId) =>
sign({ userId, twoFAPending: true }, process.env.JWT_SECRET, { expiresIn: '5m' }); sign({ userId, twoFAPending: true }, process.env.JWT_SECRET, { expiresIn: '5m' });
/** /**
* Generate a TOTP secret. * Generates a TOTP secret.
* Generates 10 random bytes using WebCrypto and encodes them into a Base32 string. * Creates 10 random bytes using WebCrypto and encodes them into a Base32 string.
*
* @returns {string} A Base32-encoded secret for TOTP.
*/ */
const generateTOTPSecret = () => { const generateTOTPSecret = () => {
const randomArray = new Uint8Array(10); const randomArray = new Uint8Array(10);
@ -71,12 +78,12 @@ const generateTOTPSecret = () => {
}; };
/** /**
* Generate a TOTP code based on the secret and current time. * Generates a Time-based One-Time Password (TOTP) based on the provided secret and time.
* Uses a 30-second time step and generates a 6-digit code. * This implementation uses a 30-second time step and produces a 6-digit code.
* *
* @param {string} secret - Base32-encoded secret * @param {string} secret - The Base32-encoded TOTP secret.
* @param {number} [forTime=Date.now()] - Time in milliseconds * @param {number} [forTime=Date.now()] - The time (in milliseconds) for which to generate the TOTP.
* @returns {Promise<string>} - The 6-digit TOTP code. * @returns {Promise<string>} A promise that resolves to the 6-digit TOTP code.
*/ */
const generateTOTP = async (secret, forTime = Date.now()) => { const generateTOTP = async (secret, forTime = Date.now()) => {
const timeStep = 30; // seconds const timeStep = 30; // seconds
@ -106,6 +113,7 @@ const generateTOTP = async (secret, forTime = Date.now()) => {
const signatureBuffer = await webcrypto.subtle.sign('HMAC', cryptoKey, counterBuffer); const signatureBuffer = await webcrypto.subtle.sign('HMAC', cryptoKey, counterBuffer);
const hmac = new Uint8Array(signatureBuffer); const hmac = new Uint8Array(signatureBuffer);
// Dynamic truncation as per RFC 4226
const offset = hmac[hmac.length - 1] & 0xf; const offset = hmac[hmac.length - 1] & 0xf;
const slice = hmac.slice(offset, offset + 4); const slice = hmac.slice(offset, offset + 4);
const view = new DataView(slice.buffer, slice.byteOffset, slice.byteLength); const view = new DataView(slice.buffer, slice.byteOffset, slice.byteLength);
@ -115,12 +123,12 @@ const generateTOTP = async (secret, forTime = Date.now()) => {
}; };
/** /**
* Verify a provided TOTP token against the secret. * Verifies a provided TOTP token against the secret.
* Allows for a ±1 time-step window. * It allows for a ±1 time-step window to account for slight clock discrepancies.
* *
* @param {string} secret * @param {string} secret - The Base32-encoded TOTP secret.
* @param {string} token * @param {string} token - The TOTP token provided by the user.
* @returns {Promise<boolean>} * @returns {Promise<boolean>} A promise that resolves to true if the token is valid; otherwise, false.
*/ */
const verifyTOTP = async (secret, token) => { const verifyTOTP = async (secret, token) => {
const timeStepMS = 30 * 1000; const timeStepMS = 30 * 1000;
@ -135,12 +143,13 @@ const verifyTOTP = async (secret, token) => {
}; };
/** /**
* Generate backup codes. * Generates backup codes for two-factor authentication.
* Generates `count` backup code objects and returns an object with both plain codes * Each backup code is an 8-character hexadecimal string along with its SHA-256 hash.
* (for one-time download) and their objects (for secure storage). Uses WebCrypto for randomness and hashing. * The plain codes are returned for one-time download, while the hashed objects are meant for secure storage.
* *
* @param {number} count - Number of backup codes to generate (default: 10). * @param {number} [count=10] - The number of backup codes to generate.
* @returns {Promise<Object>} - Contains `plainCodes` (array of strings) and `codeObjects` (array of objects). * @returns {Promise<{ plainCodes: string[], codeObjects: Array<{ codeHash: string, used: boolean, usedAt: Date | null }> }>}
* A promise that resolves to an object containing both plain backup codes and their corresponding code objects.
*/ */
const generateBackupCodes = async (count = 10) => { const generateBackupCodes = async (count = 10) => {
const plainCodes = []; const plainCodes = [];
@ -165,11 +174,12 @@ const generateBackupCodes = async (count = 10) => {
}; };
/** /**
* Verifies a backup code and updates the user's backup codes if valid * Verifies a backup code for a user and updates its status as used if valid.
* @param {Object} params *
* @param {TUser | undefined} [params.user] - The user object * @param {Object} params - The parameters object.
* @param {string | undefined} [params.backupCode] - The backup code to verify * @param {TUser | undefined} [params.user] - The user object containing backup codes.
* @returns {Promise<boolean>} - Whether the backup code was valid * @param {string | undefined} [params.backupCode] - The backup code to verify.
* @returns {Promise<boolean>} A promise that resolves to true if the backup code is valid and updated; otherwise, false.
*/ */
const verifyBackupCode = async ({ user, backupCode }) => { const verifyBackupCode = async ({ user, backupCode }) => {
if (!backupCode || !user || !Array.isArray(user.backupCodes)) { if (!backupCode || !user || !Array.isArray(user.backupCodes)) {
@ -195,9 +205,32 @@ const verifyBackupCode = async ({ user, backupCode }) => {
return false; return false;
}; };
/**
* Retrieves and, if necessary, decrypts a stored TOTP secret.
* If the secret contains a colon, it is assumed to be in the format "iv:encryptedData" and will be decrypted.
* If the secret is exactly 16 characters long, it is assumed to be a legacy plain secret.
*
* @param {string|null} storedSecret - The stored TOTP secret (which may be encrypted).
* @returns {Promise<string|null>} A promise that resolves to the plain TOTP secret, or null if none is provided.
*/
const getTOTPSecret = async (storedSecret) => {
if (!storedSecret) { return null; }
// Check for a colon marker (encrypted secrets are stored as "iv:encryptedData")
if (storedSecret.includes(':')) {
return await decryptV2(storedSecret);
}
// If it's exactly 16 characters, assume it's already plain (legacy secret)
if (storedSecret.length === 16) {
return storedSecret;
}
// Fallback in case it doesn't meet our criteria.
return storedSecret;
};
module.exports = { module.exports = {
verifyTOTP, verifyTOTP,
generateTOTP, generateTOTP,
getTOTPSecret,
verifyBackupCode, verifyBackupCode,
generateTOTPSecret, generateTOTPSecret,
generateBackupCodes, generateBackupCodes,

View file

@ -66,8 +66,8 @@
"html-to-image": "^1.11.11", "html-to-image": "^1.11.11",
"i18next": "^24.2.2", "i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.3", "i18next-browser-languagedetector": "^8.0.3",
"js-cookie": "^3.0.5",
"input-otp": "^1.4.2", "input-otp": "^1.4.2",
"js-cookie": "^3.0.5",
"librechat-data-provider": "*", "librechat-data-provider": "*",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lucide-react": "^0.394.0", "lucide-react": "^0.394.0",
@ -86,7 +86,7 @@
"react-i18next": "^15.4.0", "react-i18next": "^15.4.0",
"react-lazy-load-image-component": "^1.6.0", "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1", "react-markdown": "^9.0.1",
"react-resizable-panels": "^2.1.1", "react-resizable-panels": "^2.1.7",
"react-router-dom": "^6.11.2", "react-router-dom": "^6.11.2",
"react-speech-recognition": "^3.10.0", "react-speech-recognition": "^3.10.0",
"react-textarea-autosize": "^8.4.0", "react-textarea-autosize": "^8.4.0",

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,4 @@
import { Plus } from 'lucide-react';
import React, { useMemo, useCallback } from 'react'; import React, { useMemo, useCallback } from 'react';
import { useGetModelsQuery } from 'librechat-data-provider/react-query'; import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import { Controller, useWatch, useForm, FormProvider } from 'react-hook-form'; import { Controller, useWatch, useForm, FormProvider } from 'react-hook-form';
@ -211,34 +212,54 @@ export default function AgentPanel({
className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden" className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden"
aria-label="Agent configuration form" aria-label="Agent configuration form"
> >
<div className="mt-2 flex w-full flex-wrap gap-2"> <div className="mx-1 mt-2 flex w-full flex-wrap gap-2">
<Controller <div className="w-full">
name="agent" <Controller
control={control} name="agent"
render={({ field }) => ( control={control}
<AgentSelect render={({ field }) => (
reset={reset} <AgentSelect
value={field.value} reset={reset}
agentQuery={agentQuery} value={field.value}
setCurrentAgentId={setCurrentAgentId} agentQuery={agentQuery}
selectedAgentId={current_agent_id ?? null} setCurrentAgentId={setCurrentAgentId}
createMutation={create} selectedAgentId={current_agent_id ?? null}
/> createMutation={create}
)} />
/> )}
{/* Select Button */} />
</div>
{/* Create + Select Button */}
{agent_id && ( {agent_id && (
<Button <div className="flex w-full gap-2">
variant="submit" <Button
disabled={!agent_id} type="button"
onClick={(e) => { variant="outline"
e.preventDefault(); className="w-full justify-center"
handleSelectAgent(); onClick={() => {
}} reset(defaultAgentFormValues);
aria-label="Select agent" setCurrentAgentId(undefined);
> }}
{localize('com_ui_select')} >
</Button> <Plus className="mr-1 h-4 w-4" />
{localize('com_ui_create') +
' ' +
localize('com_ui_new') +
' ' +
localize('com_ui_agent')}
</Button>
<Button
variant="submit"
disabled={!agent_id}
onClick={(e) => {
e.preventDefault();
handleSelectAgent();
}}
aria-label={localize('com_ui_select') + ' ' + localize('com_ui_agent')}
>
{localize('com_ui_select')}
</Button>
</div>
)} )}
</div> </div>
{!canEditAgent && ( {!canEditAgent && (

View file

@ -4,10 +4,16 @@ import { Skeleton } from '~/components/ui';
export default function AgentPanelSkeleton() { export default function AgentPanelSkeleton() {
return ( return (
<div className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden"> <div className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden">
{/* Agent Select and Button */} <div className="mx-1 mt-2 flex w-full flex-wrap gap-2">
<div className="mt-1 flex w-full gap-2"> {/* Agent Select Dropdown */}
<Skeleton className="h-[40px] w-4/5 rounded-lg" /> <div className="w-full">
<Skeleton className="h-[40px] w-1/5 rounded-lg" /> <Skeleton className="h-[40px] w-full rounded-md" />
</div>
{/* Create and Select Buttons */}
<div className="flex w-full gap-2">
<Skeleton className="h-[40px] w-3/4 rounded-md" /> {/* Create Button */}
<Skeleton className="h-[40px] w-1/4 rounded-md" /> {/* Select Button */}
</div>
</div> </div>
<div className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent"> <div className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent">

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -85,6 +85,7 @@
"com_auth_email_verification_redirecting": "Weiterleitung in {{0}} Sekunden...", "com_auth_email_verification_redirecting": "Weiterleitung in {{0}} Sekunden...",
"com_auth_email_verification_resend_prompt": "Keine E-Mail erhalten?", "com_auth_email_verification_resend_prompt": "Keine E-Mail erhalten?",
"com_auth_email_verification_success": "E-Mail erfolgreich verifiziert", "com_auth_email_verification_success": "E-Mail erfolgreich verifiziert",
"com_auth_email_verifying_ellipsis": "Überprüfe …",
"com_auth_error_create": "Bei der Registrierung deines Kontos ist ein Fehler aufgetreten. Bitte versuche es erneut.", "com_auth_error_create": "Bei der Registrierung deines Kontos ist ein Fehler aufgetreten. Bitte versuche es erneut.",
"com_auth_error_invalid_reset_token": "Dieser Passwort-Reset-Token ist nicht mehr gültig.", "com_auth_error_invalid_reset_token": "Dieser Passwort-Reset-Token ist nicht mehr gültig.",
"com_auth_error_login": "Anmeldung mit den angegebenen Informationen nicht möglich. Bitte überprüfe deine Anmeldedaten und versuche es erneut.", "com_auth_error_login": "Anmeldung mit den angegebenen Informationen nicht möglich. Bitte überprüfe deine Anmeldedaten und versuche es erneut.",
@ -121,9 +122,11 @@
"com_auth_submit_registration": "Registrierung absenden", "com_auth_submit_registration": "Registrierung absenden",
"com_auth_to_reset_your_password": "um Ihr Passwort zurückzusetzen.", "com_auth_to_reset_your_password": "um Ihr Passwort zurückzusetzen.",
"com_auth_to_try_again": "um es erneut zu versuchen.", "com_auth_to_try_again": "um es erneut zu versuchen.",
"com_auth_two_factor": "Prüfe deine bevorzugte Einmalkennwort-App auf einen Code.",
"com_auth_username": "Benutzername (optional)", "com_auth_username": "Benutzername (optional)",
"com_auth_username_max_length": "Benutzername darf nicht länger als 20 Zeichen sein", "com_auth_username_max_length": "Benutzername darf nicht länger als 20 Zeichen sein",
"com_auth_username_min_length": "Benutzername muss mindestens 2 Zeichen lang sein", "com_auth_username_min_length": "Benutzername muss mindestens 2 Zeichen lang sein",
"com_auth_verify_your_identity": "Bestätige deine Identität",
"com_auth_welcome_back": "Willkommen zurück", "com_auth_welcome_back": "Willkommen zurück",
"com_click_to_download": "(hier klicken zum Herunterladen)", "com_click_to_download": "(hier klicken zum Herunterladen)",
"com_download_expired": "Download abgelaufen", "com_download_expired": "Download abgelaufen",
@ -261,6 +264,7 @@
"com_files_number_selected": "{{0}} von {{1}} Datei(en) ausgewählt", "com_files_number_selected": "{{0}} von {{1}} Datei(en) ausgewählt",
"com_generated_files": "Generierte Dateien:", "com_generated_files": "Generierte Dateien:",
"com_hide_examples": "Beispiele ausblenden", "com_hide_examples": "Beispiele ausblenden",
"com_nav_2fa": "Zwei-Faktor-Authentifizierung (2FA)",
"com_nav_account_settings": "Kontoeinstellungen", "com_nav_account_settings": "Kontoeinstellungen",
"com_nav_always_make_prod": "Neue Versionen direkt produktiv nehmen", "com_nav_always_make_prod": "Neue Versionen direkt produktiv nehmen",
"com_nav_archive_created_at": "Archivierungsdatum", "com_nav_archive_created_at": "Archivierungsdatum",
@ -326,6 +330,7 @@
"com_nav_help_faq": "Hilfe & FAQ", "com_nav_help_faq": "Hilfe & FAQ",
"com_nav_hide_panel": "Rechte Seitenleiste verstecken", "com_nav_hide_panel": "Rechte Seitenleiste verstecken",
"com_nav_info_code_artifacts": "Aktiviert die Anzeige experimenteller Code-Artefakte neben dem Chat", "com_nav_info_code_artifacts": "Aktiviert die Anzeige experimenteller Code-Artefakte neben dem Chat",
"com_nav_info_code_artifacts_agent": "Aktiviert die Verwendung von Code-Artefakten für diesen Agenten. Standardmäßig werden zusätzliche, spezielle Anweisungen für die Nutzung von Artefakten hinzugefügt, es sei denn, der \"Benutzerdefinierte Prompt-Modus\" ist aktiviert.",
"com_nav_info_custom_prompt_mode": "Wenn aktiviert, wird die Standard-Systemaufforderung für Artefakte nicht eingeschlossen. Alle Anweisungen zur Erzeugung von Artefakten müssen in diesem Modus manuell bereitgestellt werden.", "com_nav_info_custom_prompt_mode": "Wenn aktiviert, wird die Standard-Systemaufforderung für Artefakte nicht eingeschlossen. Alle Anweisungen zur Erzeugung von Artefakten müssen in diesem Modus manuell bereitgestellt werden.",
"com_nav_info_enter_to_send": "Wenn aktiviert, sendet das Drücken von `ENTER` Ihre Nachricht. Wenn deaktiviert, fügt das Drücken von Enter eine neue Zeile hinzu, und du musst `STRG + ENTER` drücken, um deine Nachricht zu senden.", "com_nav_info_enter_to_send": "Wenn aktiviert, sendet das Drücken von `ENTER` Ihre Nachricht. Wenn deaktiviert, fügt das Drücken von Enter eine neue Zeile hinzu, und du musst `STRG + ENTER` drücken, um deine Nachricht zu senden.",
"com_nav_info_fork_change_default": "`Nur sichtbare Nachrichten` umfasst nur den direkten Pfad zur ausgewählten Nachricht. `Zugehörige Verzweigungen einbeziehen` fügt Verzweigungen entlang des Pfades hinzu. `Alle bis/von hier einbeziehen` umfasst alle verbundenen Nachrichten und Verzweigungen.", "com_nav_info_fork_change_default": "`Nur sichtbare Nachrichten` umfasst nur den direkten Pfad zur ausgewählten Nachricht. `Zugehörige Verzweigungen einbeziehen` fügt Verzweigungen entlang des Pfades hinzu. `Alle bis/von hier einbeziehen` umfasst alle verbundenen Nachrichten und Verzweigungen.",
@ -429,6 +434,16 @@
"com_sidepanel_parameters": "KI-Einstellungen", "com_sidepanel_parameters": "KI-Einstellungen",
"com_sidepanel_select_agent": "Wähle einen Agenten", "com_sidepanel_select_agent": "Wähle einen Agenten",
"com_sidepanel_select_assistant": "Assistenten auswählen", "com_sidepanel_select_assistant": "Assistenten auswählen",
"com_ui_2fa_account_security": "Die Zwei-Faktor-Authentifizierung bietet deinem Konto eine zusätzliche Sicherheitsebene.",
"com_ui_2fa_disable": "2FA deaktivieren",
"com_ui_2fa_disable_error": "Beim Deaktivieren der Zwei-Faktor-Authentifizierung ist ein Fehler aufgetreten.",
"com_ui_2fa_disabled": "2FA wurde deaktiviert.",
"com_ui_2fa_enable": "2FA aktivieren",
"com_ui_2fa_enabled": "2FA wurde aktiviert.",
"com_ui_2fa_generate_error": "Beim Erstellen der Einstellungen für die Zwei-Faktor-Authentifizierung ist ein Fehler aufgetreten.",
"com_ui_2fa_invalid": "Ungültiger Zwei-Faktor-Authentifizierungscode.",
"com_ui_2fa_setup": "2FA einrichten",
"com_ui_2fa_verified": "Die Zwei-Faktor-Authentifizierung wurde erfolgreich verifiziert.",
"com_ui_accept": "Ich akzeptiere", "com_ui_accept": "Ich akzeptiere",
"com_ui_add": "Hinzufügen", "com_ui_add": "Hinzufügen",
"com_ui_add_model_preset": "Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen", "com_ui_add_model_preset": "Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen",
@ -450,12 +465,15 @@
"com_ui_agents_allow_use": "Verwendung von Agenten erlauben", "com_ui_agents_allow_use": "Verwendung von Agenten erlauben",
"com_ui_all": "alle", "com_ui_all": "alle",
"com_ui_all_proper": "Alle", "com_ui_all_proper": "Alle",
"com_ui_analyzing": "Analyse läuft",
"com_ui_analyzing_finished": "Analyse abgeschlossen",
"com_ui_api_key": "API-Schlüssel", "com_ui_api_key": "API-Schlüssel",
"com_ui_archive": "Archivieren", "com_ui_archive": "Archivieren",
"com_ui_archive_error": "Konversation konnte nicht archiviert werden", "com_ui_archive_error": "Konversation konnte nicht archiviert werden",
"com_ui_artifact_click": "Zum Öffnen klicken", "com_ui_artifact_click": "Zum Öffnen klicken",
"com_ui_artifacts": "Artefakte", "com_ui_artifacts": "Artefakte",
"com_ui_artifacts_toggle": "Artefakte-Funktion einschalten", "com_ui_artifacts_toggle": "Artefakte-Funktion einschalten",
"com_ui_artifacts_toggle_agent": "Artefakte aktivieren",
"com_ui_ascending": "Aufsteigend", "com_ui_ascending": "Aufsteigend",
"com_ui_assistant": "Assistent", "com_ui_assistant": "Assistent",
"com_ui_assistant_delete_error": "Beim Löschen des Assistenten ist ein Fehler aufgetreten", "com_ui_assistant_delete_error": "Beim Löschen des Assistenten ist ein Fehler aufgetreten",
@ -473,8 +491,12 @@
"com_ui_authentication": "Authentifizierung", "com_ui_authentication": "Authentifizierung",
"com_ui_authentication_type": "Authentifizierungstyp", "com_ui_authentication_type": "Authentifizierungstyp",
"com_ui_avatar": "Avatar", "com_ui_avatar": "Avatar",
"com_ui_azure": "Azure",
"com_ui_back_to_chat": "Zurück zum Chat", "com_ui_back_to_chat": "Zurück zum Chat",
"com_ui_back_to_prompts": "Zurück zu den Prompts", "com_ui_back_to_prompts": "Zurück zu den Prompts",
"com_ui_backup_codes": "Backup-Codes",
"com_ui_backup_codes_regenerate_error": "Beim Neuerstellen der Backup-Codes ist ein Fehler aufgetreten.",
"com_ui_backup_codes_regenerated": "Backup-Codes wurden erfolgreich neu erstellt.",
"com_ui_basic": "Basic", "com_ui_basic": "Basic",
"com_ui_basic_auth_header": "Basic-Authentifizierungsheader", "com_ui_basic_auth_header": "Basic-Authentifizierungsheader",
"com_ui_bearer": "Bearer", "com_ui_bearer": "Bearer",
@ -510,6 +532,7 @@
"com_ui_collapse_chat": "Chat einklappen", "com_ui_collapse_chat": "Chat einklappen",
"com_ui_command_placeholder": "Optional: Gib einen Promptbefehl ein oder den Namen.", "com_ui_command_placeholder": "Optional: Gib einen Promptbefehl ein oder den Namen.",
"com_ui_command_usage_placeholder": "Wähle einen Prompt nach Befehl oder Name aus", "com_ui_command_usage_placeholder": "Wähle einen Prompt nach Befehl oder Name aus",
"com_ui_complete_setup": "Einrichtung abschließen",
"com_ui_confirm_action": "Aktion bestätigen", "com_ui_confirm_action": "Aktion bestätigen",
"com_ui_confirm_admin_use_change": "Wenn du diese Einstellung änderst, wird der Zugriff für Administratoren, einschließlich dir selbst, gesperrt. Bist du sicher, dass du fortfahren möchtest?", "com_ui_confirm_admin_use_change": "Wenn du diese Einstellung änderst, wird der Zugriff für Administratoren, einschließlich dir selbst, gesperrt. Bist du sicher, dass du fortfahren möchtest?",
"com_ui_confirm_change": "Änderung bestätigen", "com_ui_confirm_change": "Änderung bestätigen",
@ -526,6 +549,7 @@
"com_ui_create_prompt": "Prompt erstellen", "com_ui_create_prompt": "Prompt erstellen",
"com_ui_currently_production": "Aktuell im Produktivbetrieb", "com_ui_currently_production": "Aktuell im Produktivbetrieb",
"com_ui_custom": "Benutzerdefiniert", "com_ui_custom": "Benutzerdefiniert",
"com_ui_custom_header_name": "Benutzerdefinierter Headername",
"com_ui_custom_prompt_mode": "Benutzerdefinierter Promptmodus für Artefakte", "com_ui_custom_prompt_mode": "Benutzerdefinierter Promptmodus für Artefakte",
"com_ui_dashboard": "Dashboard", "com_ui_dashboard": "Dashboard",
"com_ui_date": "Datum", "com_ui_date": "Datum",
@ -546,6 +570,7 @@
"com_ui_date_today": "Heute", "com_ui_date_today": "Heute",
"com_ui_date_yesterday": "Gestern", "com_ui_date_yesterday": "Gestern",
"com_ui_decline": "Ich akzeptiere nicht", "com_ui_decline": "Ich akzeptiere nicht",
"com_ui_default_post_request": "Standard (POST-Anfrage)",
"com_ui_delete": "Löschen", "com_ui_delete": "Löschen",
"com_ui_delete_action": "Aktion löschen", "com_ui_delete_action": "Aktion löschen",
"com_ui_delete_action_confirm": "Bist du sicher, dass du diese Aktion löschen möchtest?", "com_ui_delete_action_confirm": "Bist du sicher, dass du diese Aktion löschen möchtest?",
@ -561,8 +586,11 @@
"com_ui_descending": "Absteigend", "com_ui_descending": "Absteigend",
"com_ui_description": "Beschreibung", "com_ui_description": "Beschreibung",
"com_ui_description_placeholder": "Optional: Gib eine Beschreibung für den Prompt ein", "com_ui_description_placeholder": "Optional: Gib eine Beschreibung für den Prompt ein",
"com_ui_disabling": "Deaktiviere …",
"com_ui_download": "Herunterladen", "com_ui_download": "Herunterladen",
"com_ui_download_artifact": "Artefakt herunterladen", "com_ui_download_artifact": "Artefakt herunterladen",
"com_ui_download_backup": "Backup-Codes herunterladen",
"com_ui_download_backup_tooltip": "Bevor du fortfährst, lade bitte deine Backup-Codes herunter. Du benötigst sie, um den Zugang wiederherzustellen, falls du dein Authentifizierungsgerät verlierst.",
"com_ui_download_error": "Fehler beim Herunterladen der Datei. Die Datei wurde möglicherweise gelöscht.", "com_ui_download_error": "Fehler beim Herunterladen der Datei. Die Datei wurde möglicherweise gelöscht.",
"com_ui_dropdown_variables": "Dropdown-Variablen:", "com_ui_dropdown_variables": "Dropdown-Variablen:",
"com_ui_dropdown_variables_info": "Erstellen Sie benutzerdefinierte Dropdown-Menüs für Ihre Eingabeaufforderungen: `{{variable_name:option1|option2|option3}}`", "com_ui_dropdown_variables_info": "Erstellen Sie benutzerdefinierte Dropdown-Menüs für Ihre Eingabeaufforderungen: `{{variable_name:option1|option2|option3}}`",
@ -586,6 +614,7 @@
"com_ui_field_required": "Dieses Feld ist erforderlich", "com_ui_field_required": "Dieses Feld ist erforderlich",
"com_ui_filter_prompts": "Prompts filtern", "com_ui_filter_prompts": "Prompts filtern",
"com_ui_filter_prompts_name": "Prompts nach Namen filtern", "com_ui_filter_prompts_name": "Prompts nach Namen filtern",
"com_ui_finance": "Finanzen",
"com_ui_fork": "Abzweigen", "com_ui_fork": "Abzweigen",
"com_ui_fork_all_target": "Alle bis/von hier einbeziehen", "com_ui_fork_all_target": "Alle bis/von hier einbeziehen",
"com_ui_fork_branches": "Zugehörige Verzweigungen einbeziehen", "com_ui_fork_branches": "Zugehörige Verzweigungen einbeziehen",
@ -608,17 +637,23 @@
"com_ui_fork_split_target_setting": "Abzweigung standardmäßig von der Zielnachricht beginnen", "com_ui_fork_split_target_setting": "Abzweigung standardmäßig von der Zielnachricht beginnen",
"com_ui_fork_success": "Konversation erfolgreich abgezweigt", "com_ui_fork_success": "Konversation erfolgreich abgezweigt",
"com_ui_fork_visible": "Nur sichtbare Nachrichten", "com_ui_fork_visible": "Nur sichtbare Nachrichten",
"com_ui_generate_backup": "Backup-Codes generieren",
"com_ui_generate_qrcode": "QR-Code generieren",
"com_ui_generating": "Generiere …",
"com_ui_go_back": "Zurück", "com_ui_go_back": "Zurück",
"com_ui_go_to_conversation": "Zur Konversation gehen", "com_ui_go_to_conversation": "Zur Konversation gehen",
"com_ui_happy_birthday": "Es ist mein 1. Geburtstag!", "com_ui_happy_birthday": "Es ist mein 1. Geburtstag!",
"com_ui_hide_qr": "QR-Code ausblenden", "com_ui_hide_qr": "QR-Code ausblenden",
"com_ui_host": "Host", "com_ui_host": "Host",
"com_ui_idea": "Ideen",
"com_ui_image_gen": "Bildgenerierung", "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_error": "Beim Importieren Ihrer Konversationen ist ein Fehler aufgetreten",
"com_ui_import_conversation_file_type_error": "Nicht unterstützter Importtyp", "com_ui_import_conversation_file_type_error": "Nicht unterstützter Importtyp",
"com_ui_import_conversation_info": "Konversationen aus einer JSON-Datei importieren", "com_ui_import_conversation_info": "Konversationen aus einer JSON-Datei importieren",
"com_ui_import_conversation_success": "Konversationen erfolgreich importiert", "com_ui_import_conversation_success": "Konversationen erfolgreich importiert",
"com_ui_include_shadcnui": "Anweisungen für shadcn/ui-Komponenten einschließen", "com_ui_include_shadcnui": "Anweisungen für shadcn/ui-Komponenten einschließen",
"com_ui_include_shadcnui_agent": "shadcn/ui-Anweisungen einfügen",
"com_ui_input": "Eingabe", "com_ui_input": "Eingabe",
"com_ui_instructions": "Anweisungen", "com_ui_instructions": "Anweisungen",
"com_ui_latest_footer": "Alle KIs für alle.", "com_ui_latest_footer": "Alle KIs für alle.",
@ -629,12 +664,14 @@
"com_ui_librechat_code_api_title": "KI-Code ausführen", "com_ui_librechat_code_api_title": "KI-Code ausführen",
"com_ui_llm_menu": "LLM-Menü", "com_ui_llm_menu": "LLM-Menü",
"com_ui_llms_available": "Verfügbare LLMs", "com_ui_llms_available": "Verfügbare LLMs",
"com_ui_loading": "Lade …",
"com_ui_locked": "Gesperrt", "com_ui_locked": "Gesperrt",
"com_ui_logo": "{{0}} Logo", "com_ui_logo": "{{0}} Logo",
"com_ui_manage": "Verwalten", "com_ui_manage": "Verwalten",
"com_ui_max_tags": "Die maximale Anzahl ist {{0}}, es werden die neuesten Werte verwendet.", "com_ui_max_tags": "Die maximale Anzahl ist {{0}}, es werden die neuesten Werte verwendet.",
"com_ui_mention": "Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln", "com_ui_mention": "Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln",
"com_ui_min_tags": "Es können nicht mehr Werte entfernt werden, mindestens {{0}} sind erforderlich.", "com_ui_min_tags": "Es können nicht mehr Werte entfernt werden, mindestens {{0}} sind erforderlich.",
"com_ui_misc": "Verschiedenes",
"com_ui_model": "KI-Modell", "com_ui_model": "KI-Modell",
"com_ui_model_parameters": "Modell-Parameter", "com_ui_model_parameters": "Modell-Parameter",
"com_ui_more_info": "Mehr Infos", "com_ui_more_info": "Mehr Infos",
@ -643,17 +680,20 @@
"com_ui_new_chat": "Neuer Chat", "com_ui_new_chat": "Neuer Chat",
"com_ui_next": "Weiter", "com_ui_next": "Weiter",
"com_ui_no": "Nein", "com_ui_no": "Nein",
"com_ui_no_backup_codes": "Keine Backup-Codes verfügbar. Bitte erstelle neue.",
"com_ui_no_bookmarks": "Du hast noch keine Lesezeichen. Klicke auf einen Chat und füge ein neues hinzu", "com_ui_no_bookmarks": "Du hast noch keine Lesezeichen. Klicke auf einen Chat und füge ein neues hinzu",
"com_ui_no_category": "Keine Kategorie", "com_ui_no_category": "Keine Kategorie",
"com_ui_no_changes": "Keine Änderungen zum Aktualisieren", "com_ui_no_changes": "Keine Änderungen zum Aktualisieren",
"com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen", "com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen",
"com_ui_none": "Keine", "com_ui_none": "Keine",
"com_ui_none_selected": "Nichts ausgewählt", "com_ui_none_selected": "Nichts ausgewählt",
"com_ui_not_used": "Nicht verwendet",
"com_ui_nothing_found": "Nichts gefunden", "com_ui_nothing_found": "Nichts gefunden",
"com_ui_oauth": "OAuth", "com_ui_oauth": "OAuth",
"com_ui_of": "von", "com_ui_of": "von",
"com_ui_off": "Aus", "com_ui_off": "Aus",
"com_ui_on": "An", "com_ui_on": "An",
"com_ui_openai": "OpenAI",
"com_ui_page": "Seite", "com_ui_page": "Seite",
"com_ui_prev": "Zurück", "com_ui_prev": "Zurück",
"com_ui_preview": "Vorschau", "com_ui_preview": "Vorschau",
@ -675,6 +715,8 @@
"com_ui_read_aloud": "Vorlesen", "com_ui_read_aloud": "Vorlesen",
"com_ui_refresh_link": "Link aktualisieren", "com_ui_refresh_link": "Link aktualisieren",
"com_ui_regenerate": "Neu generieren", "com_ui_regenerate": "Neu generieren",
"com_ui_regenerate_backup": "Backup-Codes neu generieren",
"com_ui_regenerating": "Generiere neu ...",
"com_ui_region": "Region", "com_ui_region": "Region",
"com_ui_rename": "Umbenennen", "com_ui_rename": "Umbenennen",
"com_ui_rename_prompt": "Prompt umbenennen", "com_ui_rename_prompt": "Prompt umbenennen",
@ -688,13 +730,16 @@
"com_ui_revoke_keys": "Schlüssel widerrufen", "com_ui_revoke_keys": "Schlüssel widerrufen",
"com_ui_revoke_keys_confirm": "Bist du sicher, dass du alle Schlüssel widerrufen möchtest?", "com_ui_revoke_keys_confirm": "Bist du sicher, dass du alle Schlüssel widerrufen möchtest?",
"com_ui_role_select": "Rolle auswählen", "com_ui_role_select": "Rolle auswählen",
"com_ui_roleplay": "Rollenspiel",
"com_ui_run_code": "Code ausführen", "com_ui_run_code": "Code ausführen",
"com_ui_run_code_error": "Bei der Ausführung des Codes ist ein Fehler aufgetreten", "com_ui_run_code_error": "Bei der Ausführung des Codes ist ein Fehler aufgetreten",
"com_ui_save": "Speichern", "com_ui_save": "Speichern",
"com_ui_save_submit": "Speichern & Absenden", "com_ui_save_submit": "Speichern & Absenden",
"com_ui_saved": "Gespeichert!", "com_ui_saved": "Gespeichert!",
"com_ui_schema": "Schema", "com_ui_schema": "Schema",
"com_ui_scope": "Umfang",
"com_ui_search": "Suche", "com_ui_search": "Suche",
"com_ui_secret_key": "Geheimschlüssel",
"com_ui_select": "Auswählen", "com_ui_select": "Auswählen",
"com_ui_select_file": "Datei auswählen", "com_ui_select_file": "Datei auswählen",
"com_ui_select_model": "Ein KI-Modell auswählen", "com_ui_select_model": "Ein KI-Modell auswählen",
@ -717,6 +762,8 @@
"com_ui_shared_link_delete_success": "Geteilter Link erfolgreich gelöscht", "com_ui_shared_link_delete_success": "Geteilter Link erfolgreich gelöscht",
"com_ui_shared_link_not_found": "Geteilter Link nicht gefunden", "com_ui_shared_link_not_found": "Geteilter Link nicht gefunden",
"com_ui_shared_prompts": "Geteilte Prompts", "com_ui_shared_prompts": "Geteilte Prompts",
"com_ui_shop": "Einkaufen",
"com_ui_show": "Anzeigen",
"com_ui_show_all": "Alle anzeigen", "com_ui_show_all": "Alle anzeigen",
"com_ui_show_qr": "QR-Code anzeigen", "com_ui_show_qr": "QR-Code anzeigen",
"com_ui_sign_in_to_domain": "Anmelden bei {{0}}", "com_ui_sign_in_to_domain": "Anmelden bei {{0}}",
@ -728,6 +775,7 @@
"com_ui_stop": "Stopp", "com_ui_stop": "Stopp",
"com_ui_storage": "Speicher", "com_ui_storage": "Speicher",
"com_ui_submit": "Absenden", "com_ui_submit": "Absenden",
"com_ui_teach_or_explain": "Lernen",
"com_ui_temporary_chat": "Temporärer Chat", "com_ui_temporary_chat": "Temporärer Chat",
"com_ui_terms_and_conditions": "Allgemeine Geschäftsbedingungen", "com_ui_terms_and_conditions": "Allgemeine Geschäftsbedingungen",
"com_ui_terms_of_service": "Nutzungsbedingungen", "com_ui_terms_of_service": "Nutzungsbedingungen",
@ -736,6 +784,7 @@
"com_ui_token_exchange_method": "Token-Austauschmethode", "com_ui_token_exchange_method": "Token-Austauschmethode",
"com_ui_token_url": "Token-URL", "com_ui_token_url": "Token-URL",
"com_ui_tools": "Werkzeuge", "com_ui_tools": "Werkzeuge",
"com_ui_travel": "Reisen",
"com_ui_unarchive": "Aus Archiv holen", "com_ui_unarchive": "Aus Archiv holen",
"com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden", "com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden",
"com_ui_unknown": "Unbekannt", "com_ui_unknown": "Unbekannt",
@ -752,13 +801,18 @@
"com_ui_upload_invalid_var": "Ungültige Datei zum Hochladen. Muss ein Bild sein und {{0}} MB nicht überschreiten", "com_ui_upload_invalid_var": "Ungültige Datei zum Hochladen. Muss ein Bild sein und {{0}} MB nicht überschreiten",
"com_ui_upload_success": "Datei erfolgreich hochgeladen", "com_ui_upload_success": "Datei erfolgreich hochgeladen",
"com_ui_upload_type": "Upload-Typ auswählen", "com_ui_upload_type": "Upload-Typ auswählen",
"com_ui_use_2fa_code": "Stattdessen 2FA-Code verwenden",
"com_ui_use_backup_code": "Stattdessen Backup-Code verwenden",
"com_ui_use_micrphone": "Mikrofon verwenden", "com_ui_use_micrphone": "Mikrofon verwenden",
"com_ui_use_prompt": "Prompt verwenden", "com_ui_use_prompt": "Prompt verwenden",
"com_ui_used": "Verwendet",
"com_ui_variables": "Variablen", "com_ui_variables": "Variablen",
"com_ui_variables_info": "Verwende doppelte geschweifte Klammern in Ihrem Text, um Variablen zu erstellen, z.B. {{Beispielvariable}}, die du später beim Verwenden des Prompts ausfüllen kannst.", "com_ui_variables_info": "Verwende doppelte geschweifte Klammern in Ihrem Text, um Variablen zu erstellen, z.B. {{Beispielvariable}}, die du später beim Verwenden des Prompts ausfüllen kannst.",
"com_ui_verify": "Überprüfen",
"com_ui_version_var": "Version {{0}}", "com_ui_version_var": "Version {{0}}",
"com_ui_versions": "Versionen", "com_ui_versions": "Versionen",
"com_ui_view_source": "Quell-Chat anzeigen", "com_ui_view_source": "Quell-Chat anzeigen",
"com_ui_write": "Schreiben",
"com_ui_yes": "Ja", "com_ui_yes": "Ja",
"com_ui_zoom": "Zoom", "com_ui_zoom": "Zoom",
"com_user_message": "Du", "com_user_message": "Du",

View file

@ -685,6 +685,7 @@
"com_ui_more_info": "More info", "com_ui_more_info": "More info",
"com_ui_my_prompts": "My Prompts", "com_ui_my_prompts": "My Prompts",
"com_ui_name": "Name", "com_ui_name": "Name",
"com_ui_new": "New",
"com_ui_new_chat": "New chat", "com_ui_new_chat": "New chat",
"com_ui_next": "Next", "com_ui_next": "Next",
"com_ui_no": "No", "com_ui_no": "No",

View file

@ -1,6 +1,6 @@
{ {
"chat_direction_left_to_right": "midagi peaks siia minema. Oli tühi", "chat_direction_left_to_right": "Joonda vestlus vasakult paremale.",
"chat_direction_right_to_left": "midagi peaks siia minema. Oli tühi", "chat_direction_right_to_left": "Joonda vestlus paremalt vasakule.",
"com_a11y_ai_composing": "AI genereerib vastust.", "com_a11y_ai_composing": "AI genereerib vastust.",
"com_a11y_end": "AI on oma vastuse lõpetanud.", "com_a11y_end": "AI on oma vastuse lõpetanud.",
"com_a11y_start": "AI on oma vastuse andmise alustanud.", "com_a11y_start": "AI on oma vastuse andmise alustanud.",
@ -214,7 +214,7 @@
"com_endpoint_plug_use_functions": "Kasuta funktsioone", "com_endpoint_plug_use_functions": "Kasuta funktsioone",
"com_endpoint_presence_penalty": "Olekukaristus", "com_endpoint_presence_penalty": "Olekukaristus",
"com_endpoint_preset": "eelseadistus", "com_endpoint_preset": "eelseadistus",
"com_endpoint_preset_custom_name_placeholder": "midagi peaks siia minema. Oli tühi", "com_endpoint_preset_custom_name_placeholder": "Otspunkti kohandatud nimi.",
"com_endpoint_preset_default": "on nüüd vaike-eelseadistus.", "com_endpoint_preset_default": "on nüüd vaike-eelseadistus.",
"com_endpoint_preset_default_item": "Vaikimisi:", "com_endpoint_preset_default_item": "Vaikimisi:",
"com_endpoint_preset_default_none": "Vaikimisi eelseadistus pole aktiivne.", "com_endpoint_preset_default_none": "Vaikimisi eelseadistus pole aktiivne.",
@ -262,7 +262,7 @@
"com_files_filter": "Filtreeri faile...", "com_files_filter": "Filtreeri faile...",
"com_files_no_results": "Tulemusi pole.", "com_files_no_results": "Tulemusi pole.",
"com_files_number_selected": "{{0}} / {{1}} üksust valitud", "com_files_number_selected": "{{0}} / {{1}} üksust valitud",
"com_files_table": "Mmdagi peaks siia minema. Oli tühi", "com_files_table": "Failide tabel",
"com_generated_files": "Genereeritud failid:", "com_generated_files": "Genereeritud failid:",
"com_hide_examples": "Peida näited", "com_hide_examples": "Peida näited",
"com_nav_account_settings": "Konto seaded", "com_nav_account_settings": "Konto seaded",
@ -448,7 +448,7 @@
"com_ui_agent_duplicate_error": "Agendi dubleerimisel tekkis viga", "com_ui_agent_duplicate_error": "Agendi dubleerimisel tekkis viga",
"com_ui_agent_duplicated": "Agendi dubleerimine õnnestus", "com_ui_agent_duplicated": "Agendi dubleerimine õnnestus",
"com_ui_agent_editing_allowed": "Teised kasutajad saavad seda agenti juba muuta", "com_ui_agent_editing_allowed": "Teised kasutajad saavad seda agenti juba muuta",
"com_ui_agent_shared_to_all": "Mmdagi peaks siia minema. Oli tühi", "com_ui_agent_shared_to_all": "Seda agenti on jagatud kõigi kasutajatega",
"com_ui_agents": "Agendid", "com_ui_agents": "Agendid",
"com_ui_agents_allow_create": "Luba agentide loomine", "com_ui_agents_allow_create": "Luba agentide loomine",
"com_ui_agents_allow_share_global": "Luba agentide jagamine kõigile kasutajatele", "com_ui_agents_allow_share_global": "Luba agentide jagamine kõigile kasutajatele",
@ -576,7 +576,7 @@
"com_ui_download": "Laadi alla", "com_ui_download": "Laadi alla",
"com_ui_download_artifact": "Laadi artefakt alla", "com_ui_download_artifact": "Laadi artefakt alla",
"com_ui_download_error": "Viga faili allalaadimisel. Fail võib olla kustutatud.", "com_ui_download_error": "Viga faili allalaadimisel. Fail võib olla kustutatud.",
"com_ui_drag_drop": "Midagi peaks siia minema. Oli tühi", "com_ui_drag_drop": "Lohistage",
"com_ui_dropdown_variables": "Rippmenüü muutujad:", "com_ui_dropdown_variables": "Rippmenüü muutujad:",
"com_ui_dropdown_variables_info": "Loo sisendite jaoks kohandatud rippmenüüd: `{{muutuja_nimi:valik1|valik2|valik3}}`", "com_ui_dropdown_variables_info": "Loo sisendite jaoks kohandatud rippmenüüd: `{{muutuja_nimi:valik1|valik2|valik3}}`",
"com_ui_duplicate": "Dubleeri", "com_ui_duplicate": "Dubleeri",
@ -584,6 +584,7 @@
"com_ui_duplication_processing": "Vestlust dubleeritakse...", "com_ui_duplication_processing": "Vestlust dubleeritakse...",
"com_ui_duplication_success": "Vestluse dubleerimine õnnestus", "com_ui_duplication_success": "Vestluse dubleerimine õnnestus",
"com_ui_edit": "Muuda", "com_ui_edit": "Muuda",
"com_ui_empty_category": "-",
"com_ui_endpoint": "Otspunkt", "com_ui_endpoint": "Otspunkt",
"com_ui_endpoint_menu": "LLM otspunkti menüü", "com_ui_endpoint_menu": "LLM otspunkti menüü",
"com_ui_endpoints_available": "Saadaolevad otspunktid", "com_ui_endpoints_available": "Saadaolevad otspunktid",
@ -599,6 +600,7 @@
"com_ui_field_required": "See väli on kohustuslik", "com_ui_field_required": "See väli on kohustuslik",
"com_ui_filter_prompts": "Filtreeri sisendid", "com_ui_filter_prompts": "Filtreeri sisendid",
"com_ui_filter_prompts_name": "Filtreeri sisendeid nime järgi", "com_ui_filter_prompts_name": "Filtreeri sisendeid nime järgi",
"com_ui_finance": "Raha",
"com_ui_fork": "Hargne", "com_ui_fork": "Hargne",
"com_ui_fork_all_target": "Kaasa kõik siia/siit", "com_ui_fork_all_target": "Kaasa kõik siia/siit",
"com_ui_fork_branches": "Kaasa seotud harud", "com_ui_fork_branches": "Kaasa seotud harud",
@ -621,12 +623,13 @@
"com_ui_fork_split_target_setting": "Alusta vaikimisi sihtsõnumist hargnemist", "com_ui_fork_split_target_setting": "Alusta vaikimisi sihtsõnumist hargnemist",
"com_ui_fork_success": "Vestluse hargnemine õnnestus", "com_ui_fork_success": "Vestluse hargnemine õnnestus",
"com_ui_fork_visible": "Ainult nähtavad sõnumid", "com_ui_fork_visible": "Ainult nähtavad sõnumid",
"com_ui_global_group": "Midagi peaks siia minema. Oli tühi", "com_ui_global_group": "Ülene grupp",
"com_ui_go_back": "Mine tagasi", "com_ui_go_back": "Mine tagasi",
"com_ui_go_to_conversation": "Mine vestlusesse", "com_ui_go_to_conversation": "Mine vestlusesse",
"com_ui_happy_birthday": "Mul on 1. sünnipäev!", "com_ui_happy_birthday": "Mul on 1. sünnipäev!",
"com_ui_hide_qr": "Peida QR-kood", "com_ui_hide_qr": "Peida QR-kood",
"com_ui_host": "Host", "com_ui_host": "Host",
"com_ui_idea": "Ideed",
"com_ui_image_gen": "Pildi genereerimine", "com_ui_image_gen": "Pildi genereerimine",
"com_ui_import_conversation_error": "Vestluste importimisel tekkis viga", "com_ui_import_conversation_error": "Vestluste importimisel tekkis viga",
"com_ui_import_conversation_file_type_error": "Toetamatu imporditüüp", "com_ui_import_conversation_file_type_error": "Toetamatu imporditüüp",
@ -644,12 +647,14 @@
"com_ui_librechat_code_api_title": "Käivita AI koodi", "com_ui_librechat_code_api_title": "Käivita AI koodi",
"com_ui_llm_menu": "LLM menüü", "com_ui_llm_menu": "LLM menüü",
"com_ui_llms_available": "Saadaolevad LLM-id", "com_ui_llms_available": "Saadaolevad LLM-id",
"com_ui_loading": "Laeb...",
"com_ui_locked": "Lukus", "com_ui_locked": "Lukus",
"com_ui_logo": "{{0}} logo", "com_ui_logo": "{{0}} logo",
"com_ui_manage": "Halda", "com_ui_manage": "Halda",
"com_ui_max_tags": "Maksimaalne lubatud arv on {{0}}, kasutades viimaseid väärtusi.", "com_ui_max_tags": "Maksimaalne lubatud arv on {{0}}, kasutades viimaseid väärtusi.",
"com_ui_mention": "Maini otspunkti, assistenti või eelseadistust, et sellele kiiresti üle minna", "com_ui_mention": "Maini otspunkti, assistenti või eelseadistust, et sellele kiiresti üle minna",
"com_ui_min_tags": "Rohkem väärtusi ei saa eemaldada, vaja on vähemalt {{0}}.", "com_ui_min_tags": "Rohkem väärtusi ei saa eemaldada, vaja on vähemalt {{0}}.",
"com_ui_misc": "Muu",
"com_ui_model": "Mudel", "com_ui_model": "Mudel",
"com_ui_model_parameters": "Mudeli parameetrid", "com_ui_model_parameters": "Mudeli parameetrid",
"com_ui_more_info": "Rohkem infot", "com_ui_more_info": "Rohkem infot",
@ -661,9 +666,9 @@
"com_ui_no_bookmarks": "Tundub, et sul pole veel järjehoidjaid. Klõpsa vestlusele ja lisa uus", "com_ui_no_bookmarks": "Tundub, et sul pole veel järjehoidjaid. Klõpsa vestlusele ja lisa uus",
"com_ui_no_category": "Kategooriat pole", "com_ui_no_category": "Kategooriat pole",
"com_ui_no_changes": "Uuendamiseks pole muudatusi", "com_ui_no_changes": "Uuendamiseks pole muudatusi",
"com_ui_no_data": "midagi peaks siia minema. Oli tühi", "com_ui_no_data": "Andmed puuduvad!",
"com_ui_no_terms_content": "Kuvamiseks puudub kasutustingimuste sisu", "com_ui_no_terms_content": "Kuvamiseks puudub kasutustingimuste sisu",
"com_ui_no_valid_items": "midagi peaks siia minema. Oli tühi", "com_ui_no_valid_items": "Sobivad üksused puuduvad!",
"com_ui_none": "Puudub", "com_ui_none": "Puudub",
"com_ui_none_selected": "Ühtegi pole valitud", "com_ui_none_selected": "Ühtegi pole valitud",
"com_ui_nothing_found": "Midagi ei leitud", "com_ui_nothing_found": "Midagi ei leitud",
@ -706,6 +711,7 @@
"com_ui_revoke_keys": "Tühista võtmed", "com_ui_revoke_keys": "Tühista võtmed",
"com_ui_revoke_keys_confirm": "Oled sa kindel, et sa soovid kõik võtmed tühistada?", "com_ui_revoke_keys_confirm": "Oled sa kindel, et sa soovid kõik võtmed tühistada?",
"com_ui_role_select": "Roll", "com_ui_role_select": "Roll",
"com_ui_roleplay": "Rollimäng",
"com_ui_run_code": "Käivita kood", "com_ui_run_code": "Käivita kood",
"com_ui_run_code_error": "Koodi käivitamisel tekkis viga", "com_ui_run_code_error": "Koodi käivitamisel tekkis viga",
"com_ui_save": "Salvesta", "com_ui_save": "Salvesta",
@ -728,7 +734,7 @@
"com_ui_share_create_message": "Sinu nimi ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.", "com_ui_share_create_message": "Sinu nimi ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.",
"com_ui_share_delete_error": "Jagatud lingi kustutamisel tekkis viga", "com_ui_share_delete_error": "Jagatud lingi kustutamisel tekkis viga",
"com_ui_share_error": "Vestluslingi jagamisel tekkis viga", "com_ui_share_error": "Vestluslingi jagamisel tekkis viga",
"com_ui_share_form_description": "Midagi peaks siia minema. Oli tühi", "com_ui_share_form_description": "Jaga kasutamist.",
"com_ui_share_link_to_chat": "Jaga linki vestlusele", "com_ui_share_link_to_chat": "Jaga linki vestlusele",
"com_ui_share_to_all_users": "Jaga kõigile kasutajatele", "com_ui_share_to_all_users": "Jaga kõigile kasutajatele",
"com_ui_share_update_message": "Sinu nimi, kohandatud juhised ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.", "com_ui_share_update_message": "Sinu nimi, kohandatud juhised ja kõik sõnumid, mille sa pärast jagamist lisad, jäävad privaatseks.",
@ -737,6 +743,7 @@
"com_ui_shared_link_delete_success": "Jagatud lingi kustutamine õnnestus", "com_ui_shared_link_delete_success": "Jagatud lingi kustutamine õnnestus",
"com_ui_shared_link_not_found": "Jagatud linki ei leitud", "com_ui_shared_link_not_found": "Jagatud linki ei leitud",
"com_ui_shared_prompts": "Jagatud sisendid", "com_ui_shared_prompts": "Jagatud sisendid",
"com_ui_shop": "Ostlemine",
"com_ui_show_all": "Näita kõiki", "com_ui_show_all": "Näita kõiki",
"com_ui_show_qr": "Näita QR-koodi", "com_ui_show_qr": "Näita QR-koodi",
"com_ui_sign_in_to_domain": "Logi sisse {{0}}", "com_ui_sign_in_to_domain": "Logi sisse {{0}}",
@ -748,6 +755,7 @@
"com_ui_stop": "Peata", "com_ui_stop": "Peata",
"com_ui_storage": "Salvestusruum", "com_ui_storage": "Salvestusruum",
"com_ui_submit": "Esita", "com_ui_submit": "Esita",
"com_ui_teach_or_explain": "Õppimine",
"com_ui_temporary_chat": "Ajutine vestlus", "com_ui_temporary_chat": "Ajutine vestlus",
"com_ui_terms_and_conditions": "Kasutustingimused", "com_ui_terms_and_conditions": "Kasutustingimused",
"com_ui_terms_of_service": "Teenuse tingimused", "com_ui_terms_of_service": "Teenuse tingimused",
@ -756,6 +764,7 @@
"com_ui_token_exchange_method": "Märgi vahetamise meetod", "com_ui_token_exchange_method": "Märgi vahetamise meetod",
"com_ui_token_url": "Märgi URL", "com_ui_token_url": "Märgi URL",
"com_ui_tools": "Tööriistad", "com_ui_tools": "Tööriistad",
"com_ui_travel": "Reisimine",
"com_ui_unarchive": "Arhiveeri lahti", "com_ui_unarchive": "Arhiveeri lahti",
"com_ui_unarchive_error": "Vestluse arhiveerimine lahti ebaõnnestus", "com_ui_unarchive_error": "Vestluse arhiveerimine lahti ebaõnnestus",
"com_ui_unknown": "Tundmatu", "com_ui_unknown": "Tundmatu",
@ -779,6 +788,7 @@
"com_ui_version_var": "Versioon {{0}}", "com_ui_version_var": "Versioon {{0}}",
"com_ui_versions": "Versioonid", "com_ui_versions": "Versioonid",
"com_ui_view_source": "Vaata algset vestlust", "com_ui_view_source": "Vaata algset vestlust",
"com_ui_write": "Kirjutamine",
"com_ui_yes": "Jah", "com_ui_yes": "Jah",
"com_ui_zoom": "Suumi", "com_ui_zoom": "Suumi",
"com_user_message": "Sina", "com_user_message": "Sina",

View file

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

20
package-lock.json generated
View file

@ -1095,7 +1095,7 @@
"react-i18next": "^15.4.0", "react-i18next": "^15.4.0",
"react-lazy-load-image-component": "^1.6.0", "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1", "react-markdown": "^9.0.1",
"react-resizable-panels": "^2.1.1", "react-resizable-panels": "^2.1.7",
"react-router-dom": "^6.11.2", "react-router-dom": "^6.11.2",
"react-speech-recognition": "^3.10.0", "react-speech-recognition": "^3.10.0",
"react-textarea-autosize": "^8.4.0", "react-textarea-autosize": "^8.4.0",
@ -1609,6 +1609,15 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}, },
"client/node_modules/react-resizable-panels": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.7.tgz",
"integrity": "sha512-JtT6gI+nURzhMYQYsx8DKkx6bSoOGFp7A3CwMrOb8y5jFHFyqwo9m68UhmXRw57fRVJksFn1TSlm3ywEQ9vMgA==",
"peerDependencies": {
"react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc",
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
}
},
"client/node_modules/rollup": { "client/node_modules/rollup": {
"version": "4.34.6", "version": "4.34.6",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz",
@ -31919,15 +31928,6 @@
} }
} }
}, },
"node_modules/react-resizable-panels": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.1.tgz",
"integrity": "sha512-+cUV/yZBYfiBj+WJtpWDJ3NtR4zgDZfHt3+xtaETKE+FCvp+RK/NJxacDQKxMHgRUTSkfA6AnGljQ5QZNsCQoA==",
"peerDependencies": {
"react": "^16.14.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-router": { "node_modules/react-router": {
"version": "6.22.0", "version": "6.22.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.0.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.0.tgz",