mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-25 03:36:12 +01:00
Merge branch 'main' into feat/user-groups
This commit is contained in:
commit
0cdccb617c
34 changed files with 1016 additions and 369 deletions
22
.env.example
22
.env.example
|
|
@ -20,6 +20,11 @@ DOMAIN_CLIENT=http://localhost:3080
|
|||
DOMAIN_SERVER=http://localhost:3080
|
||||
|
||||
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 #
|
||||
|
|
@ -292,6 +297,10 @@ MEILI_NO_ANALYTICS=true
|
|||
MEILI_HOST=http://0.0.0.0:7700
|
||||
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 #
|
||||
#==================================================#
|
||||
|
|
@ -495,6 +504,16 @@ HELP_AND_FAQ_URL=https://librechat.ai
|
|||
# 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 #
|
||||
#==================================================#
|
||||
|
|
@ -502,9 +521,6 @@ HELP_AND_FAQ_URL=https://librechat.ai
|
|||
|
||||
# NODE_ENV=
|
||||
|
||||
# REDIS_URI=
|
||||
# USE_REDIS=
|
||||
|
||||
# E2E_USER_EMAIL=
|
||||
# E2E_USER_PASSWORD=
|
||||
|
||||
|
|
|
|||
50
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
50
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
|
|
@ -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
|
||||
|
|
@ -51,7 +51,7 @@ class GoogleClient extends BaseClient {
|
|||
|
||||
const serviceKey = creds[AuthKeys.GOOGLE_SERVICE_KEY] ?? {};
|
||||
this.serviceKey =
|
||||
serviceKey && typeof serviceKey === 'string' ? JSON.parse(serviceKey) : serviceKey ?? {};
|
||||
serviceKey && typeof serviceKey === 'string' ? JSON.parse(serviceKey) : (serviceKey ?? {});
|
||||
/** @type {string | null | undefined} */
|
||||
this.project_id = this.serviceKey.project_id;
|
||||
this.client_email = this.serviceKey.client_email;
|
||||
|
|
@ -73,6 +73,8 @@ class GoogleClient extends BaseClient {
|
|||
* @type {string} */
|
||||
this.outputTokensKey = 'output_tokens';
|
||||
this.visionMode = VisionModes.generative;
|
||||
/** @type {string} */
|
||||
this.systemMessage;
|
||||
if (options.skipSetOptions) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -184,7 +186,7 @@ class GoogleClient extends BaseClient {
|
|||
if (typeof this.options.artifactsPrompt === 'string' && this.options.artifactsPrompt) {
|
||||
promptPrefix = `${promptPrefix ?? ''}\n${this.options.artifactsPrompt}`.trim();
|
||||
}
|
||||
this.options.promptPrefix = promptPrefix;
|
||||
this.systemMessage = promptPrefix;
|
||||
this.initializeClient();
|
||||
return this;
|
||||
}
|
||||
|
|
@ -314,7 +316,7 @@ class GoogleClient extends BaseClient {
|
|||
}
|
||||
|
||||
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.');
|
||||
}
|
||||
|
||||
if (this.options.promptPrefix) {
|
||||
const instructionsTokenCount = this.getTokenCount(this.options.promptPrefix);
|
||||
if (this.systemMessage) {
|
||||
const instructionsTokenCount = this.getTokenCount(this.systemMessage);
|
||||
|
||||
this.maxContextTokens = this.maxContextTokens - instructionsTokenCount;
|
||||
if (this.maxContextTokens < 0) {
|
||||
|
|
@ -417,8 +419,8 @@ class GoogleClient extends BaseClient {
|
|||
],
|
||||
};
|
||||
|
||||
if (this.options.promptPrefix) {
|
||||
payload.instances[0].context = this.options.promptPrefix;
|
||||
if (this.systemMessage) {
|
||||
payload.instances[0].context = this.systemMessage;
|
||||
}
|
||||
|
||||
logger.debug('[GoogleClient] buildMessages', payload);
|
||||
|
|
@ -464,7 +466,7 @@ class GoogleClient extends BaseClient {
|
|||
identityPrefix = `${identityPrefix}\nYou are ${this.options.modelLabel}`;
|
||||
}
|
||||
|
||||
let promptPrefix = (this.options.promptPrefix ?? '').trim();
|
||||
let promptPrefix = (this.systemMessage ?? '').trim();
|
||||
|
||||
if (identityPrefix) {
|
||||
promptPrefix = `${identityPrefix}${promptPrefix}`;
|
||||
|
|
@ -639,7 +641,7 @@ class GoogleClient extends BaseClient {
|
|||
let error;
|
||||
try {
|
||||
if (!EXCLUDED_GENAI_MODELS.test(modelName) && !this.project_id) {
|
||||
/** @type {GenAI} */
|
||||
/** @type {GenerativeModel} */
|
||||
const client = this.client;
|
||||
/** @type {GenerateContentRequest} */
|
||||
const requestOptions = {
|
||||
|
|
@ -648,7 +650,7 @@ class GoogleClient extends BaseClient {
|
|||
generationConfig: googleGenConfigSchema.parse(this.modelOptions),
|
||||
};
|
||||
|
||||
const promptPrefix = (this.options.promptPrefix ?? '').trim();
|
||||
const promptPrefix = (this.systemMessage ?? '').trim();
|
||||
if (promptPrefix.length) {
|
||||
requestOptions.systemInstruction = {
|
||||
parts: [
|
||||
|
|
@ -663,7 +665,17 @@ class GoogleClient extends BaseClient {
|
|||
/** @type {GenAIUsageMetadata} */
|
||||
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) {
|
||||
usageMetadata = !usageMetadata
|
||||
? chunk?.usageMetadata
|
||||
|
|
|
|||
72
api/cache/keyvRedis.js
vendored
72
api/cache/keyvRedis.js
vendored
|
|
@ -1,15 +1,81 @@
|
|||
const fs = require('fs');
|
||||
const ioredis = require('ioredis');
|
||||
const KeyvRedis = require('@keyv/redis');
|
||||
const { isEnabled } = require('~/server/utils');
|
||||
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;
|
||||
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)) {
|
||||
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.setMaxListeners(20);
|
||||
keyvRedis.setMaxListeners(redis_max_listeners);
|
||||
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.',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
const { MeiliSearch } = require('meilisearch');
|
||||
const Conversation = require('~/models/schema/convoSchema');
|
||||
const Message = require('~/models/schema/messageSchema');
|
||||
const { isEnabled } = require('~/server/utils');
|
||||
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;
|
||||
|
||||
class MeiliSearchClient {
|
||||
|
|
@ -23,8 +25,7 @@ class MeiliSearchClient {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async function indexSync(req, res, next) {
|
||||
async function indexSync() {
|
||||
if (!searchEnabled) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -33,10 +34,15 @@ async function indexSync(req, res, next) {
|
|||
const client = MeiliSearchClient.getInstance();
|
||||
|
||||
const { status } = await client.health();
|
||||
if (status !== 'available' || !process.env.SEARCH) {
|
||||
if (status !== 'available') {
|
||||
throw new Error('Meilisearch not available');
|
||||
}
|
||||
|
||||
if (indexingDisabled === true) {
|
||||
logger.info('[indexSync] Indexing is disabled, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
const messageCount = await Message.countDocuments();
|
||||
const convoCount = await Conversation.countDocuments();
|
||||
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.');
|
||||
} else {
|
||||
logger.error('[indexSync] error', err);
|
||||
// res.status(500).json({ error: 'Server error' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,40 +3,40 @@ const { logger } = require('~/config');
|
|||
|
||||
const options = [
|
||||
{
|
||||
label: 'idea',
|
||||
value: 'com_ui_idea',
|
||||
label: 'com_ui_idea',
|
||||
value: 'idea',
|
||||
},
|
||||
{
|
||||
label: 'travel',
|
||||
value: 'com_ui_travel',
|
||||
label: 'com_ui_travel',
|
||||
value: 'travel',
|
||||
},
|
||||
{
|
||||
label: 'teach_or_explain',
|
||||
value: 'com_ui_teach_or_explain',
|
||||
label: 'com_ui_teach_or_explain',
|
||||
value: 'teach_or_explain',
|
||||
},
|
||||
{
|
||||
label: 'write',
|
||||
value: 'com_ui_write',
|
||||
label: 'com_ui_write',
|
||||
value: 'write',
|
||||
},
|
||||
{
|
||||
label: 'shop',
|
||||
value: 'com_ui_shop',
|
||||
label: 'com_ui_shop',
|
||||
value: 'shop',
|
||||
},
|
||||
{
|
||||
label: 'code',
|
||||
value: 'com_ui_code',
|
||||
label: 'com_ui_code',
|
||||
value: 'code',
|
||||
},
|
||||
{
|
||||
label: 'misc',
|
||||
value: 'com_ui_misc',
|
||||
label: 'com_ui_misc',
|
||||
value: 'misc',
|
||||
},
|
||||
{
|
||||
label: 'roleplay',
|
||||
value: 'com_ui_roleplay',
|
||||
label: 'com_ui_roleplay',
|
||||
value: 'roleplay',
|
||||
},
|
||||
{
|
||||
label: 'finance',
|
||||
value: 'com_ui_finance',
|
||||
label: 'com_ui_finance',
|
||||
value: 'finance',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ const {
|
|||
verifyBackupCode,
|
||||
generateTOTPSecret,
|
||||
generateBackupCodes,
|
||||
getTOTPSecret,
|
||||
} = require('~/server/services/twoFactorService');
|
||||
const { updateUser, getUserById } = require('~/models');
|
||||
const { logger } = require('~/config');
|
||||
const { encryptV2 } = require('~/server/utils/crypto');
|
||||
|
||||
const enable2FAController = async (req, res) => {
|
||||
const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
|
||||
|
|
@ -15,7 +17,8 @@ const enable2FAController = async (req, res) => {
|
|||
const secret = generateTOTPSecret();
|
||||
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}`;
|
||||
|
||||
|
|
@ -38,14 +41,16 @@ const verify2FAController = async (req, res) => {
|
|||
return res.status(400).json({ message: '2FA not initiated' });
|
||||
}
|
||||
|
||||
let verified = false;
|
||||
if (token && (await verifyTOTP(user.totpSecret, token))) {
|
||||
// Retrieve the plain TOTP secret using getTOTPSecret.
|
||||
const secret = await getTOTPSecret(user.totpSecret);
|
||||
|
||||
if (token && (await verifyTOTP(secret, token))) {
|
||||
return res.status(200).json();
|
||||
} else if (backupCode) {
|
||||
verified = await verifyBackupCode({ user, backupCode });
|
||||
}
|
||||
if (verified) {
|
||||
return res.status(200).json();
|
||||
const verified = await verifyBackupCode({ user, backupCode });
|
||||
if (verified) {
|
||||
return res.status(200).json();
|
||||
}
|
||||
}
|
||||
|
||||
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' });
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
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 { getUserById } = require('~/models/userMethods');
|
||||
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' });
|
||||
}
|
||||
|
||||
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;
|
||||
} else if (backupCode) {
|
||||
verified = await verifyBackupCode({ user, backupCode });
|
||||
|
|
@ -39,7 +41,7 @@ const verify2FA = async (req, res) => {
|
|||
// Prepare user data for response.
|
||||
// If the user is a plain object (from lean queries), we create a shallow copy.
|
||||
const userData = user.toObject ? user.toObject() : { ...user };
|
||||
// Remove sensitive fields
|
||||
// Remove sensitive fields.
|
||||
delete userData.password;
|
||||
delete userData.__v;
|
||||
delete userData.totpSecret;
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@ const staticCache = require('./utils/staticCache');
|
|||
const noIndex = require('./middleware/noIndex');
|
||||
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 host = HOST || 'localhost';
|
||||
const trusted_proxy = Number(TRUST_PROXY) || 1; /* trust first proxy by default */
|
||||
|
||||
const startServer = async () => {
|
||||
if (typeof Bun !== 'undefined') {
|
||||
|
|
@ -53,7 +54,7 @@ const startServer = async () => {
|
|||
app.use(staticCache(app.locals.paths.dist));
|
||||
app.use(staticCache(app.locals.paths.fonts));
|
||||
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(cookieParser());
|
||||
|
||||
|
|
@ -145,6 +146,18 @@ process.on('uncaughtException', (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 (messageCount === 0) {
|
||||
logger.warn('Meilisearch error, search will be disabled');
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ const primeFiles = async (options, apiKey) => {
|
|||
const { handleFileUpload: uploadCodeEnvFile } = getStrategyFunctions(
|
||||
FileSources.execute_code,
|
||||
);
|
||||
const stream = await getDownloadStream(file.filepath);
|
||||
const stream = await getDownloadStream(options.req, file.filepath);
|
||||
const fileIdentifier = await uploadCodeEnvFile({
|
||||
req: options.req,
|
||||
stream,
|
||||
|
|
|
|||
|
|
@ -224,10 +224,11 @@ async function uploadFileToFirebase({ req, file, file_id }) {
|
|||
/**
|
||||
* Retrieves a readable stream for a file from Firebase storage.
|
||||
*
|
||||
* @param {ServerRequest} _req
|
||||
* @param {string} filepath - The filepath.
|
||||
* @returns {Promise<ReadableStream>} A readable stream of the file.
|
||||
*/
|
||||
async function getFirebaseFileStream(filepath) {
|
||||
async function getFirebaseFileStream(_req, filepath) {
|
||||
try {
|
||||
const storage = getFirebaseStorage();
|
||||
if (!storage) {
|
||||
|
|
|
|||
|
|
@ -286,11 +286,31 @@ async function uploadLocalFile({ req, file, file_id }) {
|
|||
/**
|
||||
* Retrieves a readable stream for a file from local storage.
|
||||
*
|
||||
* @param {ServerRequest} req - The request object from Express
|
||||
* @param {string} filepath - The filepath.
|
||||
* @returns {ReadableStream} A readable stream of the file.
|
||||
*/
|
||||
function getLocalFileStream(filepath) {
|
||||
function getLocalFileStream(req, filepath) {
|
||||
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);
|
||||
} catch (error) {
|
||||
logger.error('Error getting local file stream:', error);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
const { sign } = require('jsonwebtoken');
|
||||
const { webcrypto } = require('node:crypto');
|
||||
const { hashBackupCode } = require('~/server/utils/crypto');
|
||||
const { hashBackupCode, decryptV2 } = require('~/server/utils/crypto');
|
||||
const { updateUser } = require('~/models/userMethods');
|
||||
|
||||
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.
|
||||
* @returns {string} - The Base32 encoded string.
|
||||
* @returns {string} The Base32 encoded string.
|
||||
*/
|
||||
const encodeBase32 = (buffer) => {
|
||||
let bits = 0;
|
||||
|
|
@ -30,8 +31,9 @@ const encodeBase32 = (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 cleaned = base32Str.replace(/=+$/, '').toUpperCase();
|
||||
|
|
@ -54,15 +56,20 @@ const decodeBase32 = (base32Str) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Generate a temporary token for 2FA verification.
|
||||
* This token is signed with JWT_SECRET and expires in 5 minutes.
|
||||
* Generates a temporary token for 2FA verification.
|
||||
* 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) =>
|
||||
sign({ userId, twoFAPending: true }, process.env.JWT_SECRET, { expiresIn: '5m' });
|
||||
|
||||
/**
|
||||
* Generate a TOTP secret.
|
||||
* Generates 10 random bytes using WebCrypto and encodes them into a Base32 string.
|
||||
* Generates a TOTP secret.
|
||||
* Creates 10 random bytes using WebCrypto and encodes them into a Base32 string.
|
||||
*
|
||||
* @returns {string} A Base32-encoded secret for TOTP.
|
||||
*/
|
||||
const generateTOTPSecret = () => {
|
||||
const randomArray = new Uint8Array(10);
|
||||
|
|
@ -71,12 +78,12 @@ const generateTOTPSecret = () => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Generate a TOTP code based on the secret and current time.
|
||||
* Uses a 30-second time step and generates a 6-digit code.
|
||||
* Generates a Time-based One-Time Password (TOTP) based on the provided secret and time.
|
||||
* This implementation uses a 30-second time step and produces a 6-digit code.
|
||||
*
|
||||
* @param {string} secret - Base32-encoded secret
|
||||
* @param {number} [forTime=Date.now()] - Time in milliseconds
|
||||
* @returns {Promise<string>} - The 6-digit TOTP code.
|
||||
* @param {string} secret - The Base32-encoded TOTP secret.
|
||||
* @param {number} [forTime=Date.now()] - The time (in milliseconds) for which to generate the TOTP.
|
||||
* @returns {Promise<string>} A promise that resolves to the 6-digit TOTP code.
|
||||
*/
|
||||
const generateTOTP = async (secret, forTime = Date.now()) => {
|
||||
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 hmac = new Uint8Array(signatureBuffer);
|
||||
|
||||
// Dynamic truncation as per RFC 4226
|
||||
const offset = hmac[hmac.length - 1] & 0xf;
|
||||
const slice = hmac.slice(offset, offset + 4);
|
||||
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.
|
||||
* Allows for a ±1 time-step window.
|
||||
* Verifies a provided TOTP token against the secret.
|
||||
* It allows for a ±1 time-step window to account for slight clock discrepancies.
|
||||
*
|
||||
* @param {string} secret
|
||||
* @param {string} token
|
||||
* @returns {Promise<boolean>}
|
||||
* @param {string} secret - The Base32-encoded TOTP secret.
|
||||
* @param {string} token - The TOTP token provided by the user.
|
||||
* @returns {Promise<boolean>} A promise that resolves to true if the token is valid; otherwise, false.
|
||||
*/
|
||||
const verifyTOTP = async (secret, token) => {
|
||||
const timeStepMS = 30 * 1000;
|
||||
|
|
@ -135,12 +143,13 @@ const verifyTOTP = async (secret, token) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Generate backup codes.
|
||||
* Generates `count` backup code objects and returns an object with both plain codes
|
||||
* (for one-time download) and their objects (for secure storage). Uses WebCrypto for randomness and hashing.
|
||||
* Generates backup codes for two-factor authentication.
|
||||
* Each backup code is an 8-character hexadecimal string along with its SHA-256 hash.
|
||||
* 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).
|
||||
* @returns {Promise<Object>} - Contains `plainCodes` (array of strings) and `codeObjects` (array of objects).
|
||||
* @param {number} [count=10] - The number of backup codes to generate.
|
||||
* @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 plainCodes = [];
|
||||
|
|
@ -165,11 +174,12 @@ const generateBackupCodes = async (count = 10) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Verifies a backup code and updates the user's backup codes if valid
|
||||
* @param {Object} params
|
||||
* @param {TUser | undefined} [params.user] - The user object
|
||||
* @param {string | undefined} [params.backupCode] - The backup code to verify
|
||||
* @returns {Promise<boolean>} - Whether the backup code was valid
|
||||
* Verifies a backup code for a user and updates its status as used if valid.
|
||||
*
|
||||
* @param {Object} params - The parameters object.
|
||||
* @param {TUser | undefined} [params.user] - The user object containing backup codes.
|
||||
* @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 }) => {
|
||||
if (!backupCode || !user || !Array.isArray(user.backupCodes)) {
|
||||
|
|
@ -195,9 +205,32 @@ const verifyBackupCode = async ({ user, backupCode }) => {
|
|||
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 = {
|
||||
verifyTOTP,
|
||||
generateTOTP,
|
||||
getTOTPSecret,
|
||||
verifyBackupCode,
|
||||
generateTOTPSecret,
|
||||
generateBackupCodes,
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@
|
|||
"html-to-image": "^1.11.11",
|
||||
"i18next": "^24.2.2",
|
||||
"i18next-browser-languagedetector": "^8.0.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"input-otp": "^1.4.2",
|
||||
"js-cookie": "^3.0.5",
|
||||
"librechat-data-provider": "*",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.394.0",
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
"react-i18next": "^15.4.0",
|
||||
"react-lazy-load-image-component": "^1.6.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-resizable-panels": "^2.1.1",
|
||||
"react-resizable-panels": "^2.1.7",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"react-speech-recognition": "^3.10.0",
|
||||
"react-textarea-autosize": "^8.4.0",
|
||||
|
|
@ -144,4 +144,4 @@
|
|||
"vite-plugin-node-polyfills": "^0.17.0",
|
||||
"vite-plugin-pwa": "^0.21.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ function AccountSettings() {
|
|||
!isNaN(parseFloat(balanceQuery.data)) && (
|
||||
<>
|
||||
<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>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const Command = ({
|
|||
}
|
||||
|
||||
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">
|
||||
<SquareSlash className="icon-sm" aria-hidden="true" />
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const Description = ({
|
|||
}
|
||||
|
||||
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">
|
||||
<Info className="icon-sm" aria-hidden="true" />
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default function List({
|
|||
<div className="flex w-full justify-end">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full bg-transparent px-3"
|
||||
className={`w-full bg-transparent ${isChatRoute ? '' : 'mx-2'}`}
|
||||
onClick={() => navigate('/d/prompts/new')}
|
||||
>
|
||||
<Plus className="size-4" aria-hidden />
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const PromptEditor: React.FC<Props> = ({ name, isEditing, setIsEditing }) => {
|
|||
<div
|
||||
role="button"
|
||||
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':
|
||||
!isEditing,
|
||||
|
|
@ -105,6 +105,7 @@ const PromptEditor: React.FC<Props> = ({ name, isEditing, setIsEditing }) => {
|
|||
isEditing ? (
|
||||
<TextareaAutosize
|
||||
{...field}
|
||||
autoFocus
|
||||
className="w-full resize-none overflow-y-auto rounded bg-transparent text-sm text-text-primary focus:outline-none sm:text-base"
|
||||
minRows={3}
|
||||
maxRows={14}
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ const PromptForm = () => {
|
|||
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">
|
||||
{hasShareAccess && <SharePrompt group={group} disabled={isLoadingGroup} />}
|
||||
|
|
@ -349,7 +348,7 @@ const PromptForm = () => {
|
|||
{isLoadingPrompts ? (
|
||||
<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} />
|
||||
<PromptVariables promptText={promptText} />
|
||||
<Description
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const PromptVariables = ({
|
|||
}, [promptText]);
|
||||
|
||||
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">
|
||||
<Variable className="icon-sm" aria-hidden="true" />
|
||||
{localize('com_ui_variables')}
|
||||
|
|
@ -71,7 +71,7 @@ const PromptVariables = ({
|
|||
</span>
|
||||
</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')}
|
||||
</span>
|
||||
<span className="text-sm text-text-secondary">
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ export default function AgentSwitcher({ isCollapsed }: SwitcherProps) {
|
|||
ariaLabel={'agent'}
|
||||
setValue={onSelect}
|
||||
items={agentOptions}
|
||||
iconClassName="assistant-item"
|
||||
SelectIcon={
|
||||
<Icon
|
||||
isCreatedByUser={false}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Plus } from 'lucide-react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
|
||||
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"
|
||||
aria-label="Agent configuration form"
|
||||
>
|
||||
<div className="mt-2 flex w-full flex-wrap gap-2">
|
||||
<Controller
|
||||
name="agent"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<AgentSelect
|
||||
reset={reset}
|
||||
value={field.value}
|
||||
agentQuery={agentQuery}
|
||||
setCurrentAgentId={setCurrentAgentId}
|
||||
selectedAgentId={current_agent_id ?? null}
|
||||
createMutation={create}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* Select Button */}
|
||||
<div className="mx-1 mt-2 flex w-full flex-wrap gap-2">
|
||||
<div className="w-full">
|
||||
<Controller
|
||||
name="agent"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<AgentSelect
|
||||
reset={reset}
|
||||
value={field.value}
|
||||
agentQuery={agentQuery}
|
||||
setCurrentAgentId={setCurrentAgentId}
|
||||
selectedAgentId={current_agent_id ?? null}
|
||||
createMutation={create}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Create + Select Button */}
|
||||
{agent_id && (
|
||||
<Button
|
||||
variant="submit"
|
||||
disabled={!agent_id}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
handleSelectAgent();
|
||||
}}
|
||||
aria-label="Select agent"
|
||||
>
|
||||
{localize('com_ui_select')}
|
||||
</Button>
|
||||
<div className="flex w-full gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="w-full justify-center"
|
||||
onClick={() => {
|
||||
reset(defaultAgentFormValues);
|
||||
setCurrentAgentId(undefined);
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
{!canEditAgent && (
|
||||
|
|
|
|||
|
|
@ -4,10 +4,16 @@ import { Skeleton } from '~/components/ui';
|
|||
export default function AgentPanelSkeleton() {
|
||||
return (
|
||||
<div className="scrollbar-gutter-stable h-auto w-full flex-shrink-0 overflow-x-hidden">
|
||||
{/* Agent Select and Button */}
|
||||
<div className="mt-1 flex w-full gap-2">
|
||||
<Skeleton className="h-[40px] w-4/5 rounded-lg" />
|
||||
<Skeleton className="h-[40px] w-1/5 rounded-lg" />
|
||||
<div className="mx-1 mt-2 flex w-full flex-wrap gap-2">
|
||||
{/* Agent Select Dropdown */}
|
||||
<div className="w-full">
|
||||
<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 className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent">
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import { Plus, EarthIcon } from 'lucide-react';
|
||||
import { EarthIcon } from 'lucide-react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
|
||||
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
|
||||
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
|
||||
import type { UseFormReset } from 'react-hook-form';
|
||||
import type { TAgentCapabilities, AgentForm, TAgentOption } from '~/common';
|
||||
import { cn, createDropdownSetter, createProviderOption, processAgentOption } from '~/utils';
|
||||
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';
|
||||
|
||||
const keys = new Set(Object.keys(defaultAgentFormValues));
|
||||
const SELECT_ID = 'agent-builder-combobox';
|
||||
|
||||
export default function AgentSelect({
|
||||
reset,
|
||||
|
|
@ -120,6 +121,9 @@ export default function AgentSelect({
|
|||
}
|
||||
|
||||
resetAgentForm(agent);
|
||||
setTimeout(() => {
|
||||
document.getElementById(SELECT_ID)?.focus();
|
||||
}, 5);
|
||||
},
|
||||
[agents, createMutation, setCurrentAgentId, agentQuery.data, resetAgentForm, reset],
|
||||
);
|
||||
|
|
@ -152,51 +156,36 @@ export default function AgentSelect({
|
|||
}, [selectedAgentId, agents, onSelect]);
|
||||
|
||||
const createAgent = localize('com_ui_create') + ' ' + localize('com_ui_agent');
|
||||
const hasAgentValue = !!(typeof currentAgentValue === 'object'
|
||||
? currentAgentValue.value != null && currentAgentValue.value !== ''
|
||||
: typeof currentAgentValue !== 'undefined');
|
||||
|
||||
return (
|
||||
<SelectDropDown
|
||||
value={!hasAgentValue ? createAgent : (currentAgentValue as TAgentOption)}
|
||||
setValue={createDropdownSetter(onSelect)}
|
||||
availableValues={
|
||||
agents ?? [
|
||||
<ControlCombobox
|
||||
selectId={SELECT_ID}
|
||||
containerClassName="px-0"
|
||||
selectedValue={(currentAgentValue?.value ?? '') + ''}
|
||||
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...',
|
||||
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(
|
||||
'rounded-md dark:border-gray-700 dark:bg-gray-850',
|
||||
'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>
|
||||
'z-50 flex h-[40px] w-full flex-none items-center justify-center truncate rounded-md bg-transparent font-bold',
|
||||
)}
|
||||
ariaLabel={localize('com_ui_agent')}
|
||||
isCollapsed={false}
|
||||
showCarat={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import React, { useMemo, useEffect } from 'react';
|
||||
import { ChevronLeft, RotateCcw } from 'lucide-react';
|
||||
import { getSettingsKeys } from 'librechat-data-provider';
|
||||
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 { AgentForm, AgentModelPanelProps, StringOption } from '~/common';
|
||||
import { componentMapping } from '~/components/SidePanel/Parameters/components';
|
||||
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 { SelectDropDown } from '~/components/ui';
|
||||
import { getEndpointField, cn } from '~/utils';
|
||||
import { useLocalize } from '~/hooks';
|
||||
import { Panel } from '~/common';
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ export default function Parameters({
|
|||
return value ?? '';
|
||||
}, [providerOption]);
|
||||
const models = useMemo(
|
||||
() => (provider ? modelsData[provider] ?? [] : []),
|
||||
() => (provider ? (modelsData[provider] ?? []) : []),
|
||||
[modelsData, provider],
|
||||
);
|
||||
|
||||
|
|
@ -78,8 +78,8 @@ export default function Parameters({
|
|||
|
||||
return (
|
||||
<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="absolute left-0 top-6">
|
||||
<div className="model-panel relative flex flex-col items-center px-16 py-4 text-center">
|
||||
<div className="absolute left-0 top-4">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-neutral relative"
|
||||
|
|
@ -99,6 +99,7 @@ export default function Parameters({
|
|||
{/* Endpoint aka Provider for Agents */}
|
||||
<div className="mb-4">
|
||||
<label
|
||||
id="provider-label"
|
||||
className="text-token-text-primary model-panel-label mb-2 block font-medium"
|
||||
htmlFor="provider"
|
||||
>
|
||||
|
|
@ -108,38 +109,47 @@ export default function Parameters({
|
|||
name="provider"
|
||||
control={control}
|
||||
rules={{ required: true, minLength: 1 }}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<>
|
||||
<SelectDropDown
|
||||
emptyTitle={true}
|
||||
value={field.value ?? ''}
|
||||
title={localize('com_ui_provider')}
|
||||
placeholder={localize('com_ui_select_provider')}
|
||||
searchPlaceholder={localize('com_ui_select_search_provider')}
|
||||
setValue={field.onChange}
|
||||
availableValues={providers}
|
||||
showAbove={false}
|
||||
showLabel={false}
|
||||
className={cn(
|
||||
cardStyle,
|
||||
'flex h-9 w-full flex-none items-center justify-center border-none px-4 hover:cursor-pointer',
|
||||
(field.value === undefined || field.value === '') &&
|
||||
'border-2 border-yellow-400',
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
const value =
|
||||
typeof field.value === 'string'
|
||||
? field.value
|
||||
: ((field.value as StringOption)?.value ?? '');
|
||||
const display =
|
||||
typeof field.value === 'string'
|
||||
? field.value
|
||||
: ((field.value as StringOption)?.label ?? '');
|
||||
|
||||
return (
|
||||
<>
|
||||
<ControlCombobox
|
||||
selectedValue={value}
|
||||
displayValue={alternateName[display] ?? display}
|
||||
selectPlaceholder={localize('com_ui_select_provider')}
|
||||
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>
|
||||
{/* Model */}
|
||||
<div className="model-panel-section mb-4">
|
||||
<label
|
||||
id="model-label"
|
||||
className={cn(
|
||||
'text-token-text-primary model-panel-label mb-2 block font-medium',
|
||||
!provider && 'text-gray-500 dark:text-gray-400',
|
||||
|
|
@ -152,35 +162,36 @@ export default function Parameters({
|
|||
name="model"
|
||||
control={control}
|
||||
rules={{ required: true, minLength: 1 }}
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<>
|
||||
<SelectDropDown
|
||||
emptyTitle={true}
|
||||
placeholder={
|
||||
provider
|
||||
? localize('com_ui_select_model')
|
||||
: localize('com_ui_select_provider_first')
|
||||
}
|
||||
value={field.value}
|
||||
setValue={field.onChange}
|
||||
availableValues={models}
|
||||
showAbove={false}
|
||||
showLabel={false}
|
||||
disabled={!provider}
|
||||
className={cn(
|
||||
cardStyle,
|
||||
'flex h-[40px] w-full flex-none items-center justify-center border-none px-4',
|
||||
!provider ? 'cursor-not-allowed bg-gray-200' : 'hover:cursor-pointer',
|
||||
render={({ field, fieldState: { error } }) => {
|
||||
return (
|
||||
<>
|
||||
<ControlCombobox
|
||||
selectedValue={field.value || ''}
|
||||
selectPlaceholder={
|
||||
provider
|
||||
? localize('com_ui_select_model')
|
||||
: localize('com_ui_select_provider_first')
|
||||
}
|
||||
searchPlaceholder={localize('com_ui_select_model')}
|
||||
setValue={field.onChange}
|
||||
items={models.map((model) => ({
|
||||
label: model,
|
||||
value: model,
|
||||
}))}
|
||||
disabled={!provider}
|
||||
className={cn('disabled:opacity-50', error ? 'border-2 border-red-500' : '')}
|
||||
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>
|
||||
|
|
@ -188,7 +199,6 @@ export default function Parameters({
|
|||
{parameters && (
|
||||
<div className="h-auto max-w-full overflow-x-hidden p-2">
|
||||
<div className="grid grid-cols-4 gap-6">
|
||||
{' '}
|
||||
{/* 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 */}
|
||||
{parameters.map((setting) => {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
|
|||
ariaLabel={'assistant'}
|
||||
setValue={onSelect}
|
||||
items={assistantOptions}
|
||||
iconClassName="assistant-item"
|
||||
SelectIcon={
|
||||
<Icon
|
||||
isCreatedByUser={false}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Search } from 'lucide-react';
|
||||
import * as Ariakit from '@ariakit/react';
|
||||
import { matchSorter } from 'match-sorter';
|
||||
import { Search, ChevronDown } from 'lucide-react';
|
||||
import { useMemo, useState, useRef, memo, useEffect } from 'react';
|
||||
import { SelectRenderer } from '@ariakit/react-core/select/select-renderer';
|
||||
import type { OptionWithIcon } from '~/common';
|
||||
|
|
@ -16,6 +16,13 @@ interface ControlComboboxProps {
|
|||
selectPlaceholder?: string;
|
||||
isCollapsed: boolean;
|
||||
SelectIcon?: React.ReactNode;
|
||||
containerClassName?: string;
|
||||
iconClassName?: string;
|
||||
showCarat?: boolean;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
iconSide?: 'left' | 'right';
|
||||
selectId?: string;
|
||||
}
|
||||
|
||||
const ROW_HEIGHT = 36;
|
||||
|
|
@ -28,8 +35,15 @@ function ControlCombobox({
|
|||
ariaLabel,
|
||||
searchPlaceholder,
|
||||
selectPlaceholder,
|
||||
containerClassName,
|
||||
isCollapsed,
|
||||
SelectIcon,
|
||||
showCarat,
|
||||
className,
|
||||
disabled,
|
||||
iconClassName,
|
||||
iconSide = 'left',
|
||||
selectId,
|
||||
}: ControlComboboxProps) {
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
|
|
@ -70,28 +84,48 @@ function ControlCombobox({
|
|||
}
|
||||
}, [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 (
|
||||
<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">
|
||||
{ariaLabel}
|
||||
</Ariakit.SelectLabel>
|
||||
<Ariakit.Select
|
||||
ref={buttonRef}
|
||||
store={select}
|
||||
id={selectId}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
'flex items-center justify-center gap-2 rounded-full bg-surface-secondary',
|
||||
'text-text-primary hover:bg-surface-tertiary',
|
||||
'border border-border-light',
|
||||
isCollapsed ? 'h-10 w-10' : 'h-10 w-full rounded-md px-3 py-2 text-sm',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{SelectIcon != null && (
|
||||
<div className="assistant-item flex h-5 w-5 items-center justify-center overflow-hidden rounded-full">
|
||||
{SelectIcon}
|
||||
</div>
|
||||
{SelectIcon != null && iconSide === 'left' && (
|
||||
<div className={selectIconClassName}>{SelectIcon}</div>
|
||||
)}
|
||||
{!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.SelectPopover
|
||||
|
|
@ -126,12 +160,13 @@ function ControlCombobox({
|
|||
)}
|
||||
render={<Ariakit.SelectItem value={value} />}
|
||||
>
|
||||
{icon != null && (
|
||||
<div className="assistant-item mr-2 flex h-5 w-5 items-center justify-center overflow-hidden rounded-full">
|
||||
{icon}
|
||||
</div>
|
||||
{icon != null && iconSide === 'left' && (
|
||||
<div className={optionIconClassName}>{icon}</div>
|
||||
)}
|
||||
<span className="flex-grow truncate text-left">{label}</span>
|
||||
{icon != null && iconSide === 'right' && (
|
||||
<div className={optionIconClassName}>{icon}</div>
|
||||
)}
|
||||
</Ariakit.ComboboxItem>
|
||||
)}
|
||||
</SelectRenderer>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
Label,
|
||||
Listbox,
|
||||
|
|
@ -82,18 +82,14 @@ function SelectDropDown({
|
|||
}
|
||||
|
||||
let title = _title;
|
||||
|
||||
if (emptyTitle) {
|
||||
title = '';
|
||||
} else if (!(title ?? '')) {
|
||||
title = localize('com_ui_model');
|
||||
}
|
||||
|
||||
const values = availableValues ?? [];
|
||||
|
||||
// Detemine if we should to convert this component into a searchable select. If we have enough elements, a search
|
||||
// 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)
|
||||
// Enable searchable select if enough items are provided.
|
||||
const [filteredValues, searchRender] = useMultiSearch<string[] | Option[]>({
|
||||
availableOptions: values,
|
||||
placeholder: searchPlaceholder,
|
||||
|
|
@ -103,26 +99,35 @@ function SelectDropDown({
|
|||
});
|
||||
const hasSearchRender = searchRender != null;
|
||||
const options = hasSearchRender ? filteredValues : values;
|
||||
|
||||
const renderIcon = showOptionIcon && value != null && (value as OptionWithIcon).icon != null;
|
||||
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
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 ?? '')}>
|
||||
<Listbox value={value} onChange={setValue} disabled={disabled}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<ListboxButton
|
||||
ref={buttonRef}
|
||||
data-testid="select-dropdown-button"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (!open && buttonRef.current) {
|
||||
buttonRef.current.click();
|
||||
}
|
||||
}
|
||||
}}
|
||||
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 ?? '',
|
||||
)}
|
||||
>
|
||||
{' '}
|
||||
{showLabel && (
|
||||
<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:"
|
||||
data-headlessui-state=""
|
||||
>
|
||||
|
|
@ -154,11 +159,9 @@ function SelectDropDown({
|
|||
if (!value) {
|
||||
return <span className="text-text-secondary">{placeholder}</span>;
|
||||
}
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
return value.label ?? '';
|
||||
}
|
||||
|
||||
return value;
|
||||
})()}
|
||||
</span>
|
||||
|
|
@ -171,7 +174,7 @@ function SelectDropDown({
|
|||
viewBox="0 0 24 24"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-4 w-4 text-gray-400"
|
||||
className="h-4 w-4 text-gray-400"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -212,17 +215,17 @@ function SelectDropDown({
|
|||
if (!option) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentLabel =
|
||||
typeof option === 'string' ? option : option.label ?? option.value ?? '';
|
||||
const currentValue = typeof option === 'string' ? option : option.value ?? '';
|
||||
typeof option === 'string' ? option : (option.label ?? option.value ?? '');
|
||||
const currentValue = typeof option === 'string' ? option : (option.value ?? '');
|
||||
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;
|
||||
if (typeof activeValue !== 'string') {
|
||||
activeValue = activeValue?.value ?? '';
|
||||
}
|
||||
|
||||
return (
|
||||
<ListboxOption
|
||||
key={i}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
"com_auth_email_verification_redirecting": "Weiterleitung in {{0}} Sekunden...",
|
||||
"com_auth_email_verification_resend_prompt": "Keine E-Mail erhalten?",
|
||||
"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_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.",
|
||||
|
|
@ -121,9 +122,11 @@
|
|||
"com_auth_submit_registration": "Registrierung absenden",
|
||||
"com_auth_to_reset_your_password": "um Ihr Passwort zurückzusetzen.",
|
||||
"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_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_verify_your_identity": "Bestätige deine Identität",
|
||||
"com_auth_welcome_back": "Willkommen zurück",
|
||||
"com_click_to_download": "(hier klicken zum Herunterladen)",
|
||||
"com_download_expired": "Download abgelaufen",
|
||||
|
|
@ -261,6 +264,7 @@
|
|||
"com_files_number_selected": "{{0}} von {{1}} Datei(en) ausgewählt",
|
||||
"com_generated_files": "Generierte Dateien:",
|
||||
"com_hide_examples": "Beispiele ausblenden",
|
||||
"com_nav_2fa": "Zwei-Faktor-Authentifizierung (2FA)",
|
||||
"com_nav_account_settings": "Kontoeinstellungen",
|
||||
"com_nav_always_make_prod": "Neue Versionen direkt produktiv nehmen",
|
||||
"com_nav_archive_created_at": "Archivierungsdatum",
|
||||
|
|
@ -326,6 +330,7 @@
|
|||
"com_nav_help_faq": "Hilfe & FAQ",
|
||||
"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_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_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.",
|
||||
|
|
@ -429,6 +434,16 @@
|
|||
"com_sidepanel_parameters": "KI-Einstellungen",
|
||||
"com_sidepanel_select_agent": "Wähle einen Agenten",
|
||||
"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_add": "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_all": "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_archive": "Archivieren",
|
||||
"com_ui_archive_error": "Konversation konnte nicht archiviert werden",
|
||||
"com_ui_artifact_click": "Zum Öffnen klicken",
|
||||
"com_ui_artifacts": "Artefakte",
|
||||
"com_ui_artifacts_toggle": "Artefakte-Funktion einschalten",
|
||||
"com_ui_artifacts_toggle_agent": "Artefakte aktivieren",
|
||||
"com_ui_ascending": "Aufsteigend",
|
||||
"com_ui_assistant": "Assistent",
|
||||
"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_type": "Authentifizierungstyp",
|
||||
"com_ui_avatar": "Avatar",
|
||||
"com_ui_azure": "Azure",
|
||||
"com_ui_back_to_chat": "Zurück zum Chat",
|
||||
"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_auth_header": "Basic-Authentifizierungsheader",
|
||||
"com_ui_bearer": "Bearer",
|
||||
|
|
@ -510,6 +532,7 @@
|
|||
"com_ui_collapse_chat": "Chat einklappen",
|
||||
"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_complete_setup": "Einrichtung abschließen",
|
||||
"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_change": "Änderung bestätigen",
|
||||
|
|
@ -526,6 +549,7 @@
|
|||
"com_ui_create_prompt": "Prompt erstellen",
|
||||
"com_ui_currently_production": "Aktuell im Produktivbetrieb",
|
||||
"com_ui_custom": "Benutzerdefiniert",
|
||||
"com_ui_custom_header_name": "Benutzerdefinierter Headername",
|
||||
"com_ui_custom_prompt_mode": "Benutzerdefinierter Promptmodus für Artefakte",
|
||||
"com_ui_dashboard": "Dashboard",
|
||||
"com_ui_date": "Datum",
|
||||
|
|
@ -546,6 +570,7 @@
|
|||
"com_ui_date_today": "Heute",
|
||||
"com_ui_date_yesterday": "Gestern",
|
||||
"com_ui_decline": "Ich akzeptiere nicht",
|
||||
"com_ui_default_post_request": "Standard (POST-Anfrage)",
|
||||
"com_ui_delete": "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?",
|
||||
|
|
@ -561,8 +586,11 @@
|
|||
"com_ui_descending": "Absteigend",
|
||||
"com_ui_description": "Beschreibung",
|
||||
"com_ui_description_placeholder": "Optional: Gib eine Beschreibung für den Prompt ein",
|
||||
"com_ui_disabling": "Deaktiviere …",
|
||||
"com_ui_download": "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_dropdown_variables": "Dropdown-Variablen:",
|
||||
"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_filter_prompts": "Prompts filtern",
|
||||
"com_ui_filter_prompts_name": "Prompts nach Namen filtern",
|
||||
"com_ui_finance": "Finanzen",
|
||||
"com_ui_fork": "Abzweigen",
|
||||
"com_ui_fork_all_target": "Alle bis/von hier 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_success": "Konversation erfolgreich abgezweigt",
|
||||
"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_to_conversation": "Zur Konversation gehen",
|
||||
"com_ui_happy_birthday": "Es ist mein 1. Geburtstag!",
|
||||
"com_ui_hide_qr": "QR-Code ausblenden",
|
||||
"com_ui_host": "Host",
|
||||
"com_ui_idea": "Ideen",
|
||||
"com_ui_image_gen": "Bildgenerierung",
|
||||
"com_ui_import": "Importieren",
|
||||
"com_ui_import_conversation_error": "Beim Importieren Ihrer Konversationen ist ein Fehler aufgetreten",
|
||||
"com_ui_import_conversation_file_type_error": "Nicht unterstützter Importtyp",
|
||||
"com_ui_import_conversation_info": "Konversationen aus einer JSON-Datei importieren",
|
||||
"com_ui_import_conversation_success": "Konversationen erfolgreich importiert",
|
||||
"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_instructions": "Anweisungen",
|
||||
"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_llm_menu": "LLM-Menü",
|
||||
"com_ui_llms_available": "Verfügbare LLMs",
|
||||
"com_ui_loading": "Lade …",
|
||||
"com_ui_locked": "Gesperrt",
|
||||
"com_ui_logo": "{{0}} Logo",
|
||||
"com_ui_manage": "Verwalten",
|
||||
"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_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_parameters": "Modell-Parameter",
|
||||
"com_ui_more_info": "Mehr Infos",
|
||||
|
|
@ -643,17 +680,20 @@
|
|||
"com_ui_new_chat": "Neuer Chat",
|
||||
"com_ui_next": "Weiter",
|
||||
"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_category": "Keine Kategorie",
|
||||
"com_ui_no_changes": "Keine Änderungen zum Aktualisieren",
|
||||
"com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen",
|
||||
"com_ui_none": "Keine",
|
||||
"com_ui_none_selected": "Nichts ausgewählt",
|
||||
"com_ui_not_used": "Nicht verwendet",
|
||||
"com_ui_nothing_found": "Nichts gefunden",
|
||||
"com_ui_oauth": "OAuth",
|
||||
"com_ui_of": "von",
|
||||
"com_ui_off": "Aus",
|
||||
"com_ui_on": "An",
|
||||
"com_ui_openai": "OpenAI",
|
||||
"com_ui_page": "Seite",
|
||||
"com_ui_prev": "Zurück",
|
||||
"com_ui_preview": "Vorschau",
|
||||
|
|
@ -675,6 +715,8 @@
|
|||
"com_ui_read_aloud": "Vorlesen",
|
||||
"com_ui_refresh_link": "Link aktualisieren",
|
||||
"com_ui_regenerate": "Neu generieren",
|
||||
"com_ui_regenerate_backup": "Backup-Codes neu generieren",
|
||||
"com_ui_regenerating": "Generiere neu ...",
|
||||
"com_ui_region": "Region",
|
||||
"com_ui_rename": "Umbenennen",
|
||||
"com_ui_rename_prompt": "Prompt umbenennen",
|
||||
|
|
@ -688,13 +730,16 @@
|
|||
"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_role_select": "Rolle auswählen",
|
||||
"com_ui_roleplay": "Rollenspiel",
|
||||
"com_ui_run_code": "Code ausführen",
|
||||
"com_ui_run_code_error": "Bei der Ausführung des Codes ist ein Fehler aufgetreten",
|
||||
"com_ui_save": "Speichern",
|
||||
"com_ui_save_submit": "Speichern & Absenden",
|
||||
"com_ui_saved": "Gespeichert!",
|
||||
"com_ui_schema": "Schema",
|
||||
"com_ui_scope": "Umfang",
|
||||
"com_ui_search": "Suche",
|
||||
"com_ui_secret_key": "Geheimschlüssel",
|
||||
"com_ui_select": "Auswählen",
|
||||
"com_ui_select_file": "Datei 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_not_found": "Geteilter Link nicht gefunden",
|
||||
"com_ui_shared_prompts": "Geteilte Prompts",
|
||||
"com_ui_shop": "Einkaufen",
|
||||
"com_ui_show": "Anzeigen",
|
||||
"com_ui_show_all": "Alle anzeigen",
|
||||
"com_ui_show_qr": "QR-Code anzeigen",
|
||||
"com_ui_sign_in_to_domain": "Anmelden bei {{0}}",
|
||||
|
|
@ -728,6 +775,7 @@
|
|||
"com_ui_stop": "Stopp",
|
||||
"com_ui_storage": "Speicher",
|
||||
"com_ui_submit": "Absenden",
|
||||
"com_ui_teach_or_explain": "Lernen",
|
||||
"com_ui_temporary_chat": "Temporärer Chat",
|
||||
"com_ui_terms_and_conditions": "Allgemeine Geschäftsbedingungen",
|
||||
"com_ui_terms_of_service": "Nutzungsbedingungen",
|
||||
|
|
@ -736,6 +784,7 @@
|
|||
"com_ui_token_exchange_method": "Token-Austauschmethode",
|
||||
"com_ui_token_url": "Token-URL",
|
||||
"com_ui_tools": "Werkzeuge",
|
||||
"com_ui_travel": "Reisen",
|
||||
"com_ui_unarchive": "Aus Archiv holen",
|
||||
"com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden",
|
||||
"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_success": "Datei erfolgreich hochgeladen",
|
||||
"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_prompt": "Prompt verwenden",
|
||||
"com_ui_used": "Verwendet",
|
||||
"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_verify": "Überprüfen",
|
||||
"com_ui_version_var": "Version {{0}}",
|
||||
"com_ui_versions": "Versionen",
|
||||
"com_ui_view_source": "Quell-Chat anzeigen",
|
||||
"com_ui_write": "Schreiben",
|
||||
"com_ui_yes": "Ja",
|
||||
"com_ui_zoom": "Zoom",
|
||||
"com_user_message": "Du",
|
||||
|
|
|
|||
|
|
@ -685,6 +685,7 @@
|
|||
"com_ui_more_info": "More info",
|
||||
"com_ui_my_prompts": "My Prompts",
|
||||
"com_ui_name": "Name",
|
||||
"com_ui_new": "New",
|
||||
"com_ui_new_chat": "New chat",
|
||||
"com_ui_next": "Next",
|
||||
"com_ui_no": "No",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"chat_direction_left_to_right": "midagi peaks siia minema. Oli tühi",
|
||||
"chat_direction_right_to_left": "midagi peaks siia minema. Oli tühi",
|
||||
"chat_direction_left_to_right": "Joonda vestlus vasakult paremale.",
|
||||
"chat_direction_right_to_left": "Joonda vestlus paremalt vasakule.",
|
||||
"com_a11y_ai_composing": "AI genereerib vastust.",
|
||||
"com_a11y_end": "AI on oma vastuse lõpetanud.",
|
||||
"com_a11y_start": "AI on oma vastuse andmise alustanud.",
|
||||
|
|
@ -214,7 +214,7 @@
|
|||
"com_endpoint_plug_use_functions": "Kasuta funktsioone",
|
||||
"com_endpoint_presence_penalty": "Olekukaristus",
|
||||
"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_item": "Vaikimisi:",
|
||||
"com_endpoint_preset_default_none": "Vaikimisi eelseadistus pole aktiivne.",
|
||||
|
|
@ -262,7 +262,7 @@
|
|||
"com_files_filter": "Filtreeri faile...",
|
||||
"com_files_no_results": "Tulemusi pole.",
|
||||
"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_hide_examples": "Peida näited",
|
||||
"com_nav_account_settings": "Konto seaded",
|
||||
|
|
@ -448,7 +448,7 @@
|
|||
"com_ui_agent_duplicate_error": "Agendi dubleerimisel tekkis viga",
|
||||
"com_ui_agent_duplicated": "Agendi dubleerimine õnnestus",
|
||||
"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_allow_create": "Luba agentide loomine",
|
||||
"com_ui_agents_allow_share_global": "Luba agentide jagamine kõigile kasutajatele",
|
||||
|
|
@ -576,7 +576,7 @@
|
|||
"com_ui_download": "Laadi alla",
|
||||
"com_ui_download_artifact": "Laadi artefakt alla",
|
||||
"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_info": "Loo sisendite jaoks kohandatud rippmenüüd: `{{muutuja_nimi:valik1|valik2|valik3}}`",
|
||||
"com_ui_duplicate": "Dubleeri",
|
||||
|
|
@ -584,6 +584,7 @@
|
|||
"com_ui_duplication_processing": "Vestlust dubleeritakse...",
|
||||
"com_ui_duplication_success": "Vestluse dubleerimine õnnestus",
|
||||
"com_ui_edit": "Muuda",
|
||||
"com_ui_empty_category": "-",
|
||||
"com_ui_endpoint": "Otspunkt",
|
||||
"com_ui_endpoint_menu": "LLM otspunkti menüü",
|
||||
"com_ui_endpoints_available": "Saadaolevad otspunktid",
|
||||
|
|
@ -599,6 +600,7 @@
|
|||
"com_ui_field_required": "See väli on kohustuslik",
|
||||
"com_ui_filter_prompts": "Filtreeri sisendid",
|
||||
"com_ui_filter_prompts_name": "Filtreeri sisendeid nime järgi",
|
||||
"com_ui_finance": "Raha",
|
||||
"com_ui_fork": "Hargne",
|
||||
"com_ui_fork_all_target": "Kaasa kõik siia/siit",
|
||||
"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_success": "Vestluse hargnemine õnnestus",
|
||||
"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_to_conversation": "Mine vestlusesse",
|
||||
"com_ui_happy_birthday": "Mul on 1. sünnipäev!",
|
||||
"com_ui_hide_qr": "Peida QR-kood",
|
||||
"com_ui_host": "Host",
|
||||
"com_ui_idea": "Ideed",
|
||||
"com_ui_image_gen": "Pildi genereerimine",
|
||||
"com_ui_import_conversation_error": "Vestluste importimisel tekkis viga",
|
||||
"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_llm_menu": "LLM menüü",
|
||||
"com_ui_llms_available": "Saadaolevad LLM-id",
|
||||
"com_ui_loading": "Laeb...",
|
||||
"com_ui_locked": "Lukus",
|
||||
"com_ui_logo": "{{0}} logo",
|
||||
"com_ui_manage": "Halda",
|
||||
"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_min_tags": "Rohkem väärtusi ei saa eemaldada, vaja on vähemalt {{0}}.",
|
||||
"com_ui_misc": "Muu",
|
||||
"com_ui_model": "Mudel",
|
||||
"com_ui_model_parameters": "Mudeli parameetrid",
|
||||
"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_category": "Kategooriat pole",
|
||||
"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_valid_items": "midagi peaks siia minema. Oli tühi",
|
||||
"com_ui_no_valid_items": "Sobivad üksused puuduvad!",
|
||||
"com_ui_none": "Puudub",
|
||||
"com_ui_none_selected": "Ühtegi pole valitud",
|
||||
"com_ui_nothing_found": "Midagi ei leitud",
|
||||
|
|
@ -706,6 +711,7 @@
|
|||
"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_role_select": "Roll",
|
||||
"com_ui_roleplay": "Rollimäng",
|
||||
"com_ui_run_code": "Käivita kood",
|
||||
"com_ui_run_code_error": "Koodi käivitamisel tekkis viga",
|
||||
"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_delete_error": "Jagatud lingi kustutamisel 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_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.",
|
||||
|
|
@ -737,6 +743,7 @@
|
|||
"com_ui_shared_link_delete_success": "Jagatud lingi kustutamine õnnestus",
|
||||
"com_ui_shared_link_not_found": "Jagatud linki ei leitud",
|
||||
"com_ui_shared_prompts": "Jagatud sisendid",
|
||||
"com_ui_shop": "Ostlemine",
|
||||
"com_ui_show_all": "Näita kõiki",
|
||||
"com_ui_show_qr": "Näita QR-koodi",
|
||||
"com_ui_sign_in_to_domain": "Logi sisse {{0}}",
|
||||
|
|
@ -748,6 +755,7 @@
|
|||
"com_ui_stop": "Peata",
|
||||
"com_ui_storage": "Salvestusruum",
|
||||
"com_ui_submit": "Esita",
|
||||
"com_ui_teach_or_explain": "Õppimine",
|
||||
"com_ui_temporary_chat": "Ajutine vestlus",
|
||||
"com_ui_terms_and_conditions": "Kasutustingimused",
|
||||
"com_ui_terms_of_service": "Teenuse tingimused",
|
||||
|
|
@ -756,6 +764,7 @@
|
|||
"com_ui_token_exchange_method": "Märgi vahetamise meetod",
|
||||
"com_ui_token_url": "Märgi URL",
|
||||
"com_ui_tools": "Tööriistad",
|
||||
"com_ui_travel": "Reisimine",
|
||||
"com_ui_unarchive": "Arhiveeri lahti",
|
||||
"com_ui_unarchive_error": "Vestluse arhiveerimine lahti ebaõnnestus",
|
||||
"com_ui_unknown": "Tundmatu",
|
||||
|
|
@ -779,6 +788,7 @@
|
|||
"com_ui_version_var": "Versioon {{0}}",
|
||||
"com_ui_versions": "Versioonid",
|
||||
"com_ui_view_source": "Vaata algset vestlust",
|
||||
"com_ui_write": "Kirjutamine",
|
||||
"com_ui_yes": "Jah",
|
||||
"com_ui_zoom": "Suumi",
|
||||
"com_user_message": "Sina",
|
||||
|
|
|
|||
|
|
@ -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_info": "אפשר לסייען לאחזר מידע או לבצע פעולות באמצעות API",
|
||||
"com_assistants_add_actions": "הוסף פעולות",
|
||||
"com_assistants_add_tools": "הוסף כלים",
|
||||
"com_assistants_allow_sites_you_trust": "אפשר רק אתרים שאתה סומך עליהם.",
|
||||
"com_assistants_append_date": "הוסף תאריך ושעה נוכחיים",
|
||||
"com_assistants_append_date_tooltip": "כשמופעל, תאריך ושעה נוכחיים של הלקוח יוספים להוראות מערכת הסייען.",
|
||||
"com_assistants_code_interpreter": "מתורגמן קוד",
|
||||
"com_assistants_code_interpreter_files": "הקבצים הבאים זמינים רק עבור מתורגמן קוד:",
|
||||
"com_assistants_attempt_info": "הסייען רוצה לשלוח את הדברים הבאים:",
|
||||
"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_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_knowledge": "ידע",
|
||||
"com_assistants_knowledge_disabled": "יש ליצור סייען, ויש להפעיל ולשמור את מתורגמן קוד או אחזור לפני העלאת קבצים כ-ידע.",
|
||||
"com_assistants_knowledge_info": "אם אתה מעלה קבצים תחת ידע, שיחות עם ה-סייען שלך עשויות לכלול תוכן מהקובץ.",
|
||||
"com_assistants_max_starters_reached": "הגעת למספר המקסימלי של תווים לפתיח לשיחות",
|
||||
"com_assistants_name_placeholder": "אופציונלי: שם הסייען",
|
||||
"com_assistants_non_retrieval_model": "חיפוש בקבצים אינו מופעל במודל הזה. אנא בחר מודל אחר",
|
||||
"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_success": "עודכן בהצלחה",
|
||||
"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_here": "לחץ כאן",
|
||||
"com_auth_continue": "המשך",
|
||||
|
|
@ -30,12 +77,23 @@
|
|||
"com_auth_email_min_length": "אימייל (דוא\"ל) חייב להיות בן 6 תווים לפחות",
|
||||
"com_auth_email_pattern": "עליך להזין כתובת אימייל (דוא\"ל) חוקית",
|
||||
"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_invalid_reset_token": "אסימון איפוס הסיסמה הזה אינו תקף עוד.",
|
||||
"com_auth_error_login": "לא ניתן להתחבר עם המידע שסופק. אנא בדוק את האישורים שלך ונסה שוב.",
|
||||
"com_auth_error_login_ban": "החשבון שלך נחסם באופן זמני עקב הפרות של השירות שלנו.",
|
||||
"com_auth_error_login_rl": "יותר מדי ניסיונות כניסה בזמן קצר. בבקשה נסה שוב מאוחר יותר.",
|
||||
"com_auth_error_login_server": "הייתה שגיאת שרת פנימית. אנא המתן מספר רגעים ונסה שוב.",
|
||||
"com_auth_error_login_unverified": "הדוא\"ל שלך לא אומת. אנא חפש בדוא\"ל שלך קישור לאימות.",
|
||||
"com_auth_facebook_login": "המשך עם פייסבוק",
|
||||
"com_auth_full_name": "שם מלא",
|
||||
"com_auth_github_login": "המשך עם Github",
|
||||
|
|
@ -54,7 +112,10 @@
|
|||
"com_auth_password_min_length": "הסיסמה חייבת להיות בת 8 תווים לפחות",
|
||||
"com_auth_password_not_match": "הסיסמאות אינן תואמות",
|
||||
"com_auth_password_required": "נדרשת סיסמה",
|
||||
"com_auth_registration_success_generic": "אנא בדוק את הדוא\"ל שלך כדי לאמת את כתובת הדוא\"ל שלך.",
|
||||
"com_auth_registration_success_insecure": "ההרשמה הצליחה",
|
||||
"com_auth_reset_password": "אפס את הסיסמה שלך",
|
||||
"com_auth_reset_password_if_email_exists": "אם קיים חשבון עם דוא\"ל זה, נשלח דוא\"ל עם הוראות לאיפוס סיסמה. אנא הקפד לבדוק גם בתיקיית הספאם שלך.",
|
||||
"com_auth_reset_password_link_sent": "אימייל (דוא\"ל) נשלח",
|
||||
"com_auth_reset_password_success": "איפוס סיסמה הצליח",
|
||||
"com_auth_sign_in": "כניסה",
|
||||
|
|
@ -66,15 +127,21 @@
|
|||
"com_auth_username_max_length": "שם המשתמש חייב להיות פחות מ-20 תווים",
|
||||
"com_auth_username_min_length": "שם משתמש חייב להיות לפחות 2 תווים",
|
||||
"com_auth_welcome_back": "ברוכים הבאים",
|
||||
"com_click_to_download": "(לחץ כאן להורדה)",
|
||||
"com_download_expired": "(פג תוקף ההורדה)",
|
||||
"com_download_expires": "(לחץ כאן כדי להוריד - יפוג בעוד {{0}}) ",
|
||||
"com_endpoint": "נקודת קצה",
|
||||
"com_endpoint_agent": "סוכן",
|
||||
"com_endpoint_agent_model": "מודל סוכן (מומלץ: GPT-3.5)",
|
||||
"com_endpoint_agent_placeholder": "אנא בחר סוכן",
|
||||
"com_endpoint_anthropic_maxoutputtokens": "מספר האסימונים המרבי שניתן להפיק בתגובה. ציין ערך נמוך יותר עבור תגובות קצרות יותר וערך גבוה יותר עבור תגובות ארוכות יותר.",
|
||||
"com_endpoint_anthropic_prompt_cache": "שמירת מטמון מהירה מאפשרת שימוש חוזר בהקשר גדול או בהוראות בקריאות API, תוך הפחתת העלויות וההשהייה",
|
||||
"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_topp": "Top-p משנה את האופן שבו המודל בוחר אסימונים לפלט. אסימונים נבחרים מבין רוב K (ראה פרמטר topK) הסביר לפחות עד שסכום ההסתברויות שלהם שווה לערך העליון-p.",
|
||||
"com_endpoint_assistant": "סייען",
|
||||
"com_endpoint_assistant_model": "מודל סייען",
|
||||
"com_endpoint_assistant_placeholder": "אנא בחר סייען מלוח הצד הימני",
|
||||
"com_endpoint_completion": "השלמה",
|
||||
"com_endpoint_completion_model": "מודל השלמה (מומלץ: GPT-4)",
|
||||
"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_success": "מפתח JSON של חשבון שירות יובא בהצלחה",
|
||||
"com_endpoint_config_key_name": "מפתח",
|
||||
"com_endpoint_config_key_never_expires": "המפתח שלך לא יפוג לעולם",
|
||||
"com_endpoint_config_placeholder": "הגדר את המפתח שלך בתפריט הכותרת לצאט.",
|
||||
"com_endpoint_config_value": "הזן ערך עבור",
|
||||
"com_endpoint_context": "הקשר",
|
||||
"com_endpoint_context_info": "המספר המרבי של הטוקנים שניתן להשתמש בהם בחלון ההקשר. השתמש בזה כדי לשלוט בכמה טוקנים ישלחו בכל בקשה. אם לא צוין, יתבצע שימוש בברירת המחדל של המערכת המבוססות על גודל חלון ההקשר ברירת המחדל של המודלים. הגדרת ערכים גבוהים יותר עלולה לגרום לשגיאות ו/או עלות טוקנים גבוהה יותר.",
|
||||
"com_endpoint_context_tokens": "מקסימום טוקנים בחלון ההקשר",
|
||||
"com_endpoint_custom_name": "שם מותאם אישית",
|
||||
"com_endpoint_default": "default",
|
||||
"com_endpoint_default": "ברירת מחדל",
|
||||
"com_endpoint_default_blank": "ברירת מחדל: ריק",
|
||||
"com_endpoint_default_empty": "ברירת מחדל: ריקה",
|
||||
"com_endpoint_default_with_num": "ברירת מחדל: {{0}}",
|
||||
"com_endpoint_examples": "הגדרות קבועות מראש",
|
||||
"com_endpoint_export": "ייצוא",
|
||||
"com_endpoint_export_share": "ייצא/שתף",
|
||||
"com_endpoint_frequency_penalty": "עונש תדירות",
|
||||
"com_endpoint_func_hover": "אפשר שימוש בפלאגינים כפונקציות OpenAI",
|
||||
"com_endpoint_google_custom_name_placeholder": "הגדר שם מותאם אישית עבור Google",
|
||||
|
|
@ -116,6 +187,7 @@
|
|||
"com_endpoint_instructions_assistants_placeholder": "עובר את הוראות הסייען. זה שימושי לשינוי ההתנהגות על בסיס ריצה.",
|
||||
"com_endpoint_max_output_tokens": "אסימוני פלט מרבי",
|
||||
"com_endpoint_message": "הודעה",
|
||||
"com_endpoint_message_new": "הודעה {{0}}",
|
||||
"com_endpoint_message_not_appendable": "ערוך את ההודעה שלך או צור מחדש.",
|
||||
"com_endpoint_my_preset": "ההגדרה המוגדרת מראש שלי",
|
||||
"com_endpoint_no_presets": "אין עדיין הגדרות מוגדרות מראש, השתמש בלחצן ההגדרות כדי ליצור אחת",
|
||||
|
|
@ -124,19 +196,25 @@
|
|||
"com_endpoint_openai_detail": "ההחלטה לבקשות חזון. \"נמוך\" זול ומהיר יותר, \"גבוה\" מפורט ויקר יותר, ו\"אוטומטי\" יבחר אוטומטית בין השניים על סמך רזולוציית התמונה.",
|
||||
"com_endpoint_openai_freq": "מספר בין -2.0 ל-2.0. ערכים חיוביים מענישים אסימונים חדשים בהתבסס על התדירות הקיימת שלהם בטקסט עד כה, ומקטינים את הסבירות של המודל לחזור על אותה שורה מילה במילה.",
|
||||
"com_endpoint_openai_max": "האסימונים המקסימליים להפיק. האורך הכולל של אסימוני קלט ואסימונים שנוצרו מוגבל על ידי אורך ההקשר של המודל.",
|
||||
"com_endpoint_openai_max_tokens": "שדה 'max_tokens' אופציונלי, הוא מייצג את המספר המרבי של טוקנים שניתן ליצור בהשלמת הצ'אט. האורך הכולל של טוקני קלט והטוקנים שנוצרו מוגבל על ידי אורך ההקשר של המודל. אתה עלול להיתקל בשגיאות אם המספר הזה חורג מטוקני ההקשר המקסימליים.",
|
||||
"com_endpoint_openai_pres": "מספר בין -2.0 ל-2.0. ערכים חיוביים מענישים אסימונים חדשים על סמך האם הם מופיעים בטקסט עד כה, ומגדילים את הסבירות של המודל לדבר על נושאים חדשים.",
|
||||
"com_endpoint_openai_prompt_prefix_placeholder": "הגדר הוראות מותאמות אישית לכלול בהודעת המערכת. ברירת מחדל: אין",
|
||||
"com_endpoint_openai_reasoning_effort": "במודלים o1 בלבד: מגביל את מאמץ ההנמקה במודלים של הגיון. הפחתת מאמץ החשיבה יכולה לגרום לתגובות מהירות יותר ולפחות טוקנים בשימוש בהנמקה בתגובה.",
|
||||
"com_endpoint_openai_resend": "שלח שוב את כל התמונות שצורפו בעבר. הערה: זה יכול להגדיל משמעותית את עלות האסימונים ואתה עלול להיתקל בשגיאות עם קבצים מצורפים רבים של תמונות.",
|
||||
"com_endpoint_openai_resend_files": "שלח שוב את כל הקבצים שצורפו בעבר. הערה: זה יגדיל את עלות הטוקנים, ואתה עלול להיתקל בשגיאות עם קבצים מצורפים רבים.",
|
||||
"com_endpoint_openai_stop": "עד 4 רצפים שבהם ה-API יפסיק לייצר טוקנים נוספים.",
|
||||
"com_endpoint_openai_temp": "ערכים גבוהים יותר = יותר אקראיים, בעוד שערכים נמוכים יותר = יותר ממוקד ודטרמיניסטי. אנו ממליצים לשנות את זה או את Top P אבל לא את שניהם.",
|
||||
"com_endpoint_openai_topp": "חלופה לדגימה עם טמפרטורה, הנקראת דגימת גרעין, שבה המודל מחשיב את תוצאות האסימונים עם מסת ההסתברות top_p. אז 0.1 אומר שרק האסימונים המהווים את מסת ההסתברות העליונה של 10% נחשבים. אנו ממליצים לשנות את זה או את הטמפרטורה אבל לא את שניהם.",
|
||||
"com_endpoint_output": "פלט",
|
||||
"com_endpoint_plug_image_detail": "פרטי תמונה",
|
||||
"com_endpoint_plug_resend_files": "שלח שוב את הקובץ",
|
||||
"com_endpoint_plug_set_custom_instructions_for_gpt_placeholder": "הגדר הוראות מותאמות אישית לכלול בהודעת המערכת. ברירת מחדל: אין",
|
||||
"com_endpoint_plug_skip_completion": "השלמת דילוג",
|
||||
"com_endpoint_plug_use_functions": "השתמש בפונקציות",
|
||||
"com_endpoint_presence_penalty": "עונש נוכחות",
|
||||
"com_endpoint_preset": "preset",
|
||||
"com_endpoint_preset_default": "הוא כעת ברירת המחדל המוגדרת מראש.",
|
||||
"com_endpoint_preset": "הגדרה קבועה מראש",
|
||||
"com_endpoint_preset_custom_name_placeholder": "אין אפשרות להשאיר את השדה הזה ריק, חייב לביות כאן ערך",
|
||||
"com_endpoint_preset_default": "מוגדר כמו הגדרות ברירת המחדל המוגדרת מראש.",
|
||||
"com_endpoint_preset_default_item": "ברירת מחדל:",
|
||||
"com_endpoint_preset_default_none": "אין ברירת מחדל פעילה.",
|
||||
"com_endpoint_preset_default_removed": "איננו עוד ברירת המחדל המוגדרת מראש.",
|
||||
|
|
@ -151,31 +229,87 @@
|
|||
"com_endpoint_preset_title": "הגדרה מראש",
|
||||
"com_endpoint_presets": "presets",
|
||||
"com_endpoint_presets_clear_warning": "האם אתה בטוח שאתה רוצה לנקות את כל הקביעות המוגדרות מראש? זה בלתי הפיך.",
|
||||
"com_endpoint_prompt_cache": "השתמש בשמירה במטמון של הנחיות (פרומפטים)",
|
||||
"com_endpoint_prompt_prefix": "הוראות מותאמות אישית",
|
||||
"com_endpoint_prompt_prefix_assistants": "הוראות נוספות",
|
||||
"com_endpoint_prompt_prefix_assistants_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_skip_hover": "אפשר דילוג על שלב ההשלמה, הסוקר את התשובה הסופית ואת השלבים שנוצרו",
|
||||
"com_endpoint_stop": "רצף לעצירה",
|
||||
"com_endpoint_stop_placeholder": "הפרד ערכים על ידי לחיצה על 'Enter'",
|
||||
"com_endpoint_temperature": "טמפרטורה",
|
||||
"com_endpoint_top_k": "Top K",
|
||||
"com_endpoint_top_p": "Top P",
|
||||
"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_nav_archive_created_at": "תאריך יצרן",
|
||||
"com_nav_account_settings": "הגדרות חשבון",
|
||||
"com_nav_always_make_prod": "ייצר תמיד גרסאות חדשות",
|
||||
"com_nav_archive_created_at": "תאריך ייצור",
|
||||
"com_nav_archive_name": "שם",
|
||||
"com_nav_archived_chats": "שיחות מארכיון",
|
||||
"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_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_browser": "דפדפן",
|
||||
"com_nav_buffer_append_error": "בעיה בהזרמת אודיו. ההשמעה עשויה להיות מקוטעת.",
|
||||
"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_cache_confirm_message": "האם אתה בטוח שברצונך לנקות את המטמון?",
|
||||
"com_nav_clear_conversation": "נקה שיחות",
|
||||
"com_nav_clear_conversation_confirm_message": "אתה בטוח שאתה רוצה לנקות את כל השיחות? זה בלתי הפיך.",
|
||||
"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_engine": "מנוע",
|
||||
"com_nav_enter_to_send": "הקש Enter כדי לשלוח את ההודעה",
|
||||
"com_nav_export": "ייצא",
|
||||
"com_nav_export_all_message_branches": "ייצא את כל ענפי ההודעות",
|
||||
"com_nav_export_conversation": "ייצא שיחה",
|
||||
|
|
@ -185,149 +319,405 @@
|
|||
"com_nav_export_recursive": "רקורסיבי",
|
||||
"com_nav_export_recursive_or_sequential": "רקורסיבי או רציף?",
|
||||
"com_nav_export_type": "סוג",
|
||||
"com_nav_external": "חיצוני",
|
||||
"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_hide_panel": "הסתר לוח הצד הימני ביותר",
|
||||
"com_nav_lang_arabic": "العربية",
|
||||
"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_info_custom_prompt_mode": "כאשר אפשרות זו מופעלת, הנחיית ברירת המחדל של מערכת רכיבי תצוגה לא תיכלל. כל ההוראות ליצירת רכיבי תצוגה יהיו חייבות להינתן באופן ידני במצב זה.",
|
||||
"com_nav_info_enter_to_send": "כאשר מופעל, לחיצה על \"ENTER\" תשלח את ההודעה שלך, כאשר מושבת לחיצה על \"Enter\" תוסיף שורה חדשה, ותצטרך ללחוץ על \"CTRL + ENTER\" כדי לשלוח את ההודעה.",
|
||||
"com_nav_info_fork_change_default": "'הודעות ישירות בלבד' כולל רק את הנתיב הישיר להודעה שנבחרה. 'כלול הסתעפויות קשורות' מוסיף את כל ההסתעפויות הקשורות לאורך הנתיב. 'כלול הכל עד כאן/מכאן' כולל את כל ההודעות וההסתעפויות המחוברות.",
|
||||
"com_nav_info_fork_split_target_setting": "כאשר אפשרות זו מופעלת, הפיצול יתחיל מהודעת היעד ועד להודעה האחרונה בשיחה, בהתאם להתנהגות שנבחרה",
|
||||
"com_nav_info_include_shadcnui": "כאשר אפשרות זו מופעלת, ייכללו הוראות לשימוש ברכיבי shadcn/ui. shadcn/ui הוא אוסף של רכיבים לשימוש חוזר שנבנו באמצעות Radix UI ו-Tailwind CSS.\nהערה: ההוראות הללו ארוכות, ולכן כדאי להפעיל אותן רק אם חשוב לך ליידע את מודל ה-LLM (מודל השפה) על הייבוא והרכיבים הנכונים.\nלמידע נוסף על רכיבים אלה, בקר בכתובת: https://ui.shadcn.com/",
|
||||
"com_nav_info_latex_parsing": "כאשר אפשרות זו מופעלת, קוד LaTeX בהודעות יעובד ויוצג כמשוואות מתמטיות. השבתת אפשרות זו עשויה לשפר את הביצועים אם אינך זקוק לעיבוד LaTeX.",
|
||||
"com_nav_info_save_draft": "כאשר אפשרות זו מופעלת, הטקסט והקבצים המצורפים שאתה מזין בטופס הצ'אט יישמרו באופן אוטומטי כטיוטות במכשיר שלך. טיוטות אלו יהיו זמינות גם אם תטען מחדש את הדף או תעבור לשיחה אחרת. הטיוטות נשמרות באופן מקומי במכשיר שלך ונמחקות לאחר שליחת ההודעה.",
|
||||
"com_nav_info_show_thinking": "כאשר אפשרות זו מופעלת, תיבות תצוגה שמציגות את תהליך החשיבה של הבינה המלאכותית יופיעו פתוחות כברירת מחדל, כך שתוכל לראות את תהליך הניתוח בזמן אמת. כאשר האפשרות מושבתת, תיבות הבחירה יישארו סגורות כברירת מחדל, מה שיוצר ממשק נקי וזורם יותר.",
|
||||
"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_indonesia": "Indonesia",
|
||||
"com_nav_lang_italian": "Italiano",
|
||||
"com_nav_lang_japanese": "日本語",
|
||||
"com_nav_lang_korean": "한국어",
|
||||
"com_nav_lang_polish": "Polski",
|
||||
"com_nav_lang_portuguese": "Português",
|
||||
"com_nav_lang_russian": "Русский",
|
||||
"com_nav_lang_spanish": "Español",
|
||||
"com_nav_lang_swedish": "Svenska",
|
||||
"com_nav_lang_traditional_chinese": "繁體中文",
|
||||
"com_nav_lang_turkish": "Türkçe",
|
||||
"com_nav_lang_vietnamese": "Tiếng Việt",
|
||||
"com_nav_lang_indonesia": "אינדונזית (Indonesia)",
|
||||
"com_nav_lang_italian": "איטלקית (Italiano)",
|
||||
"com_nav_lang_japanese": "יפנית (日本語)",
|
||||
"com_nav_lang_korean": "קוראנית (한국어)",
|
||||
"com_nav_lang_polish": "פולנית (Polski)",
|
||||
"com_nav_lang_portuguese": "פורטוגזית (Português)",
|
||||
"com_nav_lang_russian": "רוסית (Русский)",
|
||||
"com_nav_lang_spanish": "ספרדית (Español)",
|
||||
"com_nav_lang_swedish": "שוודית (Svenska)",
|
||||
"com_nav_lang_traditional_chinese": "סינית מסורתית (繁體中文)",
|
||||
"com_nav_lang_turkish": "טורקית (Türkçe)",
|
||||
"com_nav_lang_vietnamese": "וייטנאמית (Tiếng Việt)",
|
||||
"com_nav_language": "שפה",
|
||||
"com_nav_latex_parsing": "ניתוח LaTeX בהודעות (עשוי להשפיע על הביצועים)",
|
||||
"com_nav_log_out": "צא",
|
||||
"com_nav_long_audio_warning": "העיבוד של טקסטים ארוכים ייקח יותר זמן.",
|
||||
"com_nav_maximize_chat_space": "הגדל את שטח הצ'אט",
|
||||
"com_nav_modular_chat": "אפשר החלפת נקודות קצה באמצע שיחה",
|
||||
"com_nav_my_files": "הקבצים שלי",
|
||||
"com_nav_no_search_results": "לא נמצאו תוצאות בחיפוש",
|
||||
"com_nav_not_supported": "לא נתמך",
|
||||
"com_nav_open_sidebar": "פתח סרגל צד",
|
||||
"com_nav_playback_rate": "קצב השמעת אודיו",
|
||||
"com_nav_plugin_auth_error": "אירעה שגיאה בניסיון לאמת את הפלאגין הזה. בבקשה נסה שוב.",
|
||||
"com_nav_plugin_install": "התקן",
|
||||
"com_nav_plugin_search": "תוספי חיפוש",
|
||||
"com_nav_plugin_store": "חנות פלאגין",
|
||||
"com_nav_plugin_uninstall": "הסר התקנה",
|
||||
"com_nav_plus_command": "פקודת+-",
|
||||
"com_nav_plus_command_description": "הפעל או בטל את הפקודה '+' כדי להוסיף הגדרת תגובות מרובות",
|
||||
"com_nav_profile_picture": "תמונת פרופיל",
|
||||
"com_nav_save_drafts": "שמיר את האפצה באותו מחשב",
|
||||
"com_nav_scroll_button": "לחצן לגלילה עד הסוף",
|
||||
"com_nav_search_placeholder": "חפש הודעות",
|
||||
"com_nav_send_message": "שלח הודעה",
|
||||
"com_nav_setting_account": "חשבון",
|
||||
"com_nav_setting_beta": "תכונות ביטא",
|
||||
"com_nav_setting_chat": "צ'אט",
|
||||
"com_nav_setting_data": "בקרות נתונים",
|
||||
"com_nav_setting_general": "כללי",
|
||||
"com_nav_setting_speech": "דיבור",
|
||||
"com_nav_settings": "הגדרות",
|
||||
"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_dark": "כהה",
|
||||
"com_nav_theme_light": "אור",
|
||||
"com_nav_theme_system": "מערכת",
|
||||
"com_nav_tool_dialog": "כלי סייען",
|
||||
"com_nav_tool_dialog_agents": "כלי סוכנים",
|
||||
"com_nav_tool_dialog_description": "יש לשמור את האסיסטנט כדי להמשיך בבחירת הכלים.",
|
||||
"com_nav_tool_remove": "הסר",
|
||||
"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_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_completion_settings": "הצג הגדרות השלמה",
|
||||
"com_show_examples": "הצג דוגמאות",
|
||||
"com_sidepanel_agent_builder": "בניית סוכן",
|
||||
"com_sidepanel_assistant_builder": "בניית סייען",
|
||||
"com_sidepanel_attach_files": "צרף קבצים",
|
||||
"com_sidepanel_conversation_tags": "סימניות",
|
||||
"com_sidepanel_hide_panel": "הסתר פאנל",
|
||||
"com_sidepanel_manage_files": "נהל קבצים",
|
||||
"com_sidepanel_parameters": "פרמטרים",
|
||||
"com_sidepanel_select_agent": "בחר סוכן",
|
||||
"com_sidepanel_select_assistant": "בחר סייען",
|
||||
"com_ui_accept": "אני מקבל",
|
||||
"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_proper": "הכל",
|
||||
"com_ui_analyzing": "ניתוח",
|
||||
"com_ui_analyzing_finished": "סיים ניתוח",
|
||||
"com_ui_api_key": "מפתח API",
|
||||
"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_delete_error": "אירעה שגיאה בעת מחיקת הסייען",
|
||||
"com_ui_assistant_deleted": "הסייען נמחק בהצלחה",
|
||||
"com_ui_assistants": "סייענים",
|
||||
"com_ui_assistants_output": "פלט סייענים",
|
||||
"com_ui_attach_error": "לא ניתן לצרף קובץ. צור או בחר שיחה, או נסה לרענן את הדף.",
|
||||
"com_ui_attach_error_openai": "לא ניתן לצרף את קבצי הסייען לנקודות קצה אחרות",
|
||||
"com_ui_attach_error_size": "חרגת ממגבלת גודל הקובץ עבור נקודת הקצה:",
|
||||
"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_bookmarks": "סימניות",
|
||||
"com_ui_bookmarks_add": "הוסף סימניות",
|
||||
"com_ui_bookmarks_add_to_conversation": "הוסף לשיחה הנוכחית",
|
||||
"com_ui_bookmarks_count": "ספירה",
|
||||
"com_ui_bookmarks_create_error": "אירעה שגיאה בעת יצירת הסימניה",
|
||||
"com_ui_bookmarks_create_exists": "סימניה זו כבר קיימת",
|
||||
"com_ui_bookmarks_create_success": "הסימניה נוצרה בהצלחה",
|
||||
"com_ui_bookmarks_delete": "מחק סימ",
|
||||
"com_ui_bookmarks_delete_error": "אירעה שגיאה בעת מחיקת הסימניה",
|
||||
"com_ui_bookmarks_delete_success": "הסימניה נמחקה בהצלחה",
|
||||
"com_ui_bookmarks_description": "תיאור",
|
||||
"com_ui_bookmarks_edit": "ערוך סימניה",
|
||||
"com_ui_bookmarks_filter": "סינון סימניות...",
|
||||
"com_ui_bookmarks_new": "סימניה חדשה",
|
||||
"com_ui_bookmarks_title": "כותרת",
|
||||
"com_ui_bookmarks_update_error": "אירעה שגיאה בעת עדכון הסימניה",
|
||||
"com_ui_bookmarks_update_success": "הסימניה עודכנה בהצלחה",
|
||||
"com_ui_bulk_delete_error": "מחיקת קישורים משותפים נכשלה",
|
||||
"com_ui_callback_url": "כתובת URL להחזרת המידע",
|
||||
"com_ui_cancel": "בטל",
|
||||
"com_ui_chat": "צ'אט",
|
||||
"com_ui_chat_history": "נקה היסטוריה",
|
||||
"com_ui_clear": "נקה",
|
||||
"com_ui_clear_all": "נקה הכל",
|
||||
"com_ui_client_id": "מזהה לקוח",
|
||||
"com_ui_client_secret": "ב",
|
||||
"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_admin_use_change": "שינוי הגדרה זו יחסום גישה למנהלים, כולל אותך. האם אתה בטוח שברצונך להמשיך?",
|
||||
"com_ui_confirm_change": "אשר את השינוי",
|
||||
"com_ui_context": "הקשר",
|
||||
"com_ui_continue": "המשך",
|
||||
"com_ui_controls": "פקדים",
|
||||
"com_ui_copied": "הועתק!",
|
||||
"com_ui_copied_to_clipboard": "הועתק ללוח",
|
||||
"com_ui_copy_code": "העתק קוד",
|
||||
"com_ui_copy_link": "העתק קישור",
|
||||
"com_ui_copy_to_clipboard": "העתק ללוח",
|
||||
"com_ui_create": "צור",
|
||||
"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_default_post_request": "ברירת המחדל (בקשת POST)",
|
||||
"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_confirm": "זה ימחק",
|
||||
"com_ui_delete_confirm_prompt_version_var": "פעולה זו תמחק את הגרסה שנבחרה עבור \"{{0}}\". אם לא קיימות גרסאות נוספות, ההנחיה תימחק.",
|
||||
"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_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_empty_category": "-",
|
||||
"com_ui_endpoint": "נקודת קצה",
|
||||
"com_ui_endpoint_menu": "תפריט נקודת קצה LLM",
|
||||
"com_ui_endpoints_available": "נקודות קצה זמינות",
|
||||
"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_connection": "שגיאה בחיבור לשרת, נסה לרענן את הדף",
|
||||
"com_ui_error_save_admin_settings": "אירעה שגיאה בשמירת הגדרות הניהול שלך",
|
||||
"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_host": "מארח",
|
||||
"com_ui_import_conversation_error": "אירעה שגיאה בעת ייבוא השיחות שלך",
|
||||
"com_ui_import_conversation_info": "ייבא שיחות מקובץ JSON",
|
||||
"com_ui_import_conversation_success": "השיחות יובאו בהצלחה",
|
||||
"com_ui_input": "קלט",
|
||||
"com_ui_instructions": "הוראות",
|
||||
"com_ui_latest_version": "גרסה אחרונה",
|
||||
"com_ui_loading": "טוען...",
|
||||
"com_ui_locked": "נעול",
|
||||
"com_ui_manage": "נהל",
|
||||
"com_ui_model": "דגם",
|
||||
"com_ui_more_info": "מידע נוסף",
|
||||
"com_ui_name": "שם",
|
||||
"com_ui_new_chat": "שיחה חדשה",
|
||||
"com_ui_next": "הבא",
|
||||
"com_ui_no": "לא",
|
||||
"com_ui_no_category": "אין קטגוריה",
|
||||
"com_ui_no_terms_content": "אין תוכן תנאים והגבלות להצגה",
|
||||
"com_ui_of": "של",
|
||||
"com_ui_off": "של",
|
||||
"com_ui_page": "עמוד",
|
||||
"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_rename": "שם מחדש",
|
||||
"com_ui_rename": "שנה שם",
|
||||
"com_ui_rename_prompt": "שנה שם הנחיה (פרומפט)",
|
||||
"com_ui_revoke": "בטל",
|
||||
"com_ui_revoke_info": "בטל את כל האישורים שסופקו על ידי המשתמש",
|
||||
"com_ui_save": "שמור",
|
||||
"com_ui_save_submit": "שמור ושלח",
|
||||
"com_ui_saved": "שמור!",
|
||||
"com_ui_schema": "סכמה",
|
||||
"com_ui_scope": "תחום",
|
||||
"com_ui_search": "חיפוש",
|
||||
"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_create_message": "שמך וכל הודעה שתוסיף לאחר השיתוף יישארו פרטיים.",
|
||||
"com_ui_share_delete_error": "אירעה שגיאה בעת מחיקת הקישור המשותף.",
|
||||
"com_ui_share_error": "אירעה שגיאה בעת שיתוף קישור הצ'אט",
|
||||
"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_shared_link_not_found": "Shared link not found",
|
||||
"com_ui_share_to_all_users": "שתף עם כל המשתמשים",
|
||||
"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_storage": "אחסון",
|
||||
"com_ui_submit": "שלח",
|
||||
"com_ui_teach_or_explain": "למידה",
|
||||
"com_ui_temporary_chat": "צ'אט זמני",
|
||||
"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_error": "אירעה שגיאה בארכיון השיחה",
|
||||
"com_ui_unknown": "לא ידוע",
|
||||
"com_ui_update": "עדכון",
|
||||
"com_ui_upload": "העלה",
|
||||
"com_ui_upload_error": "אירעה שגיאה בהעלאת הקובץ שלך",
|
||||
"com_ui_upload_files": "העלה קבצים",
|
||||
"com_ui_upload_success": "קובץ שהועלה בהצלחה",
|
||||
"com_ui_use_prompt": "השתמש בהודעת",
|
||||
"com_user_message": "אתה"
|
||||
"com_ui_upload_image": "העלה תמונה",
|
||||
"com_ui_upload_image_input": "העלה תמונה",
|
||||
"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
20
package-lock.json
generated
|
|
@ -1095,7 +1095,7 @@
|
|||
"react-i18next": "^15.4.0",
|
||||
"react-lazy-load-image-component": "^1.6.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-resizable-panels": "^2.1.1",
|
||||
"react-resizable-panels": "^2.1.7",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"react-speech-recognition": "^3.10.0",
|
||||
"react-textarea-autosize": "^8.4.0",
|
||||
|
|
@ -1609,6 +1609,15 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"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": {
|
||||
"version": "4.34.6",
|
||||
"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": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.0.tgz",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue