Feat/Link sampler selection lock to TC API Type (#4782) * Update - Revert connection profile change TC commands load order This change was made to prevent preset tied samplers from breaking, such thing doesn't exist anymore. * Update - Unlink preset renaming logic from sampler selection lock * Update - Link TC sampler selection lock to API Type * Fix - Clean comments * Update - Use localforage selectedSamplers and data selectsampler as main sampler selection storage * Fix - ESLint errors * Update - Change lock tooltip with correct description * Fix - Move and await sampler select localforage initializer to finish Tried to move it to the most reasonable place possible that allowed to make an await. * Fix - Make loadTextGenSettings async to load API selected samplers

e8a75c33299b7f164c1af8f531de3a804060a374

Leandro Jofré <leandrotomasjofre@gmail.com>

Signed
6 files changed, +149 -327Showing whitespace changes
public/script.js+1 -1
@@ -7395,7 +7395,7 @@ export async function getSettings() {
73957395 loadNovelSettings(data, settings.nai_settings ?? settings);
73967396
73977397 // TextGen
73987398 await loadTextGenSettings(data, settings);
73997399
74007400 // OpenAI
74017401 loadOpenAISettings(data, settings.oai_settings ?? settings);
public/scripts/extensions/connection-manager/index.js+1 -1
@@ -47,8 +47,8 @@ const CC_COMMANDS = [
4747];
4848
4949const TC_COMMANDS = [
50- 'preset',
5150 'api',
51+ 'preset',
5252 'api-url',
5353 'model',
5454 'sysprompt',
public/scripts/preset-manager.js+0 -11
@@ -27,7 +27,6 @@ import { oai_settings, openai_setting_names, openai_settings } from './openai.js
2727import { POPUP_RESULT, POPUP_TYPE, Popup } from './popup.js';
2828import { context_presets, getContextSettings, power_user } from './power-user.js';
2929import { reasoning_templates } from './reasoning.js';
30-import { getManualPresetSamplers, resetPresetSelectedSamplers, setPresetSamplersState } from './samplerSelect.js';
3130import { SlashCommand } from './slash-commands/SlashCommand.js';
3231import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
3332import { enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
@@ -1072,16 +1071,6 @@ export async function initPresetManager() {
10721071 return;
10731072 }
10741073
1075- if (apiId === 'textgenerationwebui') {
1076- const manualSamplersIterable = Object.entries(getManualPresetSamplers(oldName));
1077-
1078- for (const [sampler, value] of manualSamplersIterable) {
1079- setPresetSamplersState(sampler, value, newName);
1080- }
1081-
1082- await resetPresetSelectedSamplers(oldName, true);
1083- }
1084-
10851074 const successToast = !presetManager.isAdvancedFormatting() ? t`Preset renamed` : t`Template renamed`;
10861075 toastr.success(successToast);
10871076 });
public/scripts/samplerSelect.js+133 -295
@@ -2,7 +2,6 @@ import {
22 main_api,
33 saveSettingsDebounced,
44} from '../script.js';
5-import { power_user } from './power-user.js';
65//import { BIAS_CACHE, displayLogitBias, getLogitBiasListResult } from './logit-bias.js';
76//import { getEventSourceStream } from './sse-stream.js';
87//import { getSortableDelay, onlyUnique } from './utils.js';
@@ -14,8 +13,11 @@ import { localforage } from '../lib.js';
1413
1514const forcedOnColoring = 'color: #89db35;';
1615const forcedOffColoring = 'color: #e84f62;';
17-
16+const SELECT_SAMPLER = {
18-let userDisabledSamplers, userShownSamplers;
17+ DATA: 'selectsampler',
18+ SHOWN: 'shown',
19+ HIDDEN: 'hidden',
20+};
1921
2022const textGenObjectStore = localforage.createInstance({ name: 'SillyTavern_TextCompletions' });
2123let selectedSamplers = {};
@@ -38,28 +40,15 @@ async function showSamplerSelectPopup() {
3840
3941 $('#resetSelectedSamplers').off('click').on('click', async function () {
4042 console.log('saw sampler select reset click');
41- userDisabledSamplers = [];
42- userShownSamplers = [];
43- power_user.selectSamplers.forceShown = [];
44- power_user.selectSamplers.forceHidden = [];
4543
4644 if (main_api === 'textgenerationwebui') {
4745 $('#prioritizeManuallySelectedSamplers').toggleClass('toggleEnabled', false);
4846 await resetPresetSelectedSamplersresetApiSelectedSamplers(null, true);
4947 }
5048
5149 await validateDisabledSamplers(true);
5250 });
5351
54- $('#textgen_type').on('change', async function () {
55- console.log('changed TG Type, resetting custom samplers'); //unfortunate, but necessary unless we save custom samplers for each TGTytpe
56- userDisabledSamplers = [];
57- userShownSamplers = [];
58- power_user.selectSamplers.forceShown = [];
59- power_user.selectSamplers.forceHidden = [];
60- await validateDisabledSamplers();
61- });
62-
6352 if (main_api === 'textgenerationwebui') {
6453 $('#prioritizeManuallySelectedSamplers').show();
6554 $('#prioritizeManuallySelectedSamplers').toggleClass('toggleEnabled', isSamplerManualPriorityEnabled());
@@ -76,51 +65,54 @@ async function showSamplerSelectPopup() {
7665 }
7766
7867 await showPromise;
7968 if (main_api === 'textgenerationwebui') await savePresetSelectedSamplerssaveApiSelectedSamplers();
8069}
8170
8271function setSamplerListListenersgetRelatedDOMElement(samplerName) {
83- // Goal 2: hide unchecked samplers from DOM
84- let listContainer = $('#apiSamplersList');
85- listContainer.find('input').off('change').on('change', async function () {
86-
87- const samplerName = this.name.replace('_checkbox', '');
8872 let relatedDOMElement = $(`#${samplerName}_${main_api}`).parent();
8973 let targetDisplayType = 'flex';
74+ let displayname;
9075
9176 if (samplerName === 'json_schema') {
9277 relatedDOMElement = $('#json_schema_block');
9378 targetDisplayType = 'block';
79+ displayname = 'JSON Schema Block';
9480 }
9581
9682 if (samplerName === 'grammar_string') {
9783 relatedDOMElement = $('#grammar_block_ooba');
9884 targetDisplayType = 'block';
85+ displayname = 'Grammar Block';
9986 }
10087
10188 if (samplerName === 'guidance_scale') {
10289 relatedDOMElement = $('#cfg_block_ooba');
10390 targetDisplayType = 'block';
91+ displayname = 'CFG Block';
10492 }
10593
10694 if (samplerName === 'mirostat_mode') {
10795 relatedDOMElement = $('#mirostat_block_ooba');
10896 targetDisplayType = 'block';
97+ displayname = 'Mirostat Block';
10998 }
11099
111100 if (samplerName === 'dry_multiplier') {
112101 relatedDOMElement = $('#dryBlock');
113102 targetDisplayType = 'block';
103+ displayname = 'DRY Rep Pen Block';
114104 }
115105
116106 if (samplerName === 'xtc_probability') {
117107 relatedDOMElement = $('#xtc_block');
118108 targetDisplayType = 'block';
109+ displayname = 'XTC Block';
119110 }
120111
121112 if (samplerName === 'dynatemp') {
122113 relatedDOMElement = $('#dynatemp_block_ooba');
123114 targetDisplayType = 'block';
115+ displayname = 'DynaTemp Block';
124116 }
125117
126118 if (samplerName === 'banned_tokens') {
@@ -130,84 +122,86 @@ function setSamplerListListeners() {
130122
131123 if (samplerName === 'sampler_order') { //this is for kcpp sampler order
132124 relatedDOMElement = $('#sampler_order_block_kcpp');
125+ displayname = 'KCPP Sampler Order Block';
133126 }
134127
135128 if (samplerName === 'samplers') { //this is for lcpp sampler order
136129 relatedDOMElement = $('#sampler_order_block_lcpp');
130+ displayname = 'LCPP Sampler Order Block';
137131 }
138132
139133 if (samplerName === 'sampler_priority') { //this is for ooba's sampler priority
140134 relatedDOMElement = $('#sampler_priority_block_ooba');
135+ displayname = 'Ooba Sampler Priority Block';
141136 }
142137
143138 if (samplerName === 'samplers_priorities') { //this is for aphrodite's sampler priority
144139 relatedDOMElement = $('#sampler_priority_block_aphrodite');
140+ displayname = 'Aphrodite Sampler Priority Block';
145141 }
146142
147143 if (samplerName === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block?
148144 relatedDOMElement = $('#contrastiveSearchBlock');
145+ displayname = 'Contrast Search Block';
149146 }
150147
151148 if (samplerName === 'num_beams') { // num_beams is the killswitch for Beam Search
152149 relatedDOMElement = $('#beamSearchBlock');
153150 targetDisplayType = 'block';
151+ displayname = 'Beam Search Block';
154152 }
155153
156154 if (samplerName === 'smoothing_factor') { // num_beams is the killswitch for Beam Search
157155 relatedDOMElement = $('#smoothingBlock');
158156 targetDisplayType = 'block';
157+ displayname = 'Smoothing Block';
159158 }
160159
160+ return { relatedDOMElement, targetDisplayType, displayname };
161+}
162+
163+function setSamplerListListeners() {
164+ // Goal 2: hide unchecked samplers from DOM
165+ let listContainer = $('#apiSamplersList');
166+ listContainer.find('input').off('change').on('change', async function () {
167+ const samplerName = this.name.replace('_checkbox', '');
168+ const { relatedDOMElement, targetDisplayType } = getRelatedDOMElement(samplerName);
169+
161170 // Get the current state of the custom data attribute
162171 const previousState = relatedDOMElement.data('selectsampler'SELECT_SAMPLER.DATA);
163-
172+ const isChecked = $(this).prop('checked');
164- if ($(this).prop('checked') === false) {
173+ const popupInputLabel = $(this).parent().find('.sampler_name');
165- //console.log('saw clicking checkbox from on to off...');
174+
166175 if (previousStateisChecked === 'shown'false) {
167- console.log('saw previously custom shown sampler');
176+ if (previousState === SELECT_SAMPLER.SHOWN) {
168177 //console.log('removingsaw frompreviously custom forceshown showsampler list=> new state:', isChecked, samplerName);
169178 relatedDOMElement.removeData('selectsampler'SELECT_SAMPLER.DATA);
170179 $(this).parent().find('.sampler_name')popupInputLabel.removeAttr('style');
171- power_user?.selectSamplers?.forceShown.splice(power_user?.selectSamplers?.forceShown.indexOf(samplerName), 1);
180+ } else {
172- console.log(power_user?.selectSamplers?.forceShown);
181+ console.log('saw previous untouched sampler => new state:', isChecked, samplerName);
182+ relatedDOMElement.data(SELECT_SAMPLER.DATA, SELECT_SAMPLER.HIDDEN);
183+ popupInputLabel.attr('style', forcedOffColoring);
184+ }
173185 } else {
174- console.log('saw previous untouched sampler');
186+ if (previousState === SELECT_SAMPLER.HIDDEN) {
175- //console.log(`adding ${samplerName} to force hide list`);
187+ console.log('saw previously custom hidden sampler => new state:', isChecked, samplerName);
176- relatedDOMElement.data('selectsampler', 'hidden');
188+ relatedDOMElement.removeData(SELECT_SAMPLER.DATA);
177189 console.log(relatedDOMElementpopupInputLabel.dataremoveAttr('selectsamplerstyle'));
178- power_user.selectSamplers.forceHidden.push(samplerName);
179- $(this).parent().find('.sampler_name').attr('style', forcedOffColoring);
180- console.log(power_user.selectSamplers.forceHidden);
181- }
182- } else { // going from unchecked to checked
183- //console.log('saw clicking checkbox from off to on...');
184- if (previousState === 'hidden') {
185- console.log('saw previously custom hidden sampler');
186- //console.log('removing from custom force hide list');
187- relatedDOMElement.removeData('selectsampler');
188- $(this).parent().find('.sampler_name').removeAttr('style');
189- power_user?.selectSamplers?.forceHidden.splice(power_user?.selectSamplers?.forceHidden.indexOf(samplerName), 1);
190- console.log(power_user?.selectSamplers?.forceHidden);
191190 } else {
192191 console.log('saw previous untouched sampler => new state:', isChecked, samplerName);
193- //console.log(`adding ${samplerName} to force shown list`);
192+ relatedDOMElement.data(SELECT_SAMPLER.DATA, SELECT_SAMPLER.SHOWN);
194193 relatedDOMElementpopupInputLabel.dataattr('selectsamplerstyle', 'shown'forcedOnColoring);
195- console.log(relatedDOMElement.data('selectsampler'));
196- power_user.selectSamplers.forceShown.push(samplerName);
197- $(this).parent().find('.sampler_name').attr('style', forcedOnColoring);
198- console.log(power_user.selectSamplers.forceShown);
199194 }
200195 }
196+
201197 await saveSettingsDebounced();
202198
203199 const shouldDisplay = $(this).prop('checked')isChecked ? targetDisplayType : 'none';
204200 relatedDOMElement.css('display', shouldDisplay);
205201
206202 if (main_api === 'textgenerationwebui') {setApiSamplersState(samplerName, shouldDisplay !== 'none');
207- setPresetSamplersState(samplerName, shouldDisplay !== 'none');
208- }
209203
210204 console.log(samplerName, relatedDOMElement.data('selectsampler'SELECT_SAMPLER.DATA), shouldDisplay);
211205 });
212206
213207}
@@ -237,115 +231,42 @@ async function listSamplers(main_api, arrayOnly = false) {
237231 return availableSamplers;
238232 }
239233
240234 const samplersActivatedManually = (main_api === 'textgenerationwebui') ? getManualActivePresetSamplersgetActiveManualApiSamplers() : [];
241235 const prioritizeManualSamplerSelect = (main_api === 'textgenerationwebui') ? isSamplerManualPriorityEnabled() : false;
242236
243237 const samplersListHTML = availableSamplers.reduce((html, sampler) => {
244238 let customColor, displayname;
245- let targetDOMelement = $(`#${sampler}_${main_api}`);
239+ let { relatedDOMElement, displayname } = getRelatedDOMElement(sampler);
246-
247- if (sampler === 'sampler_order') { //this is for kcpp sampler order
248- targetDOMelement = $('#sampler_order_block_kcpp');
249- displayname = 'KCPP Sampler Order Block';
250- }
251-
252- if (sampler === 'samplers') { //this is for lcpp sampler order
253- targetDOMelement = $('#sampler_order_block_lcpp');
254- displayname = 'LCPP Sampler Order Block';
255- }
256-
257- if (sampler === 'sampler_priority') { //this is for ooba's sampler priority
258- targetDOMelement = $('#sampler_priority_block_ooba');
259- displayname = 'Ooba Sampler Priority Block';
260- }
261-
262- if (sampler === 'samplers_priorities') { //this is for aphrodite's sampler priority
263- targetDOMelement = $('#sampler_priority_block_aphrodite');
264- displayname = 'Aphrodite Sampler Priority Block';
265- }
266-
267- if (sampler === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block?
268- targetDOMelement = $('#contrastiveSearchBlock');
269- displayname = 'Contrast Search Block';
270- }
271-
272- if (sampler === 'num_beams') { // num_beams is the killswitch for Beam Search
273- targetDOMelement = $('#beamSearchBlock');
274- displayname = 'Beam Search Block';
275- }
276-
277- if (sampler === 'smoothing_factor') { // num_beams is the killswitch for Beam Search
278- targetDOMelement = $('#smoothingBlock');
279- displayname = 'Smoothing Block';
280- }
281240
282- if (sampler === 'dry_multiplier') {
241+ const isManuallyActivated = samplersActivatedManually.includes(sampler);
283- targetDOMelement = $('#dryBlock');
242+ const displayModified = relatedDOMElement.data(SELECT_SAMPLER.DATA);
284- displayname = 'DRY Rep Pen Block';
243+ const isInDefaultState = !displayModified;
285- }
286- if (sampler === 'xtc_probability') {
287- targetDOMelement = $('#xtc_block');
288- displayname = 'XTC Block';
289- }
290244
291245 ifconst (samplershouldBeChecked === 'dynatemp'() => {
292246 targetDOMelementlet finalState = $isElementVisibleInDOM('#dynatemp_block_ooba'relatedDOMElement[0]);
293- displayname = 'DynaTemp Block';
294- }
295247
296248 if (sampler === 'json_schema'prioritizeManualSamplerSelect) {
297- targetDOMelement = $('#json_schema_block');
249+ finalState = isManuallyActivated;
298- displayname = 'JSON Schema Block';
299250 }
300251
301- if (sampler === 'grammar_string') {
252+ else if (!isInDefaultState) {
302- targetDOMelement = $('#grammar_block_ooba');
253+ finalState = displayModified === SELECT_SAMPLER.SHOWN;
303- displayname = 'Grammar Block';
254+ customColor = finalState ? forcedOnColoring : forcedOffColoring;
304255 }
305256
306- if (sampler === 'guidance_scale') {
257+ return finalState;
307- targetDOMelement = $('#cfg_block_ooba');
258+ };
308- displayname = 'CFG Block';
309- }
310259
311- if (sampler === 'mirostat_mode') {
260+ console.log(sampler, relatedDOMElement.prop('id'), isInDefaultState, shouldBeChecked());
312- targetDOMelement = $('#mirostat_block_ooba');
313- displayname = 'Mirostat Block';
314- }
315261
316- const isManuallyActivated = samplersActivatedManually.includes(sampler);
262+ if (displayname === undefined) displayname = sampler;
317- const isInForceHiddenArray = userDisabledSamplers.includes(sampler);
263+ if (main_api === 'textgenerationwebui') setApiSamplersState(sampler, shouldBeChecked());
318- const isInForceShownArray = userShownSamplers.includes(sampler);
319- let isVisibleInDOM = isElementVisibleInDOM(targetDOMelement[0]);
320- const isInDefaultState = () => {
321- if (isVisibleInDOM && isInForceShownArray) { return false; }
322- else if (!isVisibleInDOM && isInForceHiddenArray) { return false; }
323- else { return true; }
324- };
325264
326- const shouldBeChecked = () => {
327- if (prioritizeManualSamplerSelect) {
328- return isManuallyActivated;
329- }
330- else if (isInForceHiddenArray) {
331- customColor = forcedOffColoring;
332- return false;
333- }
334- else if (isInForceShownArray) {
335- customColor = forcedOnColoring;
336- return true;
337- }
338- else { return isVisibleInDOM; }
339- };
340- console.log(sampler, targetDOMelement.prop('id'), isInDefaultState(), isInForceShownArray, isInForceHiddenArray, shouldBeChecked());
341- if (displayname === undefined) { displayname = sampler; }
342- if (main_api === 'textgenerationwebui') setPresetSamplersState(sampler, shouldBeChecked());
343265 return html + `
344266 <divlabel class="sampler_view_list_item wide50p flex-container">
345267 <input type="checkbox" name="${sampler}_checkbox" ${shouldBeChecked() ? 'checked' : ''}>
346268 <small class="sampler_name" style="${customColor}">${displayname}</small>
347269 </divlabel>`;
348- `;
349270 }, '');
350271
351272 return samplersListHTML;
@@ -361,109 +282,28 @@ export async function validateDisabledSamplers(redraw = false) {
361282 return;
362283 }
363284
364285 const samplersActivatedManually = (main_api === 'textgenerationwebui') ? getManualActivePresetSamplersgetActiveManualApiSamplers() : [];
365286 const prioritizeManualSamplerSelect = (main_api === 'textgenerationwebui') ? isSamplerManualPriorityEnabled() : false;
366287
367288 for (const sampler of APISamplers) {
368- let relatedDOMElement = $(`#${sampler}_${main_api}`).parent();
289+ const { relatedDOMElement, targetDisplayType } = getRelatedDOMElement(sampler);
369- let targetDisplayType = 'flex';
370-
371- if (sampler === 'json_schema') {
372- relatedDOMElement = $('#json_schema_block');
373- targetDisplayType = 'block';
374- }
375-
376- if (sampler === 'grammar_string') {
377- relatedDOMElement = $('#grammar_block_ooba');
378- targetDisplayType = 'block';
379- }
380-
381- if (sampler === 'guidance_scale') {
382- relatedDOMElement = $('#cfg_block_ooba');
383- targetDisplayType = 'block';
384- }
385-
386- if (sampler === 'mirostat_mode') {
387- relatedDOMElement = $('#mirostat_block_ooba');
388- targetDisplayType = 'block';
389- }
390-
391- if (sampler === 'dynatemp') {
392- relatedDOMElement = $('#dynatemp_block_ooba');
393- targetDisplayType = 'block';
394- }
395-
396- if (sampler === 'banned_tokens') {
397- relatedDOMElement = $('#banned_tokens_block_ooba');
398- targetDisplayType = 'block';
399- }
400-
401- if (sampler === 'sampler_order') { //this is for kcpp sampler order
402- relatedDOMElement = $('#sampler_order_block_kcpp');
403- }
404-
405- if (sampler === 'samplers') { //this is for lcpp sampler order
406- relatedDOMElement = $('#sampler_order_block_lcpp');
407- }
408-
409- if (sampler === 'sampler_priority') { //this is for ooba's sampler priority
410- relatedDOMElement = $('#sampler_priority_block_ooba');
411- }
412-
413- if (sampler === 'samplers_priorities') { //this is for aphrodite's sampler priority
414- relatedDOMElement = $('#sampler_priority_block_aphrodite');
415- }
416-
417- if (sampler === 'dry_multiplier') {
418- relatedDOMElement = $('#dryBlock');
419- targetDisplayType = 'block';
420- }
421-
422- if (sampler === 'xtc_probability') {
423- relatedDOMElement = $('#xtc_block');
424- targetDisplayType = 'block';
425- }
426-
427- if (sampler === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block?
428- relatedDOMElement = $('#contrastiveSearchBlock');
429- }
430-
431- if (sampler === 'num_beams') { // num_beams is the killswitch for Beam Search
432- relatedDOMElement = $('#beamSearchBlock');
433- }
434-
435- if (sampler === 'smoothing_factor') { // num_beams is the killswitch for Beam Search
436- relatedDOMElement = $('#smoothingBlock');
437- }
438-
439-
440- if (power_user?.selectSamplers?.forceHidden.includes(sampler)) {
441- //default handling for standard sliders
442- relatedDOMElement.data('selectsampler', 'hidden');
443- relatedDOMElement.css('display', 'none');
444- } else if (power_user?.selectSamplers?.forceShown.includes(sampler)) {
445- relatedDOMElement.data('selectsampler', 'shown');
446- relatedDOMElement.css('display', targetDisplayType);
447- } else {
448- if (relatedDOMElement.data('selectsampler') === 'hidden') {
449- relatedDOMElement.removeAttr('selectsampler');
450- relatedDOMElement.css('display', targetDisplayType);
451- }
452- if (relatedDOMElement.data('selectsampler') === 'shown') {
453- relatedDOMElement.removeAttr('selectsampler');
454- relatedDOMElement.css('display', 'none');
455- }
456- }
457290
458291 if (prioritizeManualSamplerSelect) {
459292 const isManuallyActivated = samplersActivatedManually.includes(sampler);
460293 relatedDOMElement.css('display', isManuallyActivated ? targetDisplayType : 'none');
294+ } else {
295+ const selectSamplerData = relatedDOMElement.data(SELECT_SAMPLER.DATA);
296+ relatedDOMElement.css('display', selectSamplerData === SELECT_SAMPLER.SHOWN ? targetDisplayType : 'none');
461297 }
298+
299+ relatedDOMElement.removeData(SELECT_SAMPLER.DATA);
462300 }
463301
464- if (redraw) {
302+ if (!prioritizeManualSamplerSelect && main_api === 'textgenerationwebui') {
465- if (main_api === 'textgenerationwebui') showTGSamplerControls();
303+ showTGSamplerControls();
304+ }
466305
306+ if (redraw) {
467307 let samplersHTML = await listSamplers(main_api);
468308 $('#apiSamplersList').empty().append(samplersHTML.toString());
469309 setSamplerListListeners();
@@ -474,8 +314,9 @@ export async function validateDisabledSamplers(redraw = false) {
474314
475315/**
476316 * Initializes the configuration object for manually selected samplers.
317+ * @returns void
477318 */
478319export async function loadPresetSelectedSamplersloadApiSelectedSamplers() {
479320 try {
480321 console.debug('Text Completions: loading selected samplers');
481322 selectedSamplers = await textGenObjectStore.getItem('selectedSamplers') || {};
@@ -487,8 +328,9 @@ export async function loadPresetSelectedSamplers() {
487328
488329/**
489330 * Synchronizes the local forage instance with the selected samplers configuration object.
331+ * @returns void
490332 */
491333export async function savePresetSelectedSamplerssaveApiSelectedSamplers() {
492334 try {
493335 console.debug('Text Completions: saving selected samplers');
494336 await textGenObjectStore.setItem('selectedSamplers', selectedSamplers);
@@ -499,18 +341,19 @@ export async function savePresetSelectedSamplers() {
499341
500342/**
501343 * Resets the selected samplers configuration object from the local forage instance.
502344 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
503345 * @param {boolean} silent Suppresses the toastr message confirming that the data was deleted.
346+ * @returns void
504347 */
505348export async function resetPresetSelectedSamplersresetApiSelectedSamplers(presetNametcApiType = '', silent = false) {
506349 try {
507350 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return;
508351 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
509352 if (!selectedSamplers[presetNametcApiType]) return;
510353
511354 console.debug('Text Completions: resetting selected samplers');
512355 delete selectedSamplers[presetNametcApiType];
513356 await savePresetSelectedSamplerssaveApiSelectedSamplers();
514357 if (!silent) toastr.success('Selected samplers cleared.');
515358 } catch (error) {
516359 console.log('Text Completions: unable to reset selected preset samplers', error);
@@ -521,43 +364,43 @@ export async function resetPresetSelectedSamplers(presetName = '', silent = fals
521364 * Saves the visibility state for selected samplers into the configuration object.
522365 * @param {string} samplerName Target sampler key name
523366 * @param {string|boolean} state Visibility state of the target sampler
524367 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
525368 * @returns void
526369 */
527370export function setPresetSamplersStatesetApiSamplersState(samplerName, state, presetNametcApiType = '') {
528371 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return;
529372 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
530373 if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {};
531374
532375 const presetSamplers = selectedSamplers[presetNametcApiType];
533376 presetSamplers[samplerName] = String(state) === 'true';
534377}
535378
536379/**
537380 * Returns the local forage object belonging to the active/selected TC presetAPI Type
538381 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
539382 * @returns {object} Full localforage object with manual selections
540383 */
541384export function getManualPresetSamplersgetAllManualApiSamplers(presetNametcApiType = '') {
542385 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return {};
543386 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
544387 if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {};
545388
546389 return selectedSamplers[presetNametcApiType];
547390}
548391
549392/**
550393 * Returns the key names of all the preset samplersmanually activated manuallyAPI Type samplers.
551394 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
552395 * @returns {string[]} Array of sampler key names
553396 */
554397export function getManualActivePresetSamplersgetActiveManualApiSamplers(presetNametcApiType = '') {
555398 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return [];
556399 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
557400 if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {};
558401
559402 try {
560403 const presetSamplers = Object.entries(selectedSamplers[presetNametcApiType]);
561404
562405 return presetSamplers
563406 .filter(([key, val]) => val === true && key !== 'st_manual_priority')
@@ -570,36 +413,31 @@ export function getManualActivePresetSamplers(presetName = '') {
570413
571414/**
572415 * @param {string|boolean} state Target state of the feature
573416 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
574417 * @returns void
575418 */
576419export function toggleSamplerManualPriority(state = false, presetNametcApiType = '') {
577420 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return;
578421 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
579422 if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {};
580423
581424 const presetSamplers = selectedSamplers[presetNametcApiType];
582425 presetSamplers.st_manual_priority = String(state) === 'true';
583426}
584427
585428/**
586429 * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default
587430 * @returns {boolean}
588431 */
589432export function isSamplerManualPriorityEnabled(presetNametcApiType = '') {
590433 if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return false;
591434 if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype;
592435 if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {};
593436
594437 return selectedSamplers[presetNametcApiType]?.st_manual_priority ?? false;
595438}
596439
597440export async function initCustomSelectedSamplers() {
598- userDisabledSamplers = power_user?.selectSamplers?.forceHidden || [];
599- userShownSamplers = power_user?.selectSamplers?.forceShown || [];
600- power_user.selectSamplers = {};
601- power_user.selectSamplers.forceHidden = userDisabledSamplers;
602- power_user.selectSamplers.forceShown = userShownSamplers;
603441 await saveSettingsDebounced();
604442 $('#samplerSelectButton').off('click').on('click', showSamplerSelectPopup);
605443}
public/scripts/templates/samplerSelector.html+1 -1
@@ -10,7 +10,7 @@
1010 <i class="fa-solid fa-lock"></i>
1111 <span data-i18n="Prioritize">Prioritize</span>
1212 </div>
1313 <div class="margin5 fa-solid fa-exclamation-circle" data-i18n="[title]Toggle on to force the samplers selected in this menu to be shown when switching to thisthe presetcurrent API Type (API Connections Panel). By default, SillyTavern automatically selects samplers used or needed by the selected API Type in the API Connections panel." title="Toggle on to force the samplers selected in this menu to be shown when switching to thisthe presetcurrent API Type (API Connections Panel). By default, SillyTavern automatically selects samplers used or needed by the selected API Type in the API Connections panel."></div>
1414 </div>
1515 <!--<div class="flex-container alignItemsBaseline">
1616 <div class="menu_button menu_button_icon" title="Create a new sampler">
public/scripts/textgen-settings.js+13 -18
@@ -20,7 +20,7 @@ import { autoSelectInstructPreset, selectContextPreset, selectInstructPreset } f
2020import { BIAS_CACHE, createNewLogitBiasEntry, displayLogitBias, getLogitBiasListResult } from './logit-bias.js';
2121
2222import { power_user, registerDebugFunction } from './power-user.js';
2323import { getManualActivePresetSamplersgetActiveManualApiSamplers, isSamplerManualPriorityEnabledloadApiSelectedSamplers, loadPresetSelectedSamplersisSamplerManualPriorityEnabled } from './samplerSelect.js';
2424import { SECRET_KEYS, writeSecret } from './secrets.js';
2525import { getEventSourceStream } from './sse-stream.js';
2626import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer, loadAphroditeModels, loadDreamGenModels, loadFeatherlessModels, loadGenericModels, loadInfermaticAIModels, loadMancerModels, loadOllamaModels, loadOpenRouterModels, loadTabbyModels, loadTogetherAIModels, loadVllmModels } from './textgen-models.js';
@@ -372,7 +372,6 @@ async function selectPreset(name) {
372372 setSettingByName(name, value, true);
373373 }
374374 setGenerationParamsFromPreset(preset);
375- showSamplerControls(null, true);
376375 BIAS_CACHE.delete(BIAS_KEY);
377376 displayLogitBias(preset.logit_bias, BIAS_KEY);
378377 saveSettingsDebounced();
@@ -530,7 +529,8 @@ function calculateLogitBias() {
530529 return result;
531530}
532531
533532export async function loadTextGenSettings(data, loadedSettings) {
533+ await loadApiSelectedSamplers();
534534 textgenerationwebui_presets = convertPresets(data.textgenerationwebui_presets);
535535 textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? [];
536536 Object.assign(settings, loadedSettings.textgenerationwebui_settings ?? {});
@@ -572,8 +572,7 @@ export function loadTextGenSettings(data, loadedSettings) {
572572
573573 $('#textgen_type').val(settings.type);
574574 $('#openrouter_providers_text').val(settings.openrouter_providers).trigger('change');
575575 loadPresetSelectedSamplersshowSamplerControls(settings.type);
576- showSamplerControls();
577576 BIAS_CACHE.delete(BIAS_KEY);
578577 displayLogitBias(settings.logit_bias, BIAS_KEY);
579578
@@ -779,8 +778,6 @@ async function getStatusTextgen() {
779778}
780779
781780export function initTextGenSettings() {
782- loadPresetSelectedSamplers();
783-
784781 $('#send_banned_tokens_textgenerationwebui').on('change', function () {
785782 const checked = !!$(this).prop('checked');
786783 toggleBannedStringsKillSwitch(checked,
@@ -1078,21 +1075,19 @@ export function initTextGenSettings() {
10781075/**
10791076 * Hides and shows preset samplers from the left panel.
10801077 * @param {string?} apiType API Type selected in API Connections - Currently selected one by default
1081- * @param {boolean?} isPresetSwitch Wheter the trigger comes from a preset switch - false by default
10821078 * @returns void
10831079 */
10841080function showSamplerControls(apiType = null, isPresetSwitch = false) {
1085- const prioritizeManualSamplerSelect = isSamplerManualPriorityEnabled();
1081+ $('#textgenerationwebui_api-settings [data-tg-samplers]').each(function(idx, elem) {
1086-
1082+ const typeSpecificControlled = $(elem).data('tg-type') !== undefined;
1087- if (isPresetSwitch && !prioritizeManualSamplerSelect) return;
10881083
1089- $('#textgenerationwebui_api-settings [data-tg-samplers]:not([data-tg-type])').each(function() {
1084+ if (!typeSpecificControlled) $(this).show();
1090- $(this).show();
10911085 });
10921086
10931087 showTypeSpecificControls(apiType ?? settings.type);
10941088
10951089 const samplersActivatedManuallyprioritizeManualSamplerSelect = getManualActivePresetSamplersisSamplerManualPriorityEnabled(apiType ?? settings.type);
1090+ const samplersActivatedManually = getActiveManualApiSamplers(apiType ?? settings.type);
10961091
10971092 if (!samplersActivatedManually?.length || !prioritizeManualSamplerSelect) return;
10981093
@@ -1110,18 +1105,18 @@ function showSamplerControls(apiType = null, isPresetSwitch = false) {
11101105 });
11111106}
11121107
11131108function showTypeSpecificControls(typeapiType) {
11141109 $('[data-tg-type]').each(function () {
11151110 const mode = String($(this).attr('data-tg-type-mode') ?? '').toLowerCase().trim();
11161111 const tgTypes = $(this).attr('data-tg-type').split(',').map(x => x.trim());
11171112
11181113 if (mode === 'except') {
11191114 $(this)[tgTypes.includes(typeapiType) ? 'hide' : 'show']();
11201115 return;
11211116 }
11221117
11231118 for (const tgType of tgTypes) {
11241119 if (tgType === typeapiType || tgType == 'all') {
11251120 $(this).show();
11261121 return;
11271122 } else {