Merge branch 'staging' into whitelist-hosts

8fded7506938e28c3a850c3941f1abdaf4102ab2

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

16 files changed, +221 -167Ignore whitespace
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+41 -41
@@ -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,49 +389,49 @@ export function setFloatingPrompt() {
389}389}
390390
391function onANMenuItemClick() {391function onANMenuItemClick() {
392 if (selected_group || this_chid) {392 if (!selected_group && this_chid === undefined) {
393 //show AN if it's hidden393 toastr.warning(t`Select a character before trying to use Author's Note`, '', { timeOut: 2000 });
394 if ($('#floatingPrompt').css('display') !== 'flex') {394 return;
395 $('#floatingPrompt').addClass('resizing');395 }
396 $('#floatingPrompt').css('display', 'flex');396
397 $('#floatingPrompt').css('opacity', 0.0);397 //show AN if it's hidden
398 $('#floatingPrompt').transition({398 if ($('#floatingPrompt').css('display') !== 'flex') {
399 opacity: 1.0,399 $('#floatingPrompt').addClass('resizing');
400 duration: animation_duration,400 $('#floatingPrompt').css('display', 'flex');
401 }, async function () {401 $('#floatingPrompt').css('opacity', 0.0);
402 await delay(50);402 $('#floatingPrompt').transition({
403 $('#floatingPrompt').removeClass('resizing');403 opacity: 1.0,
404 });404 duration: animation_duration,
405405 }, async function () {
406 //auto-open the main AN inline drawer406 await delay(50);
407 if ($('#ANBlockToggle')407 $('#floatingPrompt').removeClass('resizing');
408 .siblings('.inline-drawer-content')408 });
409 .css('display') !== 'block') {
410 $('#floatingPrompt').addClass('resizing');
411 $('#ANBlockToggle').click();
412 }
413 } else {
414 //hide AN if it's already displayed
415 $('#floatingPrompt').addClass('resizing');
416 $('#floatingPrompt').transition({
417 opacity: 0.0,
418 duration: animation_duration,
419 },
420 async function () {
421 await delay(50);
422 $('#floatingPrompt').removeClass('resizing');
423 });
424 setTimeout(function () {
425 $('#floatingPrompt').hide();
426 }, animation_duration);
427409
410 //auto-open the main AN inline drawer
411 if ($('#ANBlockToggle')
412 .siblings('.inline-drawer-content')
413 .css('display') !== 'block') {
414 $('#floatingPrompt').addClass('resizing');
415 $('#ANBlockToggle').click();
428 }416 }
429 //duplicate options menu close handler from script.js
430 //because this listener takes priority
431 $('#options').stop().fadeOut(animation_duration);
432 } else {417 } else {
433 toastr.warning(t`Select a character before trying to use Author's Note`, '', { timeOut: 2000 });418 //hide AN if it's already displayed
419 $('#floatingPrompt').addClass('resizing');
420 $('#floatingPrompt').transition({
421 opacity: 0.0,
422 duration: animation_duration,
423 }, async function () {
424 await delay(50);
425 $('#floatingPrompt').removeClass('resizing');
426 });
427 setTimeout(function () {
428 $('#floatingPrompt').hide();
429 }, animation_duration);
434 }430 }
431
432 //duplicate options menu close handler from script.js
433 //because this listener takes priority
434 $('#options').stop().fadeOut(animation_duration);
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+56 -57
@@ -40,7 +40,7 @@ function setCharCfg(tempValue, setting) {
40 name: avatarName,40 name: avatarName,
41 };41 };
4242
43 switch(setting) {43 switch (setting) {
44 case settingType.guidance_scale:44 case settingType.guidance_scale:
45 tempCharaCfg['guidance_scale'] = Number(tempValue);45 tempCharaCfg['guidance_scale'] = Number(tempValue);
46 break;46 break;
@@ -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) {
@@ -92,7 +91,7 @@ function setCharCfg(tempValue, setting) {
92}91}
9392
94function setChatCfg(tempValue, setting) {93function setChatCfg(tempValue, setting) {
95 switch(setting) {94 switch (setting) {
96 case settingType.guidance_scale:95 case settingType.guidance_scale:
97 chat_metadata[metadataKeys.guidance_scale] = tempValue;96 chat_metadata[metadataKeys.guidance_scale] = tempValue;
98 break;97 break;
@@ -113,49 +112,49 @@ 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) {
117 //show CFG config if it's hidden116 toastr.warning('Select a character before trying to configure CFG', '', { timeOut: 2000 });
118 if ($('#cfgConfig').css('display') !== 'flex') {117 return;
119 $('#cfgConfig').addClass('resizing');118 }
120 $('#cfgConfig').css('display', 'flex');119
121 $('#cfgConfig').css('opacity', 0.0);120 //show CFG config if it's hidden
122 $('#cfgConfig').transition({121 if ($('#cfgConfig').css('display') !== 'flex') {
123 opacity: 1.0,122 $('#cfgConfig').addClass('resizing');
124 duration: animation_duration,123 $('#cfgConfig').css('display', 'flex');
125 }, async function () {124 $('#cfgConfig').css('opacity', 0.0);
126 await delay(50);125 $('#cfgConfig').transition({
127 $('#cfgConfig').removeClass('resizing');126 opacity: 1.0,
128 });127 duration: animation_duration,
129128 }, async function () {
130 //auto-open the main AN inline drawer129 await delay(50);
131 if ($('#CFGBlockToggle')130 $('#cfgConfig').removeClass('resizing');
132 .siblings('.inline-drawer-content')131 });
133 .css('display') !== 'block') {
134 $('#floatingPrompt').addClass('resizing');
135 $('#CFGBlockToggle').click();
136 }
137 } else {
138 //hide AN if it's already displayed
139 $('#cfgConfig').addClass('resizing');
140 $('#cfgConfig').transition({
141 opacity: 0.0,
142 duration: animation_duration,
143 },
144 async function () {
145 await delay(50);
146 $('#cfgConfig').removeClass('resizing');
147 });
148 setTimeout(function () {
149 $('#cfgConfig').hide();
150 }, animation_duration);
151132
133 //auto-open the main AN inline drawer
134 if ($('#CFGBlockToggle')
135 .siblings('.inline-drawer-content')
136 .css('display') !== 'block') {
137 $('#floatingPrompt').addClass('resizing');
138 $('#CFGBlockToggle').click();
152 }139 }
153 //duplicate options menu close handler from script.js
154 //because this listener takes priority
155 $('#options').stop().fadeOut(animation_duration);
156 } else {140 } else {
157 toastr.warning('Select a character before trying to configure CFG', '', { timeOut: 2000 });141 //hide AN if it's already displayed
142 $('#cfgConfig').addClass('resizing');
143 $('#cfgConfig').transition({
144 opacity: 0.0,
145 duration: animation_duration,
146 }, async function () {
147 await delay(50);
148 $('#cfgConfig').removeClass('resizing');
149 });
150 setTimeout(function () {
151 $('#cfgConfig').hide();
152 }, animation_duration);
153
158 }154 }
155 //duplicate options menu close handler from script.js
156 //because this listener takes priority
157 $('#options').stop().fadeOut(animation_duration);
159}158}
160159
161async function onChatChanged() {160async function onChatChanged() {
@@ -288,7 +287,7 @@ export function initCfg() {
288 setTimeout(function () { $('#cfgConfig').hide(); }, animation_duration);287 setTimeout(function () { $('#cfgConfig').hide(); }, animation_duration);
289 });288 });
290289
291 $('#chat_cfg_guidance_scale').on('input', function() {290 $('#chat_cfg_guidance_scale').on('input', function () {
292 const numberValue = Number($(this).val());291 const numberValue = Number($(this).val());
293 const success = setChatCfg(numberValue, settingType.guidance_scale);292 const success = setChatCfg(numberValue, settingType.guidance_scale);
294 if (success) {293 if (success) {
@@ -296,15 +295,15 @@ export function initCfg() {
296 }295 }
297 });296 });
298297
299 $('#chat_cfg_negative_prompt').on('input', function() {298 $('#chat_cfg_negative_prompt').on('input', function () {
300 setChatCfg($(this).val(), settingType.negative_prompt);299 setChatCfg($(this).val(), settingType.negative_prompt);
301 });300 });
302301
303 $('#chat_cfg_positive_prompt').on('input', function() {302 $('#chat_cfg_positive_prompt').on('input', function () {
304 setChatCfg($(this).val(), settingType.positive_prompt);303 setChatCfg($(this).val(), settingType.positive_prompt);
305 });304 });
306305
307 $('#chara_cfg_guidance_scale').on('input', function() {306 $('#chara_cfg_guidance_scale').on('input', function () {
308 const value = $(this).val();307 const value = $(this).val();
309 const success = setCharCfg(value, settingType.guidance_scale);308 const success = setCharCfg(value, settingType.guidance_scale);
310 if (success) {309 if (success) {
@@ -312,34 +311,34 @@ export function initCfg() {
312 }311 }
313 });312 });
314313
315 $('#chara_cfg_negative_prompt').on('input', function() {314 $('#chara_cfg_negative_prompt').on('input', function () {
316 setCharCfg($(this).val(), settingType.negative_prompt);315 setCharCfg($(this).val(), settingType.negative_prompt);
317 });316 });
318317
319 $('#chara_cfg_positive_prompt').on('input', function() {318 $('#chara_cfg_positive_prompt').on('input', function () {
320 setCharCfg($(this).val(), settingType.positive_prompt);319 setCharCfg($(this).val(), settingType.positive_prompt);
321 });320 });
322321
323 $('#global_cfg_guidance_scale').on('input', function() {322 $('#global_cfg_guidance_scale').on('input', function () {
324 extension_settings.cfg.global.guidance_scale = Number($(this).val());323 extension_settings.cfg.global.guidance_scale = Number($(this).val());
325 $('#global_cfg_guidance_scale_counter').val(extension_settings.cfg.global.guidance_scale.toFixed(2));324 $('#global_cfg_guidance_scale_counter').val(extension_settings.cfg.global.guidance_scale.toFixed(2));
326 saveSettingsDebounced();325 saveSettingsDebounced();
327 });326 });
328327
329 $('#global_cfg_negative_prompt').on('input', function() {328 $('#global_cfg_negative_prompt').on('input', function () {
330 extension_settings.cfg.global.negative_prompt = $(this).val();329 extension_settings.cfg.global.negative_prompt = $(this).val();
331 saveSettingsDebounced();330 saveSettingsDebounced();
332 });331 });
333332
334 $('#global_cfg_positive_prompt').on('input', function() {333 $('#global_cfg_positive_prompt').on('input', function () {
335 extension_settings.cfg.global.positive_prompt = $(this).val();334 extension_settings.cfg.global.positive_prompt = $(this).val();
336 saveSettingsDebounced();335 saveSettingsDebounced();
337 });336 });
338337
339 $('input[name="cfg_prompt_combine"]').on('input', function() {338 $('input[name="cfg_prompt_combine"]').on('input', function () {
340 const values = $('#cfgConfig').find('input[name="cfg_prompt_combine"]')339 const values = $('#cfgConfig').find('input[name="cfg_prompt_combine"]')
341 .filter(':checked')340 .filter(':checked')
342 .map(function() { return Number($(this).val()); })341 .map(function () { return Number($(this).val()); })
343 .get()342 .get()
344 .filter((e) => !Number.isNaN(e)) || [];343 .filter((e) => !Number.isNaN(e)) || [];
345344
@@ -347,17 +346,17 @@ export function initCfg() {
347 saveMetadataDebounced();346 saveMetadataDebounced();
348 });347 });
349348
350 $('#cfg_prompt_insertion_depth').on('input', function() {349 $('#cfg_prompt_insertion_depth').on('input', function () {
351 chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());350 chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());
352 saveMetadataDebounced();351 saveMetadataDebounced();
353 });352 });
354353
355 $('#cfg_prompt_separator').on('input', function() {354 $('#cfg_prompt_separator').on('input', function () {
356 chat_metadata[metadataKeys.prompt_separator] = $(this).val();355 chat_metadata[metadataKeys.prompt_separator] = $(this).val();
357 saveMetadataDebounced();356 saveMetadataDebounced();
358 });357 });
359358
360 $('#groupchat_cfg_use_chara').on('input', function() {359 $('#groupchat_cfg_use_chara').on('input', function () {
361 const checked = !!$(this).prop('checked');360 const checked = !!$(this).prop('checked');
362 chat_metadata[metadataKeys.groupchat_individual_chars] = checked;361 chat_metadata[metadataKeys.groupchat_individual_chars] = checked;
363362
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+26 -16
@@ -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,20 +5173,24 @@ 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) {
5173 const worldName = characters[chid]?.data?.extensions?.world;5180 openSetWorldMenu();
5174 const hasEmbed = checkEmbeddedWorld(chid);5181 return;
5175 if (worldName && world_names.includes(worldName) && !event.shiftKey) {5182 }
5176 openWorldInfoEditor(worldName);5183
5177 } else if (hasEmbed && !event.shiftKey) {5184 const worldName = characters[chid]?.data?.extensions?.world;
5178 await importEmbeddedWorldInfo();5185 const hasEmbed = checkEmbeddedWorld(chid);
5179 saveCharacterDebounced();5186 if (worldName && world_names.includes(worldName) && !event.shiftKey) {
5180 }5187 openWorldInfoEditor(worldName);
5181 else {5188 } else if (hasEmbed && !event.shiftKey) {
5182 $('#char-management-dropdown').val($('#set_character_world').val()).trigger('change');5189 await importEmbeddedWorldInfo();
5183 }5190 saveCharacterDebounced();
5191 }
5192 else {
5193 openSetWorldMenu();
5184 }5194 }
5185 });5195 });
51865196