Merge branch 'staging' into cli-args-refactor
| @@ -1294,8 +1294,8 @@ | |||
| 1294 | <span data-i18n="TFS">TFS</span> | 1294 | <span data-i18n="TFS">TFS</span> |
| 1295 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail_Free_Sampling_desc" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution, by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative. The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div> | 1295 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail_Free_Sampling_desc" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution, by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative. The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div> |
| 1296 | </small> | 1296 | </small> |
| 1297 | <input class="neo-range-slider" type="range" id="tfs_textgenerationwebui" name="volume" min="0" max="1" step="0.01"> | 1297 | <input class="neo-range-slider" type="range" id="tfs_textgenerationwebui" name="volume" min="0" max="1" step="0.001"> |
| 1298 | <input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="tfs_textgenerationwebui" id="tfs_counter_textgenerationwebui"> | 1298 | <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="tfs_textgenerationwebui" id="tfs_counter_textgenerationwebui"> |
| 1299 | </div> | 1299 | </div> |
| 1300 | <div data-tg-type="ooba,mancer,aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | 1300 | <div data-tg-type="ooba,mancer,aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> |
| 1301 | <small> | 1301 | <small> |
| @@ -1477,8 +1477,8 @@ | |||
| 1477 | </div> | 1477 | </div> |
| 1478 | <div class="alignitemscenter flex-container marginBot5 flexFlowColumn flexGrow flexShrink gap0"> | 1478 | <div class="alignitemscenter flex-container marginBot5 flexFlowColumn flexGrow flexShrink gap0"> |
| 1479 | <small data-i18n="Exponent">Exponent</small> | 1479 | <small data-i18n="Exponent">Exponent</small> |
| 1480 | <input class="neo-range-slider" type="range" id="dynatemp_exponent_textgenerationwebui" name="volume" min="0.01" max="10" step="0.01" /> | 1480 | <input class="neo-range-slider" type="range" id="dynatemp_exponent_textgenerationwebui" name="volume" min="0.001" max="10" step="0.001" /> |
| 1481 | <input class="neo-range-input" type="number" min="0.01" max="10" step="0.01" data-for="dynatemp_exponent_textgenerationwebui" id="dynatemp_exponent_counter_textgenerationwebui"> | 1481 | <input class="neo-range-input" type="number" min="0.001" max="10" step="0.001" data-for="dynatemp_exponent_textgenerationwebui" id="dynatemp_exponent_counter_textgenerationwebui"> |
| 1482 | </div> | 1482 | </div> |
| 1483 | </div> | 1483 | </div> |
| 1484 | </div> | 1484 | </div> |
| @@ -606,7 +606,6 @@ export const printCharactersDebounced = debounce(() => { printCharacters(false); | |||
| 606 | export const system_message_types = { | 606 | export const system_message_types = { |
| 607 | HELP: 'help', | 607 | HELP: 'help', |
| 608 | WELCOME: 'welcome', | 608 | WELCOME: 'welcome', |
| 609 | GROUP: 'group', | ||
| 610 | EMPTY: 'empty', | 609 | EMPTY: 'empty', |
| 611 | GENERIC: 'generic', | 610 | GENERIC: 'generic', |
| 612 | NARRATOR: 'narrator', | 611 | NARRATOR: 'narrator', |
| @@ -699,14 +698,6 @@ async function getSystemMessages() { | |||
| 699 | uses_system_ui: true, | 698 | uses_system_ui: true, |
| 700 | mes: await renderTemplateAsync('welcome', { displayVersion }), | 699 | mes: await renderTemplateAsync('welcome', { displayVersion }), |
| 701 | }, | 700 | }, |
| 702 | group: { | ||
| 703 | name: systemUserName, | ||
| 704 | force_avatar: system_avatar, | ||
| 705 | is_user: false, | ||
| 706 | is_system: true, | ||
| 707 | is_group: true, | ||
| 708 | mes: 'Group chat created. Say \'Hi\' to lovely people!', | ||
| 709 | }, | ||
| 710 | empty: { | 701 | empty: { |
| 711 | name: systemUserName, | 702 | name: systemUserName, |
| 712 | force_avatar: system_avatar, | 703 | force_avatar: system_avatar, |
| @@ -318,16 +318,6 @@ export async function convertSoloToGroupChat() { | |||
| 318 | const groupChat = chat.slice(); | 318 | const groupChat = chat.slice(); |
| 319 | const genIdFirst = Date.now(); | 319 | const genIdFirst = Date.now(); |
| 320 | 320 | ||
| 321 | // Add something if the chat is empty | ||
| 322 | if (groupChat.length === 0) { | ||
| 323 | const newMessage = { | ||
| 324 | ...system_messages[system_message_types.GROUP], | ||
| 325 | send_date: getMessageTimeStamp(), | ||
| 326 | extra: { type: system_message_types.GROUP }, | ||
| 327 | }; | ||
| 328 | groupChat.push(newMessage); | ||
| 329 | } | ||
| 330 | |||
| 331 | for (let index = 0; index < groupChat.length; index++) { | 321 | for (let index = 0; index < groupChat.length; index++) { |
| 332 | const message = groupChat[index]; | 322 | const message = groupChat[index]; |
| 333 | 323 | ||
| @@ -7,7 +7,7 @@ import { renderTemplate, renderTemplateAsync } from './templates.js'; | |||
| 7 | import { delay, isSubsetOf, sanitizeSelector, setValueByPath } from './utils.js'; | 7 | import { delay, isSubsetOf, sanitizeSelector, setValueByPath } from './utils.js'; |
| 8 | import { getContext } from './st-context.js'; | 8 | import { getContext } from './st-context.js'; |
| 9 | import { isAdmin } from './user.js'; | 9 | import { isAdmin } from './user.js'; |
| 10 | import { t } from './i18n.js'; | 10 | import { addLocaleData, getCurrentLocale, t } from './i18n.js'; |
| 11 | import { debounce_timeout } from './constants.js'; | 11 | import { debounce_timeout } from './constants.js'; |
| 12 | import { accountStorage } from './util/AccountStorage.js'; | 12 | import { accountStorage } from './util/AccountStorage.js'; |
| 13 | 13 | ||
| @@ -384,7 +384,7 @@ async function activateExtensions() { | |||
| 384 | if (meetsModuleRequirements && !isDisabled) { | 384 | if (meetsModuleRequirements && !isDisabled) { |
| 385 | try { | 385 | try { |
| 386 | console.debug('Activating extension', name); | 386 | console.debug('Activating extension', name); |
| 387 | const promise = Promise.all([addExtensionScript(name, manifest), addExtensionStyle(name, manifest)]); | 387 | const promise = addExtensionLocale(name, manifest).finally(() => Promise.all([addExtensionScript(name, manifest), addExtensionStyle(name, manifest)])); |
| 388 | await promise | 388 | await promise |
| 389 | .then(() => activeExtensions.add(name)) | 389 | .then(() => activeExtensions.add(name)) |
| 390 | .catch(err => console.log('Could not activate extension', name, err)); | 390 | .catch(err => console.log('Could not activate extension', name, err)); |
| @@ -577,6 +577,42 @@ function addExtensionScript(name, manifest) { | |||
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | /** | 579 | /** |
| 580 | * Adds a localization data for an extension. | ||
| 581 | * @param {string} name Extension name | ||
| 582 | * @param {object} manifest Manifest object | ||
| 583 | */ | ||
| 584 | function addExtensionLocale(name, manifest) { | ||
| 585 | // No i18n data in the manifest | ||
| 586 | if (!manifest.i18n || typeof manifest.i18n !== 'object') { | ||
| 587 | return Promise.resolve(); | ||
| 588 | } | ||
| 589 | |||
| 590 | const currentLocale = getCurrentLocale(); | ||
| 591 | const localeFile = manifest.i18n[currentLocale]; | ||
| 592 | |||
| 593 | // Manifest doesn't provide a locale file for the current locale | ||
| 594 | if (!localeFile) { | ||
| 595 | return Promise.resolve(); | ||
| 596 | } | ||
| 597 | |||
| 598 | return fetch(`/scripts/extensions/${name}/${localeFile}`) | ||
| 599 | .then(async response => { | ||
| 600 | if (!response.ok) { | ||
| 601 | throw new Error(`HTTP ${response.status}: ${response.statusText}`); | ||
| 602 | } | ||
| 603 | |||
| 604 | const data = await response.json(); | ||
| 605 | |||
| 606 | if (data && typeof data === 'object') { | ||
| 607 | addLocaleData(currentLocale, data); | ||
| 608 | } | ||
| 609 | }) | ||
| 610 | .catch(err => { | ||
| 611 | console.log('Could not load extension locale data for ' + name, err); | ||
| 612 | }); | ||
| 613 | } | ||
| 614 | |||
| 615 | /** | ||
| 580 | * Generates HTML string for displaying an extension in the UI. | 616 | * Generates HTML string for displaying an extension in the UI. |
| 581 | * | 617 | * |
| 582 | * @param {string} name - The name of the extension. | 618 | * @param {string} name - The name of the extension. |
| @@ -228,9 +228,6 @@ export async function getGroupChat(groupId, reload = false) { | |||
| 228 | chat.splice(0, chat.length, ...data); | 228 | chat.splice(0, chat.length, ...data); |
| 229 | await printMessages(); | 229 | await printMessages(); |
| 230 | } else { | 230 | } else { |
| 231 | sendSystemMessage(system_message_types.GROUP, '', { isSmallSys: true }); | ||
| 232 | await eventSource.emit(event_types.MESSAGE_RECEIVED, (chat.length - 1)); | ||
| 233 | await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, (chat.length - 1)); | ||
| 234 | if (group && Array.isArray(group.members)) { | 231 | if (group && Array.isArray(group.members)) { |
| 235 | for (let member of group.members) { | 232 | for (let member of group.members) { |
| 236 | const character = characters.find(x => x.avatar === member || x.name === member); | 233 | const character = characters.find(x => x.avatar === member || x.name === member); |
| @@ -12,6 +12,30 @@ var localeData; | |||
| 12 | export const getCurrentLocale = () => localeFile; | 12 | export const getCurrentLocale = () => localeFile; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * Adds additional localization data to the current locale file. | ||
| 16 | * @param {string} localeId Locale ID (e.g. 'fr-fr' or 'zh-cn') | ||
| 17 | * @param {Record<string, string>} data Localization data to add | ||
| 18 | */ | ||
| 19 | export function addLocaleData(localeId, data) { | ||
| 20 | if (!localeData) { | ||
| 21 | console.warn('Localization data not loaded yet. Additional data will not be added.'); | ||
| 22 | return; | ||
| 23 | } | ||
| 24 | |||
| 25 | if (localeId !== localeFile) { | ||
| 26 | console.debug('Ignoring addLocaleData call for different locale', localeId); | ||
| 27 | return; | ||
| 28 | } | ||
| 29 | |||
| 30 | for (const [key, value] of Object.entries(data)) { | ||
| 31 | // Overrides for default locale data are not allowed | ||
| 32 | if (!Object.hasOwn(localeData, key)) { | ||
| 33 | localeData[key] = value; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | /** | ||
| 15 | * An observer that will check if any new i18n elements are added to the document | 39 | * An observer that will check if any new i18n elements are added to the document |
| 16 | * @type {MutationObserver} | 40 | * @type {MutationObserver} |
| 17 | */ | 41 | */ |
| @@ -644,7 +644,6 @@ async function CreateZenSliders(elmnt) { | |||
| 644 | } | 644 | } |
| 645 | if (sliderID == 'min_temp_textgenerationwebui' || | 645 | if (sliderID == 'min_temp_textgenerationwebui' || |
| 646 | sliderID == 'max_temp_textgenerationwebui' || | 646 | sliderID == 'max_temp_textgenerationwebui' || |
| 647 | sliderID == 'dynatemp_exponent_textgenerationwebui' || | ||
| 648 | sliderID == 'smoothing_curve_textgenerationwebui' || | 647 | sliderID == 'smoothing_curve_textgenerationwebui' || |
| 649 | sliderID == 'smoothing_factor_textgenerationwebui' || | 648 | sliderID == 'smoothing_factor_textgenerationwebui' || |
| 650 | sliderID == 'dry_multiplier_textgenerationwebui' || | 649 | sliderID == 'dry_multiplier_textgenerationwebui' || |
| @@ -54,7 +54,7 @@ import { | |||
| 54 | writeExtensionField, | 54 | writeExtensionField, |
| 55 | } from './extensions.js'; | 55 | } from './extensions.js'; |
| 56 | import { groups, openGroupChat, selected_group } from './group-chats.js'; | 56 | import { groups, openGroupChat, selected_group } from './group-chats.js'; |
| 57 | import { t, translate } from './i18n.js'; | 57 | import { addLocaleData, getCurrentLocale, t, translate } from './i18n.js'; |
| 58 | import { hideLoader, showLoader } from './loader.js'; | 58 | import { hideLoader, showLoader } from './loader.js'; |
| 59 | import { MacrosParser } from './macros.js'; | 59 | import { MacrosParser } from './macros.js'; |
| 60 | import { getChatCompletionModel, oai_settings } from './openai.js'; | 60 | import { getChatCompletionModel, oai_settings } from './openai.js'; |
| @@ -165,6 +165,8 @@ export function getContext() { | |||
| 165 | isMobile, | 165 | isMobile, |
| 166 | t, | 166 | t, |
| 167 | translate, | 167 | translate, |
| 168 | getCurrentLocale, | ||
| 169 | addLocaleData, | ||
| 168 | tags, | 170 | tags, |
| 169 | tagMap: tag_map, | 171 | tagMap: tag_map, |
| 170 | menuType: menu_type, | 172 | menuType: menu_type, |
| @@ -323,7 +323,7 @@ router.get('/discover', jsonParser, function (request, response) { | |||
| 323 | 323 | ||
| 324 | // Combine all extensions | 324 | // Combine all extensions |
| 325 | const allExtensions = [...builtInExtensions, ...userExtensions, ...globalExtensions]; | 325 | const allExtensions = [...builtInExtensions, ...userExtensions, ...globalExtensions]; |
| 326 | console.info('Extensions available for', request.user.profile.handle, allExtensions); | 326 | console.debug('Extensions available for', request.user.profile.handle, allExtensions); |
| 327 | 327 | ||
| 328 | return response.send(allExtensions); | 328 | return response.send(allExtensions); |
| 329 | }); | 329 | }); |