Merge branch 'staging' into whitelist-hosts

8fded7506938e28c3a850c3941f1abdaf4102ab2

Cohee <18619528+Cohee1207@users.noreply.github.com>

16 files changed, +131 -77Showing whitespace changes
public/index.html+7 -7
@@ -4153,7 +4153,7 @@
4153 </div>4153 </div>
4154 <div id="UI-language-block" class="flex-container alignItemsBaseline">4154 <div id="UI-language-block" class="flex-container alignItemsBaseline">
4155 <span data-i18n="UI Language">Language:</span>4155 <span data-i18n="UI Language">Language:</span>
4156 <select id="ui_language_select" class="flex1 margin0">4156 <select id="ui_language_select" class="flex1 margin0 text_pole">
4157 <option value="" data-i18n="Default">Default</option>4157 <option value="" data-i18n="Default">Default</option>
4158 <option value="en">English</option>4158 <option value="en">English</option>
4159 </select>4159 </select>
@@ -5388,17 +5388,17 @@
5388 </div>5388 </div>
5389 </div>5389 </div>
5390 <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1">5390 <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1">
5391 <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-left-long"></div>5391 <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-left-long"></div>
5392 <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-scroll" title="Set a group chat scenario" data-i18n="[title]Set a group chat scenario"></div>5392 <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-scroll" title="Set a group chat scenario" data-i18n="[title]Set a group chat scenario"></div>
5393 <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div>5393 <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div>
5394 <input id="rm_group_fav" type="hidden" />5394 <input id="rm_group_fav" type="hidden" />
5395 <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group.">5395 <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group.">
5396 <i id="group_media_allowed_icon" class="fa-solid fa-fw fa-link"></i>5396 <i id="group_media_allowed_icon" class="fa-solid fa-fw fa-link"></i>
5397 <i id="group_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i>5397 <i id="group_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i>
5398 </div>5398 </div>
5399 <div id="rm_group_submit" class="heightFitContent margin0 menu_button fa-solid fa-check" title="Create" data-i18n="[title]Create"></div>5399 <div id="rm_group_submit" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-check" title="Create" data-i18n="[title]Create"></div>
5400 <div id="rm_group_restore_avatar" class="heightFitContent margin0 menu_button fa-solid fa-images" title="Restore collage avatar" data-i18n="[title]Restore collage avatar"></div>5400 <div id="rm_group_restore_avatar" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-images" title="Restore collage avatar" data-i18n="[title]Restore collage avatar"></div>
5401 <div id="rm_group_delete" class="heightFitContent margin0 menu_button fa-solid fa-trash-can" title="Delete" data-i18n="[title]Delete"></div>5401 <div id="rm_group_delete" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-trash-can" title="Delete" data-i18n="[title]Delete"></div>
5402 <div class="flex1">5402 <div class="flex1">
5403 <label class="checkbox_label whitespacenowrap">5403 <label class="checkbox_label whitespacenowrap">
5404 <input id="rm_group_allow_self_responses" type="checkbox" />5404 <input id="rm_group_allow_self_responses" type="checkbox" />
public/script.js+42 -15
@@ -553,6 +553,10 @@ let generatedPromptCache = '';
553let generation_started = new Date();553let generation_started = new Date();
554/** @type {import('./scripts/char-data.js').v1CharData[]} */554/** @type {import('./scripts/char-data.js').v1CharData[]} */
555export let characters = [];555export let characters = [];
556/**
557 * Stringified index of a currently chosen entity in the characters array.
558 * @type {string|undefined} Yes, we hate it as much as you do.
559 */
556export let this_chid;560export let this_chid;
557let saveCharactersPage = 0;561let saveCharactersPage = 0;
558export const default_avatar = 'img/ai4.png';562export const default_avatar = 'img/ai4.png';
@@ -1378,7 +1382,7 @@ export async function selectCharacterById(id) {
1378 return;1382 return;
1379 }1383 }
13801384
1381 if (selected_group || this_chid !== id) {1385 if (selected_group || String(this_chid) !== String(id)) {
1382 //if clicked on a different character from what was currently selected1386 //if clicked on a different character from what was currently selected
1383 if (!is_send_press) {1387 if (!is_send_press) {
1384 await clearChat();1388 await clearChat();
@@ -1386,7 +1390,7 @@ export async function selectCharacterById(id) {
1386 resetSelectedGroup();1390 resetSelectedGroup();
1387 this_edit_mes_id = undefined;1391 this_edit_mes_id = undefined;
1388 selected_button = 'character_edit';1392 selected_button = 'character_edit';
1389 this_chid = id;1393 setCharacterId(id);
1390 chat.length = 0;1394 chat.length = 0;
1391 chat_metadata = {};1395 chat_metadata = {};
1392 await getChat();1396 await getChat();
@@ -5309,7 +5313,7 @@ function addChatsSeparator(mesSendString) {
5309}5313}
53105314
5311async function duplicateCharacter() {5315async function duplicateCharacter() {
5312 if (!this_chid) {5316 if (this_chid === undefined || !characters[this_chid]) {
5313 toastr.warning(t`You must first select a character to duplicate!`);5317 toastr.warning(t`You must first select a character to duplicate!`);
5314 return '';5318 return '';
5315 }5319 }
@@ -6210,7 +6214,7 @@ export function resetChatState() {
6210 // replaces deleted charcter name with system user since it will be displayed next.6214 // replaces deleted charcter name with system user since it will be displayed next.
6211 name2 = (this_chid === undefined && neutralCharacterName) ? neutralCharacterName : systemUserName;6215 name2 = (this_chid === undefined && neutralCharacterName) ? neutralCharacterName : systemUserName;
6212 //unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays)6216 //unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays)
6213 this_chid = undefined;6217 setCharacterId(undefined);
6214 // sets up system user to tell user about having deleted a character6218 // sets up system user to tell user about having deleted a character
6215 chat.splice(0, chat.length, ...SAFETY_CHAT);6219 chat.splice(0, chat.length, ...SAFETY_CHAT);
6216 // resets chat metadata6220 // resets chat metadata
@@ -6233,8 +6237,29 @@ export function setExternalAbortController(controller) {
6233 abortController = controller;6237 abortController = controller;
6234}6238}
62356239
6240/**
6241 * Sets a character array index.
6242 * @param {number|string|undefined} value
6243 */
6236export function setCharacterId(value) {6244export function setCharacterId(value) {
6237 this_chid = value;6245 switch (typeof value) {
6246 case 'bigint':
6247 case 'number':
6248 this_chid = String(value);
6249 break;
6250 case 'string':
6251 this_chid = !isNaN(parseInt(value)) ? value : undefined;
6252 break;
6253 case 'object':
6254 this_chid = characters.indexOf(value) !== -1 ? String(characters.indexOf(value)) : undefined;
6255 break;
6256 case 'undefined':
6257 this_chid = undefined;
6258 break;
6259 default:
6260 console.error('Invalid character ID type:', value);
6261 break;
6262 }
6238}6263}
62396264
6240export function setCharacterName(value) {6265export function setCharacterName(value) {
@@ -6350,13 +6375,13 @@ export async function renameCharacter(name = null, { silent = false, renameChats
63506375
6351 if (newChId !== -1) {6376 if (newChId !== -1) {
6352 // Select the character after the renaming6377 // Select the character after the renaming
6353 this_chid = -1;6378 setCharacterId(undefined);
6354 await selectCharacterById(newChId);6379 await selectCharacterById(newChId);
63556380
6356 // Async delay to update UI6381 // Async delay to update UI
6357 await delay(1);6382 await delay(1);
63586383
6359 if (this_chid === -1) {6384 if (this_chid === undefined) {
6360 throw new Error('New character not selected');6385 throw new Error('New character not selected');
6361 }6386 }
63626387
@@ -7658,7 +7683,7 @@ export function select_rm_info(type, charId, previousCharId = null) {
7658 if (previousCharId) {7683 if (previousCharId) {
7659 const newId = characters.findIndex((x) => x.avatar == previousCharId);7684 const newId = characters.findIndex((x) => x.avatar == previousCharId);
7660 if (newId >= 0) {7685 if (newId >= 0) {
7661 this_chid = newId;7686 setCharacterId(newId);
7662 }7687 }
7663 }7688 }
7664}7689}
@@ -7678,6 +7703,7 @@ export function select_selected_character(chid) {
7678 $('#create_button').attr('value', 'Save'); // what is the use case for this?7703 $('#create_button').attr('value', 'Save'); // what is the use case for this?
7679 $('#dupe_button').show();7704 $('#dupe_button').show();
7680 $('#create_button_label').css('display', 'none');7705 $('#create_button_label').css('display', 'none');
7706 $('#char_connections_button').show();
76817707
7682 // Hide the chat scenario button if we're peeking the group member defs7708 // Hide the chat scenario button if we're peeking the group member defs
7683 $('#set_chat_scenario').toggle(!selected_group);7709 $('#set_chat_scenario').toggle(!selected_group);
@@ -7762,6 +7788,7 @@ function select_rm_create() {
7762 $('#create_button_label').css('display', '');7788 $('#create_button_label').css('display', '');
7763 $('#create_button').attr('value', 'Create');7789 $('#create_button').attr('value', 'Create');
7764 $('#dupe_button').hide();7790 $('#dupe_button').hide();
7791 $('#char_connections_button').hide();
77657792
7766 //create text poles7793 //create text poles
7767 $('#rm_button_back').css('display', '');7794 $('#rm_button_back').css('display', '');
@@ -7791,8 +7818,8 @@ function select_rm_create() {
7791 $('#renameCharButton').css('display', 'none');7818 $('#renameCharButton').css('display', 'none');
7792 $('#name_div').removeClass('displayNone');7819 $('#name_div').removeClass('displayNone');
7793 $('#name_div').addClass('displayBlock');7820 $('#name_div').addClass('displayBlock');
7794 $('.open_alternate_greetings').data('chid', undefined);7821 $('.open_alternate_greetings').data('chid', -1);
7795 $('#set_character_world').data('chid', undefined);7822 $('#set_character_world').data('chid', -1);
7796 setWorldInfoButtonClass(undefined, !!create_save.world);7823 setWorldInfoButtonClass(undefined, !!create_save.world);
7797 updateFavButtonState(false);7824 updateFavButtonState(false);
7798 checkEmbeddedWorld();7825 checkEmbeddedWorld();
@@ -7883,7 +7910,7 @@ function updateFavButtonState(state) {
7883}7910}
78847911
7885export async function setScenarioOverride() {7912export async function setScenarioOverride() {
7886 if (!selected_group && !this_chid) {7913 if (!selected_group && (this_chid === undefined || !characters[this_chid])) {
7887 console.warn('setScenarioOverride() -- no selected group or character');7914 console.warn('setScenarioOverride() -- no selected group or character');
7888 return;7915 return;
7889 }7916 }
@@ -8248,7 +8275,7 @@ function updateAlternateGreetingsHintVisibility(root) {
8248function openCharacterWorldPopup() {8275function openCharacterWorldPopup() {
8249 const chid = $('#set_character_world').data('chid');8276 const chid = $('#set_character_world').data('chid');
82508277
8251 if (menu_type != 'create' && chid == undefined) {8278 if (menu_type != 'create' && chid === undefined) {
8252 toastr.error('Does not have an Id for this character in world select menu.');8279 toastr.error('Does not have an Id for this character in world select menu.');
8253 return;8280 return;
8254 }8281 }
@@ -8380,7 +8407,7 @@ function openAlternateGreetings() {
8380 return;8407 return;
8381 } else {8408 } else {
8382 // If the character does not have alternate greetings, create an empty array8409 // If the character does not have alternate greetings, create an empty array
8383 if (chid && Array.isArray(characters[chid].data.alternate_greetings) == false) {8410 if (characters[chid] && !Array.isArray(characters[chid].data.alternate_greetings)) {
8384 characters[chid].data.alternate_greetings = [];8411 characters[chid].data.alternate_greetings = [];
8385 }8412 }
8386 }8413 }
@@ -8567,7 +8594,7 @@ async function createOrEditCharacter(e) {
85678594
8568 formData.delete('alternate_greetings');8595 formData.delete('alternate_greetings');
8569 const chid = $('.open_alternate_greetings').data('chid');8596 const chid = $('.open_alternate_greetings').data('chid');
8570 if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) {8597 if (characters[chid] && Array.isArray(characters[chid]?.data?.alternate_greetings)) {
8571 for (const value of characters[chid].data.alternate_greetings) {8598 for (const value of characters[chid].data.alternate_greetings) {
8572 formData.append('alternate_greetings', value);8599 formData.append('alternate_greetings', value);
8573 }8600 }
@@ -10283,7 +10310,7 @@ jQuery(async function () {
10283 $('#form_create').submit(createOrEditCharacter);10310 $('#form_create').submit(createOrEditCharacter);
1028410311
10285 $('#delete_button').on('click', async function () {10312 $('#delete_button').on('click', async function () {
10286 if (!this_chid) {10313 if (this_chid === undefined || !characters[this_chid]) {
10287 toastr.warning('No character selected.');10314 toastr.warning('No character selected.');
10288 return;10315 return;
10289 }10316 }
public/scripts/BulkEditOverlay.js+2 -2
@@ -395,7 +395,7 @@ class BulkEditOverlay {
395395
396 /**396 /**
397 * @typedef {object} LastSelected - An object noting the last selected character and its state.397 * @typedef {object} LastSelected - An object noting the last selected character and its state.
398 * @property {string} [characterId] - The character id of the last selected character.398 * @property {number} [characterId] - The character id of the last selected character.
399 * @property {boolean} [select] - The selected state of the last selected character. <c>true</c> if it was selected, <c>false</c> if it was deselected.399 * @property {boolean} [select] - The selected state of the last selected character. <c>true</c> if it was selected, <c>false</c> if it was deselected.
400 */400 */
401401
@@ -675,7 +675,7 @@ class BulkEditOverlay {
675 const characterId = Number(currentCharacter.getAttribute('data-chid'));675 const characterId = Number(currentCharacter.getAttribute('data-chid'));
676 const select = !this.selectedCharacters.includes(characterId);676 const select = !this.selectedCharacters.includes(characterId);
677677
678 if (this.lastSelected.characterId && this.lastSelected.select !== undefined) {678 if (this.lastSelected.characterId >= 0 && this.lastSelected.select !== undefined) {
679 // Only if select state and the last select state match we execute the range select679 // Only if select state and the last select state match we execute the range select
680 if (select === this.lastSelected.select) {680 if (select === this.lastSelected.select) {
681 this.toggleCharactersInRange(currentCharacter, select);681 this.toggleCharactersInRange(currentCharacter, select);
public/scripts/authors-note.js+9 -9
@@ -299,7 +299,7 @@ function loadSettings() {
299 $('#extension_floating_role').val(chat_metadata[metadata_keys.role]);299 $('#extension_floating_role').val(chat_metadata[metadata_keys.role]);
300 $(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);300 $(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
301301
302 if (extension_settings.note.chara && getContext().characterId) {302 if (extension_settings.note.chara && getContext().characterId !== undefined) {
303 const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());303 const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
304304
305 $('#extension_floating_chara').val(charaNote ? charaNote.prompt : '');305 $('#extension_floating_chara').val(charaNote ? charaNote.prompt : '');
@@ -389,7 +389,11 @@ export function setFloatingPrompt() {
389}389}
390390
391function onANMenuItemClick() {391function onANMenuItemClick() {
392 if (selected_group || this_chid) {392 if (!selected_group && this_chid === undefined) {
393 toastr.warning(t`Select a character before trying to use Author's Note`, '', { timeOut: 2000 });
394 return;
395 }
396
393 //show AN if it's hidden397 //show AN if it's hidden
394 if ($('#floatingPrompt').css('display') !== 'flex') {398 if ($('#floatingPrompt').css('display') !== 'flex') {
395 $('#floatingPrompt').addClass('resizing');399 $('#floatingPrompt').addClass('resizing');
@@ -416,22 +420,18 @@ function onANMenuItemClick() {
416 $('#floatingPrompt').transition({420 $('#floatingPrompt').transition({
417 opacity: 0.0,421 opacity: 0.0,
418 duration: animation_duration,422 duration: animation_duration,
419 },423 }, async function () {
420 async function () {
421 await delay(50);424 await delay(50);
422 $('#floatingPrompt').removeClass('resizing');425 $('#floatingPrompt').removeClass('resizing');
423 });426 });
424 setTimeout(function () {427 setTimeout(function () {
425 $('#floatingPrompt').hide();428 $('#floatingPrompt').hide();
426 }, animation_duration);429 }, animation_duration);
427
428 }430 }
431
429 //duplicate options menu close handler from script.js432 //duplicate options menu close handler from script.js
430 //because this listener takes priority433 //because this listener takes priority
431 $('#options').stop().fadeOut(animation_duration);434 $('#options').stop().fadeOut(animation_duration);
432 } else {
433 toastr.warning(t`Select a character before trying to use Author's Note`, '', { timeOut: 2000 });
434 }
435}435}
436436
437async function onChatChanged() {437async function onChatChanged() {
@@ -446,7 +446,7 @@ async function onChatChanged() {
446 $('#extension_floating_prompt_token_counter').text(tokenCounter1);446 $('#extension_floating_prompt_token_counter').text(tokenCounter1);
447447
448 let tokenCounter2;448 let tokenCounter2;
449 if (extension_settings.note.chara && context.characterId) {449 if (extension_settings.note.chara && context.characterId !== undefined) {
450 const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());450 const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
451451
452 if (charaNote) {452 if (charaNote) {
public/scripts/cfg-scale.js+7 -8
@@ -69,8 +69,7 @@ function setCharCfg(tempValue, setting) {
69 if (!existingCharaCfg.useChara &&69 if (!existingCharaCfg.useChara &&
70 (tempAssign.guidance_scale ?? 1.00) === 1.00 &&70 (tempAssign.guidance_scale ?? 1.00) === 1.00 &&
71 (tempAssign.negative_prompt?.length ?? 0) === 0 &&71 (tempAssign.negative_prompt?.length ?? 0) === 0 &&
72 (tempAssign.positive_prompt?.length ?? 0) === 0)72 (tempAssign.positive_prompt?.length ?? 0) === 0) {
73 {
74 extension_settings.cfg.chara.splice(existingCharaCfgIndex, 1);73 extension_settings.cfg.chara.splice(existingCharaCfgIndex, 1);
75 }74 }
76 } else if (avatarName && tempValue.length > 0) {75 } else if (avatarName && tempValue.length > 0) {
@@ -113,7 +112,11 @@ function setChatCfg(tempValue, setting) {
113112
114// TODO: Only change CFG when character is selected113// TODO: Only change CFG when character is selected
115function onCfgMenuItemClick() {114function onCfgMenuItemClick() {
116 if (selected_group || this_chid) {115 if (!selected_group && this_chid === undefined) {
116 toastr.warning('Select a character before trying to configure CFG', '', { timeOut: 2000 });
117 return;
118 }
119
117 //show CFG config if it's hidden120 //show CFG config if it's hidden
118 if ($('#cfgConfig').css('display') !== 'flex') {121 if ($('#cfgConfig').css('display') !== 'flex') {
119 $('#cfgConfig').addClass('resizing');122 $('#cfgConfig').addClass('resizing');
@@ -140,8 +143,7 @@ function onCfgMenuItemClick() {
140 $('#cfgConfig').transition({143 $('#cfgConfig').transition({
141 opacity: 0.0,144 opacity: 0.0,
142 duration: animation_duration,145 duration: animation_duration,
143 },146 }, async function () {
144 async function () {
145 await delay(50);147 await delay(50);
146 $('#cfgConfig').removeClass('resizing');148 $('#cfgConfig').removeClass('resizing');
147 });149 });
@@ -153,9 +155,6 @@ function onCfgMenuItemClick() {
153 //duplicate options menu close handler from script.js155 //duplicate options menu close handler from script.js
154 //because this listener takes priority156 //because this listener takes priority
155 $('#options').stop().fadeOut(animation_duration);157 $('#options').stop().fadeOut(animation_duration);
156 } else {
157 toastr.warning('Select a character before trying to configure CFG', '', { timeOut: 2000 });
158 }
159}158}
160159
161async function onChatChanged() {160async function onChatChanged() {
public/scripts/extensions/expressions/index.js+1 -1
@@ -624,7 +624,7 @@ function getFolderNameByMessage(message) {
624 if (context.groupId) {624 if (context.groupId) {
625 avatarPath = message.original_avatar || context.characters.find(x => message.force_avatar && message.force_avatar.includes(encodeURIComponent(x.avatar)))?.avatar;625 avatarPath = message.original_avatar || context.characters.find(x => message.force_avatar && message.force_avatar.includes(encodeURIComponent(x.avatar)))?.avatar;
626 }626 }
627 else if (context.characterId) {627 else if (context.characterId !== undefined) {
628 avatarPath = getCharaFilename();628 avatarPath = getCharaFilename();
629 }629 }
630630
public/scripts/extensions/gallery/index.js+4 -4
@@ -169,9 +169,9 @@ async function showCharGallery() {
169169
170 try {170 try {
171 let url = selected_group || this_chid;171 let url = selected_group || this_chid;
172 if (!selected_group && this_chid) {172 if (!selected_group && this_chid !== undefined) {
173 const char = characters[this_chid];173 const char = characters[this_chid];
174 url = char.avatar.replace('.png', '');174 url = char.name;
175 }175 }
176176
177 const items = await getGalleryItems(url);177 const items = await getGalleryItems(url);
@@ -455,9 +455,9 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
455async function listGalleryCommand(args) {455async function listGalleryCommand(args) {
456 try {456 try {
457 let url = args.char ?? (args.group ? groups.find(it => it.name == args.group)?.id : null) ?? (selected_group || this_chid);457 let url = args.char ?? (args.group ? groups.find(it => it.name == args.group)?.id : null) ?? (selected_group || this_chid);
458 if (!args.char && !args.group && !selected_group && this_chid) {458 if (!args.char && !args.group && !selected_group && this_chid !== undefined) {
459 const char = characters[this_chid];459 const char = characters[this_chid];
460 url = char.avatar.replace('.png', '');460 url = char.name;
461 }461 }
462462
463 const items = await getGalleryItems(url);463 const items = await getGalleryItems(url);
public/scripts/extensions/memory/index.js+20 -18
@@ -378,6 +378,23 @@ function getIndexOfLatestChatSummary(chat) {
378 return -1;378 return -1;
379}379}
380380
381/**
382 * Check if something is changed during the summarization process.
383 * @param {{ groupId: any; chatId: any; characterId: any; }} context
384 * @returns {boolean} True if the context has changed and the summary should be discarded
385 */
386function isContextChanged(context) {
387 const newContext = getContext();
388 if (newContext.groupId !== context.groupId
389 || newContext.chatId !== context.chatId
390 || (!newContext.groupId && (newContext.characterId !== context.characterId))) {
391 console.log('Context changed, summary discarded');
392 return true;
393 }
394
395 return false;
396}
397
381function onChatChanged() {398function onChatChanged() {
382 const context = getContext();399 const context = getContext();
383 const latestMemory = getLatestMemoryFromChat(context.chat);400 const latestMemory = getLatestMemoryFromChat(context.chat);
@@ -626,7 +643,6 @@ async function summarizeChatWebLLM(context, force) {
626 try {643 try {
627 inApiCall = true;644 inApiCall = true;
628 const summary = await generateWebLlmChatPrompt(messages, params);645 const summary = await generateWebLlmChatPrompt(messages, params);
629 const newContext = getContext();
630646
631 if (!summary) {647 if (!summary) {
632 console.warn('Empty summary received');648 console.warn('Empty summary received');
@@ -634,10 +650,7 @@ async function summarizeChatWebLLM(context, force) {
634 }650 }
635651
636 // something changed during summarization request652 // something changed during summarization request
637 if (newContext.groupId !== context.groupId ||653 if (isContextChanged(context)) {
638 newContext.chatId !== context.chatId ||
639 (!newContext.groupId && (newContext.characterId !== context.characterId))) {
640 console.log('Context changed, summary discarded');
641 return;654 return;
642 }655 }
643656
@@ -701,13 +714,7 @@ async function summarizeChatMain(context, force, skipWIAN) {
701 return;714 return;
702 }715 }
703716
704 const newContext = getContext();717 if (isContextChanged(context)) {
705
706 // something changed during summarization request
707 if (newContext.groupId !== context.groupId
708 || newContext.chatId !== context.chatId
709 || (!newContext.groupId && (newContext.characterId !== context.characterId))) {
710 console.log('Context changed, summary discarded');
711 return;718 return;
712 }719 }
713720
@@ -833,18 +840,13 @@ async function summarizeChatExtras(context) {
833 try {840 try {
834 inApiCall = true;841 inApiCall = true;
835 const summary = await callExtrasSummarizeAPI(resultingString);842 const summary = await callExtrasSummarizeAPI(resultingString);
836 const newContext = getContext();
837843
838 if (!summary) {844 if (!summary) {
839 console.warn('Empty summary received');845 console.warn('Empty summary received');
840 return;846 return;
841 }847 }
842848
843 // something changed during summarization request849 if (isContextChanged(context)) {
844 if (newContext.groupId !== context.groupId
845 || newContext.chatId !== context.chatId
846 || (!newContext.groupId && (newContext.characterId !== context.characterId))) {
847 console.log('Context changed, summary discarded');
848 return;850 return;
849 }851 }
850852
public/scripts/extensions/stable-diffusion/index.js+2 -2
@@ -783,7 +783,7 @@ async function onCharacterNegativePromptInput() {
783}783}
784784
785function getCharacterPrefix() {785function getCharacterPrefix() {
786 if (!this_chid || selected_group) {786 if (this_chid === undefined || selected_group) {
787 return '';787 return '';
788 }788 }
789789
@@ -797,7 +797,7 @@ function getCharacterPrefix() {
797}797}
798798
799function getCharacterNegativePrefix() {799function getCharacterNegativePrefix() {
800 if (!this_chid || selected_group) {800 if (this_chid === undefined || selected_group) {
801 return '';801 return '';
802 }802 }
803803
public/scripts/extensions/tts/system.js+2 -0
@@ -51,6 +51,8 @@ var speechUtteranceChunker = function (utt, settings, callback) {
51 }51 }
52 newUtt.lang = utt.lang;52 newUtt.lang = utt.lang;
53 newUtt.voice = utt.voice;53 newUtt.voice = utt.voice;
54 newUtt.rate = utt.rate;
55 newUtt.pitch = utt.pitch;
54 newUtt.addEventListener('end', function () {56 newUtt.addEventListener('end', function () {
55 if (speechUtteranceChunker.cancel) {57 if (speechUtteranceChunker.cancel) {
56 speechUtteranceChunker.cancel = false;58 speechUtteranceChunker.cancel = false;
public/scripts/horde.js+2 -0
@@ -406,6 +406,8 @@ jQuery(function () {
406 } else {406 } else {
407 $('#adjustedHordeParams').text('Context: --, Response: --');407 $('#adjustedHordeParams').text('Context: --, Response: --');
408 }408 }
409
410 saveSettingsDebounced();
409 });411 });
410412
411 $('#horde_auto_adjust_response_length').on('input', function () {413 $('#horde_auto_adjust_response_length').on('input', function () {
public/scripts/i18n.js+6 -2
@@ -132,10 +132,14 @@ async function getLocaleData(language) {
132 return data;132 return data;
133}133}
134134
135/**
136 * Gets a language object for the given language code.
137 * @param {string} language Language code
138 */
135function findLang(language) {139function findLang(language) {
136 var supportedLang = langs.find(x => x.lang === language);140 const supportedLang = langs.find(x => x.lang === language);
137141
138 if (!supportedLang) {142 if (!supportedLang && language !== 'en') {
139 console.warn(`Unsupported language: ${language}`);143 console.warn(`Unsupported language: ${language}`);
140 }144 }
141 return supportedLang;145 return supportedLang;
public/scripts/logprobs.js+5 -1
@@ -496,9 +496,13 @@ function getMessageHash(message) {
496/**496/**
497 * getActiveMessageLogprobData returns the logprobs data for the active chat497 * getActiveMessageLogprobData returns the logprobs data for the active chat
498 * message.498 * message.
499 * @returns {MessageLogprobData || null}499 * @returns {MessageLogprobData|null}
500 */500 */
501function getActiveMessageLogprobData() {501function getActiveMessageLogprobData() {
502 if (chat.length === 0) {
503 return null;
504 }
505
502 const hash = getMessageHash(chat[chat.length - 1]);506 const hash = getMessageHash(chat[chat.length - 1]);
503 return state.messageLogprobs.get(hash) || null;507 return state.messageLogprobs.get(hash) || null;
504}508}
public/scripts/st-context.js+4 -0
@@ -45,6 +45,8 @@ import {
45 this_chid,45 this_chid,
46 updateChatMetadata,46 updateChatMetadata,
47 updateMessageBlock,47 updateMessageBlock,
48 printMessages,
49 clearChat,
48} from '../script.js';50} from '../script.js';
49import {51import {
50 extension_settings,52 extension_settings,
@@ -203,6 +205,8 @@ export function getContext() {
203 extractMessageFromData,205 extractMessageFromData,
204 getPresetManager,206 getPresetManager,
205 getChatCompletionModel,207 getChatCompletionModel,
208 printMessages,
209 clearChat,
206 };210 };
207}211}
208212
public/scripts/tags.js+1 -1
@@ -410,7 +410,7 @@ function getInlineListSelector() {
410 return `.group_select[grid="${selected_group}"] .tags`;410 return `.group_select[grid="${selected_group}"] .tags`;
411 }411 }
412412
413 if (this_chid && menu_type === 'character_edit') {413 if (this_chid !== undefined && menu_type === 'character_edit') {
414 return `.character_select[chid="${this_chid}"] .tags`;414 return `.character_select[chid="${this_chid}"] .tags`;
415 }415 }
416416
public/scripts/world-info.js+17 -7
@@ -4732,7 +4732,7 @@ export function setWorldInfoButtonClass(chid, forceValue = undefined) {
4732 return;4732 return;
4733 }4733 }
47344734
4735 if (!chid) {4735 if (chid === undefined) {
4736 return;4736 return;
4737 }4737 }
47384738
@@ -4749,7 +4749,7 @@ export function checkEmbeddedWorld(chid) {
4749 }4749 }
47504750
4751 if (characters[chid]?.data?.character_book) {4751 if (characters[chid]?.data?.character_book) {
4752 $('#import_character_info').data('data-chid', chid).show();4752 $('#import_character_info').data('chid', chid).show();
47534753
4754 // Only show the alert once per character4754 // Only show the alert once per character
4755 const checkKey = `AlertWI_${characters[chid].avatar}`;4755 const checkKey = `AlertWI_${characters[chid].avatar}`;
@@ -4783,9 +4783,15 @@ export function checkEmbeddedWorld(chid) {
4783}4783}
47844784
4785export async function importEmbeddedWorldInfo(skipPopup = false) {4785export async function importEmbeddedWorldInfo(skipPopup = false) {
4786 const chid = $('#import_character_info').data('data-chid');4786 const chid = $('#import_character_info').data('chid');
47874787
4788 if (chid === undefined) {4788 if (chid === undefined || chid === -1) {
4789 return;
4790 }
4791
4792 const hasEmbed = checkEmbeddedWorld(chid);
4793
4794 if (!hasEmbed) {
4789 return;4795 return;
4790 }4796 }
47914797
@@ -5167,9 +5173,14 @@ jQuery(() => {
5167 });5173 });
51685174
5169 $('#world_button').on('click', async function (event) {5175 $('#world_button').on('click', async function (event) {
5176 const openSetWorldMenu = () => $('#char-management-dropdown').val($('#set_character_world').val()).trigger('change');
5170 const chid = $('#set_character_world').data('chid');5177 const chid = $('#set_character_world').data('chid');
51715178
5172 if (chid) {5179 if (chid === -1) {
5180 openSetWorldMenu();
5181 return;
5182 }
5183
5173 const worldName = characters[chid]?.data?.extensions?.world;5184 const worldName = characters[chid]?.data?.extensions?.world;
5174 const hasEmbed = checkEmbeddedWorld(chid);5185 const hasEmbed = checkEmbeddedWorld(chid);
5175 if (worldName && world_names.includes(worldName) && !event.shiftKey) {5186 if (worldName && world_names.includes(worldName) && !event.shiftKey) {
@@ -5179,8 +5190,7 @@ jQuery(() => {
5179 saveCharacterDebounced();5190 saveCharacterDebounced();
5180 }5191 }
5181 else {5192 else {
5182 $('#char-management-dropdown').val($('#set_character_world').val()).trigger('change');5193 openSetWorldMenu();
5183 }
5184 }5194 }
5185 });5195 });
51865196