+
diff --git a/public/locales/ru-ru.json b/public/locales/ru-ru.json
index a633db208..cd8068a98 100644
--- a/public/locales/ru-ru.json
+++ b/public/locales/ru-ru.json
@@ -1720,7 +1720,7 @@
"Proxy Preset": "Пресет для прокси",
"Enter a name:": "Введите название:",
"Are you sure you want to delete the selected profile?": "Вы точно хотите удалить выбранный профиль?",
- "instruct_enabled": "Включить Instruct-режим",
+ "instruct_enabled": "Вкл/выкл Instruct-режим",
"Instruct Template": "Шаблон Instruct-режима",
"instruct_template_activation_regex_desc": "Автоматически активировать этот шаблон в момент подключения к API или выбора модели, если название модели соответствует этому рег. выражению.",
"instruct_bind_to_context": "При включении этой опции Шаблон контекста будет выбираться, исходя из выбранного в текущий момент Шаблона Instruct-режима, либо по вашему желанию.",
@@ -1730,11 +1730,11 @@
"Export Advanced Formatting settings": "Экспорт настроек Расширенного форматирования",
"Select your current System Prompt": "Выберите текущий системный промпт",
"Prompt Content": "Текст промпта",
- "Update current prompt": "Обновить текущий промпт",
+ "Update current prompt": "Сохранить промпт",
"Save prompt as": "Сохранить как...",
"Import template": "Импорт шаблона",
"Export template": "Экспорт шаблона",
- "Restore current prompt": "Восстановить текущий промпт",
+ "Restore current prompt": "Восстановить промпт",
"comma delimited,no spaces between": "через запятую,без пробелов в промежутках",
"User Message Sequences": "Строки для сообщений пользователя",
"Assistant Message Sequences": "Строки для сообщений ассистента",
@@ -1757,7 +1757,7 @@
"Preset was not deleted from server": "Пресет не удалён с сервера",
"Preset deleted": "Пресет удалён",
"Delete the preset?": "Удалить пресет?",
- "Preset updated": "Пресет обновлён",
+ "Preset updated": "Пресет сохранён",
"Entered reverse proxy address is not a valid URL": "Введённый адрес прокси невалиден",
"An error occurred while counting tokens: Token budget exceeded.": "Ошибка при подсчёте токенов: Превышен бюджет токенов",
"An error occurred while counting tokens: Invalid character name": "Ошибка при подсчёте токенов: Невалидное имя персонажа",
@@ -1893,5 +1893,71 @@
"Base": "Основание",
"DRY_Base_desc": "Определяет, насколько быстро возрастает штраф с увеличением длины строки.",
"Allowed Length": "Допустимая длина",
- "DRY_Allowed_Length_desc": "Длина повторяющейся строки, при превышении которой DRY начинает налагать штраф."
+ "DRY_Allowed_Length_desc": "Длина повторяющейся строки, при превышении которой DRY начинает налагать штраф.",
+ "Invalid data provided for master import": "Глоб. импорт не может быть выполнен по причине невалидности данных",
+ "Importing instruct template...": "Импортируем...",
+ "Instruct template detected": "Обнаружен шаблон Instruct-режима",
+ "Importing as context template...": "Импортируем...",
+ "Context template detected": "Обнаружен шаблон контекста",
+ "Importing as system prompt...": "Импортируем...",
+ "System prompt detected": "Обнаружен системный промпт",
+ "Importing as settings preset...": "Импортируем...",
+ "Text Completion settings detected": "Обнаружены настройки Text Completion",
+ "No valid sections found in imported data": "Не найдено ни одной валидной секции данных",
+ "No sections selected for import": "Не выбрано ни одной секции для импорта",
+ "Import": "Импортировать",
+ "Imported ${0} settings: ${1}": "Импортировано ${0} настроек: ${1}",
+ "Export": "Экспортировать",
+ "No sections selected for export": "Не выбрано ни одной секции для экспорта",
+ "Cannot update GUI preset": "Пресет для GUI обновить невозможно",
+ "Template updated": "Шаблон сохранён",
+ "Hint: Use a character/group name to bind preset to a specific chat.": "Совет: введите имя персонажа/группы, чтобы привязать пресет к определённому чату.",
+ "Preset name:": "Название пресета:",
+ "Template name:": "Название шаблона:",
+ "Preset saved": "Пресет сохранён",
+ "Template saved": "Шаблон сохранён",
+ "Preset could not be saved": "Не удалось сохранить пресет",
+ "Preset could not be renamed": "Не удалось обновить пресет",
+ "Preset renamed": "Пресет переименован",
+ "Template renamed": "Шаблон переименован",
+ "Cannot delete GUI preset": "Пресет для GUI удалить невозможно",
+ "Failed to restore default preset": "Не удалось восстановить пресет по умолчанию",
+ "Failed to restore default template": "Не удалось восстановить шаблон по умолчанию",
+ "Rename preset": "Переименовать пресет",
+ "Rename template": "Переименовать шаблон",
+ "Enter a new name:": "Введите новое название:",
+ "Preset imported": "Пресет импортирован",
+ "Template imported": "Шаблон импортирован",
+ "Delete this preset?": "Удалить этот пресет?",
+ "Delete this template?": "Удалить этот шаблон?",
+ "This action is irreversible and your current settings will be overwritten.": "Отменить это действие невозможно. Ваши текущие настройки будут перезаписаны.",
+ "Preset deleted": "Пресет удалён",
+ "Template deleted": "Шаблон удалён",
+ "Template was not deleted from server": "Шаблон не удалён с сервера",
+ "Cannot restore GUI preset": "Пресет для Gui восстановить нельзя",
+ "Default preset cannot be restored": "Невозможно восстановить пресет по умолчанию",
+ "Default template cannot be restored": "Невозможно восстановить шаблон по умолчанию",
+ "Resetting a
default preset will restore the default settings": "Сброс
стандартного пресета восстановит настройки по умолчанию.",
+ "Resetting a
default template will restore the default settings.": "Сброс
стандартного шаблона восстановит настройки по умолчанию.",
+ "Are you sure?": "Вы уверены?",
+ "Default preset restored": "Стандартный пресет восстановлен",
+ "Default template restored": "Стандартный шаблон восстановлен",
+ "Resetting a
custom preset will restore to the last saved state.": "Сброс
пользовательского пресета откатит его к последнему сохранённому состоянию.",
+ "Resetting a
custom template will restore to the last saved state.": "Сброс
пользовательского шаблона откатит его к последнему сохранённому состоянию.",
+ "Preset restored": "Пресет восстановлен",
+ "Template restored": "Шаблон восстановлен",
+ "Update current template": "Сохранить шаблон",
+ "Rename current template": "Переименовать шаблон",
+ "Save template as": "Сохранить как...",
+ "Restore current template": "Восстановить шаблон",
+ "Delete the template": "Удалить шаблон",
+ "Rename current prompt": "Переименовать промпт",
+ "Select your current Context Template": "Выберите активный шаблон контекста",
+ "Select your current Instruct Template": "Выберите активный шаблон Instruct-режима",
+ "and connect to an": "и подключитесь к",
+ "You can add more": "Можете добавить больше",
+ "from other websites": "с других сайтов.",
+ "Go to the": "Загляните в",
+ "to install additional features.": ", чтобы установить разные дополнительные ресурсы.",
+ "or_welcome": "; также доступен"
}
diff --git a/public/script.js b/public/script.js
index 8fc833666..cc3504b60 100644
--- a/public/script.js
+++ b/public/script.js
@@ -6755,7 +6755,7 @@ export async function saveSettings(type) {
eventSource.emit(event_types.SETTINGS_UPDATED);
},
error: function (jqXHR, exception) {
- toastr.error(t`Check the server connection and reload the page to prevent data loss.t`, t`Settings could not be saved`);
+ toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Settings could not be saved`);
console.log(exception);
console.log(jqXHR);
},
diff --git a/public/scripts/preset-manager.js b/public/scripts/preset-manager.js
index 1fc993af4..e25de5eec 100644
--- a/public/scripts/preset-manager.js
+++ b/public/scripts/preset-manager.js
@@ -34,6 +34,7 @@ import {
textgenerationwebui_settings as textgen_settings,
} from './textgen-settings.js';
import { download, parseJsonFile, waitUntilCondition } from './utils.js';
+import { t } from './i18n.js';
const presetManagers = {};
@@ -194,32 +195,32 @@ class PresetManager {
*/
static async performMasterImport(data, fileName) {
if (!data || typeof data !== 'object') {
- toastr.error('Invalid data provided for master import');
+ toastr.error(t`Invalid data provided for master import`);
return;
}
// Check for legacy file imports
// 1. Instruct Template
if (this.isPossiblyInstructData(data)) {
- toastr.info('Importing instruct template...', 'Instruct template detected');
+ toastr.info(t`Importing instruct template...`, t`Instruct template detected`);
return await getPresetManager('instruct').savePreset(data.name, data);
}
// 2. Context Template
if (this.isPossiblyContextData(data)) {
- toastr.info('Importing as context template...', 'Context template detected');
+ toastr.info(t`Importing as context template...`, t`Context template detected`);
return await getPresetManager('context').savePreset(data.name, data);
}
// 3. System Prompt
if (this.isPossiblySystemPromptData(data)) {
- toastr.info('Importing as system prompt...', 'System prompt detected');
+ toastr.info(t`Importing as system prompt...`, t`System prompt detected`);
return await getPresetManager('sysprompt').savePreset(data.name, data);
}
// 4. Text Completion settings
if (this.isPossiblyTextCompletionData(data)) {
- toastr.info('Importing as settings preset...', 'Text Completion settings detected');
+ toastr.info(t`Importing as settings preset...`, t`Text Completion settings detected`);
return await getPresetManager('textgenerationwebui').savePreset(fileName, data);
}
@@ -231,7 +232,7 @@ class PresetManager {
}
if (validSections.length === 0) {
- toastr.error('No valid sections found in imported data');
+ toastr.error(t`No valid sections found in imported data`);
return;
}
@@ -242,8 +243,8 @@ class PresetManager {
const html = $(await renderTemplateAsync('masterImport', { sections: sectionNames }));
const popup = new Popup(html, POPUP_TYPE.CONFIRM, '', {
- okButton: 'Import',
- cancelButton: 'Cancel',
+ okButton: t`Import`,
+ cancelButton: t`Cancel`,
});
const result = await popup.show();
@@ -257,7 +258,7 @@ class PresetManager {
const confirmedSections = html.find('input:checked').map((_, el) => el instanceof HTMLInputElement && el.value).get();
if (confirmedSections.length === 0) {
- toastr.info('No sections selected for import');
+ toastr.info(t`No sections selected for import`);
return;
}
@@ -270,7 +271,7 @@ class PresetManager {
}
}
- toastr.success(`Imported ${importedSections.length} settings: ${importedSections.join(', ')}`);
+ toastr.success(t`Imported ${importedSections.length} settings: ${importedSections.join(', ')}`);
}
/**
@@ -285,8 +286,8 @@ class PresetManager {
const html = $(await renderTemplateAsync('masterExport', { sections: sectionNames }));
const popup = new Popup(html, POPUP_TYPE.CONFIRM, '', {
- okButton: 'Export',
- cancelButton: 'Cancel',
+ okButton: t`Export`,
+ cancelButton: t`Cancel`,
});
const result = await popup.show();
@@ -300,7 +301,7 @@ class PresetManager {
const data = {};
if (confirmedSections.length === 0) {
- toastr.info('No sections selected for export');
+ toastr.info(t`No sections selected for export`);
return;
}
@@ -328,7 +329,7 @@ class PresetManager {
* @returns {any} Preset value
*/
findPreset(name) {
- return $(this.select).find('option').filter(function() {
+ return $(this.select).find('option').filter(function () {
return $(this).text() === name;
}).val();
}
@@ -354,7 +355,7 @@ class PresetManager {
* @param {string} value Preset option value
*/
selectPreset(value) {
- const option = $(this.select).filter(function() {
+ const option = $(this.select).filter(function () {
return $(this).val() === value;
});
option.prop('selected', true);
@@ -366,21 +367,21 @@ class PresetManager {
console.log(selected);
if (selected.val() == 'gui') {
- toastr.info('Cannot update GUI preset');
+ toastr.info(t`Cannot update GUI preset`);
return;
}
const name = selected.text();
await this.savePreset(name);
- const successToast = !this.isAdvancedFormatting() ? 'Preset updated' : 'Template updated';
+ const successToast = !this.isAdvancedFormatting() ? t`Preset updated` : t`Template updated`;
toastr.success(successToast);
}
async savePresetAs() {
const inputValue = this.getSelectedPresetName();
- const popupText = !this.isAdvancedFormatting() ? '
Hint: Use a character/group name to bind preset to a specific chat.
' : '';
- const headerText = !this.isAdvancedFormatting() ? 'Preset name:' : 'Template name:';
+ const popupText = !this.isAdvancedFormatting() ? '
' + t`Hint: Use a character/group name to bind preset to a specific chat.` + '
' : '';
+ const headerText = !this.isAdvancedFormatting() ? t`Preset name:` : t`Template name:`;
const name = await Popup.show.input(headerText, popupText, inputValue);
if (!name) {
console.log('Preset name not provided');
@@ -389,7 +390,7 @@ class PresetManager {
await this.savePreset(name);
- const successToast = !this.isAdvancedFormatting() ? 'Preset saved' : 'Template saved';
+ const successToast = !this.isAdvancedFormatting() ? t`Preset saved` : t`Template saved`;
toastr.success(successToast);
}
@@ -411,7 +412,7 @@ class PresetManager {
});
if (!response.ok) {
- toastr.error('Check the server connection and reload the page to prevent data loss.', 'Preset could not be saved');
+ toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Preset could not be saved`);
console.error('Preset could not be saved', response);
throw new Error('Preset could not be saved');
}
@@ -422,6 +423,19 @@ class PresetManager {
this.updateList(name, preset);
}
+ async renamePreset(newName) {
+ const oldName = this.getSelectedPresetName();
+ try {
+ await this.savePreset(newName);
+ await this.deletePreset(oldName);
+ } catch (error) {
+ toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Preset could not be renamed`);
+ console.error('Preset could not be renamed', error);
+ throw new Error('Preset could not be renamed');
+ }
+
+ }
+
getPresetList() {
let presets = [];
let preset_names = {};
@@ -585,13 +599,14 @@ class PresetManager {
return settings;
}
- async deleteCurrentPreset() {
+ // pass no arguments to delete current preset
+ async deletePreset(name) {
const { preset_names, presets } = this.getPresetList();
- const value = this.getSelectedPreset();
- const nameToDelete = this.getSelectedPresetName();
+ const value = name ? (this.isKeyedApi() ? this.findPreset(name) : name) : this.getSelectedPreset();
+ const nameToDelete = name || this.getSelectedPresetName();
if (value == 'gui') {
- toastr.info('Cannot delete GUI preset');
+ toastr.info(t`Cannot delete GUI preset`);
return;
}
@@ -605,7 +620,10 @@ class PresetManager {
delete preset_names[nameToDelete];
}
- if (Object.keys(preset_names).length) {
+ // switch in UI only when deleting currently selected preset
+ const switchPresets = !name || this.getSelectedPresetName() == name;
+
+ if (Object.keys(preset_names).length && switchPresets) {
const nextPresetName = Object.keys(preset_names)[0];
const newValue = preset_names[nextPresetName];
$(this.select).find(`option[value="${newValue}"]`).attr('selected', 'true');
@@ -629,7 +647,7 @@ class PresetManager {
});
if (!response.ok) {
- const errorToast = !this.isAdvancedFormatting() ? 'Failed to restore default preset' : 'Failed to restore default template';
+ const errorToast = !this.isAdvancedFormatting() ? t`Failed to restore default preset` : t`Failed to restore default template`;
toastr.error(errorToast);
return;
}
@@ -721,7 +739,8 @@ async function waitForConnection() {
export async function initPresetManager() {
eventSource.on(event_types.CHAT_CHANGED, autoSelectPreset);
registerPresetManagers();
- SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'preset',
+ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
+ name: 'preset',
callback: presetCommandCallback,
returns: 'current preset',
unnamedArgumentList: [
@@ -774,6 +793,29 @@ export async function initPresetManager() {
await presetManager.savePresetAs();
});
+ $(document).on('click', '[data-preset-manager-rename]', async function () {
+ const apiId = $(this).data('preset-manager-rename');
+ const presetManager = getPresetManager(apiId);
+
+ if (!presetManager) {
+ console.warn(`Preset Manager not found for API: ${apiId}`);
+ return;
+ }
+
+ const popupHeader = !presetManager.isAdvancedFormatting() ? t`Rename preset` : t`Rename template`;
+ const oldName = presetManager.getSelectedPresetName();
+ const newName = await Popup.show.input(popupHeader, t`Enter a new name:`, oldName);
+ if (!newName || oldName === newName) {
+ console.debug(!presetManager.isAdvancedFormatting() ? 'Preset rename cancelled' : 'Template rename cancelled');
+ return;
+ }
+
+ await presetManager.renamePreset(newName);
+
+ const successToast = !presetManager.isAdvancedFormatting() ? t`Preset renamed` : t`Template renamed`;
+ toastr.success(successToast);
+ });
+
$(document).on('click', '[data-preset-manager-export]', async function () {
const apiId = $(this).data('preset-manager-export');
const presetManager = getPresetManager(apiId);
@@ -816,7 +858,7 @@ export async function initPresetManager() {
data['name'] = name;
await presetManager.savePreset(name, data);
- const successToast = !presetManager.isAdvancedFormatting() ? 'Preset imported' : 'Template imported';
+ const successToast = !presetManager.isAdvancedFormatting() ? t`Preset imported` : t`Template imported`;
toastr.success(successToast);
e.target.value = null;
});
@@ -830,19 +872,19 @@ export async function initPresetManager() {
return;
}
- const headerText = !presetManager.isAdvancedFormatting() ? 'Delete this preset?' : 'Delete this template?';
- const confirm = await Popup.show.confirm(headerText, 'This action is irreversible and your current settings will be overwritten.');
+ const headerText = !presetManager.isAdvancedFormatting() ? t`Delete this preset?` : t`Delete this template?`;
+ const confirm = await Popup.show.confirm(headerText, t`This action is irreversible and your current settings will be overwritten.`);
if (!confirm) {
return;
}
- const result = await presetManager.deleteCurrentPreset();
+ const result = await presetManager.deletePreset();
if (result) {
- const successToast = !presetManager.isAdvancedFormatting() ? 'Preset deleted' : 'Template deleted';
+ const successToast = !presetManager.isAdvancedFormatting() ? t`Preset deleted` : t`Template deleted`;
toastr.success(successToast);
} else {
- const warningToast = !presetManager.isAdvancedFormatting() ? 'Preset was not deleted from server' : 'Template was not deleted from server';
+ const warningToast = !presetManager.isAdvancedFormatting() ? t`Preset was not deleted from server` : t`Template was not deleted from server`;
toastr.warning(warningToast);
}
@@ -862,7 +904,7 @@ export async function initPresetManager() {
const data = await presetManager.getDefaultPreset(name);
if (name == 'gui') {
- toastr.info('Cannot restore GUI preset');
+ toastr.info(t`Cannot restore GUI preset`);
return;
}
@@ -872,37 +914,37 @@ export async function initPresetManager() {
if (data.isDefault) {
if (Object.keys(data.preset).length === 0) {
- const errorToast = !presetManager.isAdvancedFormatting() ? 'Default preset cannot be restored' : 'Default template cannot be restored';
+ const errorToast = !presetManager.isAdvancedFormatting() ? t`Default preset cannot be restored` : t`Default template cannot be restored`;
toastr.error(errorToast);
return;
}
const confirmText = !presetManager.isAdvancedFormatting()
- ? 'Resetting a
default preset will restore the default settings.'
- : 'Resetting a
default template will restore the default settings.';
- const confirm = await Popup.show.confirm('Are you sure?', confirmText);
+ ? t`Resetting a
default preset will restore the default settings.`
+ : t`Resetting a
default template will restore the default settings.`;
+ const confirm = await Popup.show.confirm(t`Are you sure?`, confirmText);
if (!confirm) {
return;
}
- await presetManager.deleteCurrentPreset();
+ await presetManager.deletePreset();
await presetManager.savePreset(name, data.preset);
const option = presetManager.findPreset(name);
presetManager.selectPreset(option);
- const successToast = !presetManager.isAdvancedFormatting() ? 'Default preset restored' : 'Default template restored';
+ const successToast = !presetManager.isAdvancedFormatting() ? t`Default preset restored` : t`Default template restored`;
toastr.success(successToast);
} else {
const confirmText = !presetManager.isAdvancedFormatting()
- ? 'Resetting a
custom preset will restore to the last saved state.'
- : 'Resetting a
custom template will restore to the last saved state.';
- const confirm = await Popup.show.confirm('Are you sure?', confirmText);
+ ? t`Resetting a
custom preset will restore to the last saved state.`
+ : t`Resetting a
custom template will restore to the last saved state.`;
+ const confirm = await Popup.show.confirm(t`Are you sure?`, confirmText);
if (!confirm) {
return;
}
const option = presetManager.findPreset(name);
presetManager.selectPreset(option);
- const successToast = !presetManager.isAdvancedFormatting() ? 'Preset restored' : 'Template restored';
+ const successToast = !presetManager.isAdvancedFormatting() ? t`Preset restored` : t`Template restored`;
toastr.success(successToast);
}
});
diff --git a/public/scripts/templates/welcome.html b/public/scripts/templates/welcome.html
index 202609012..931875ce5 100644
--- a/public/scripts/templates/welcome.html
+++ b/public/scripts/templates/welcome.html
@@ -10,7 +10,7 @@
Click
and connect to an
@@ -21,7 +21,7 @@
Click
and pick a character.
@@ -33,7 +33,7 @@
Sample characters
- or
+ or