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
Signed| @@ -7395,7 +7395,7 @@ export async function getSettings() { | ||
| 7395 | 7395 | loadNovelSettings(data, settings.nai_settings ?? settings); |
| 7396 | 7396 | |
| 7397 | 7397 | // TextGen |
| 7398 | 7398 | await loadTextGenSettings(data, settings); |
| 7399 | 7399 | |
| 7400 | 7400 | // OpenAI |
| 7401 | 7401 | loadOpenAISettings(data, settings.oai_settings ?? settings); |
| @@ -47,8 +47,8 @@ const CC_COMMANDS = [ | ||
| 47 | 47 | ]; |
| 48 | 48 | |
| 49 | 49 | const TC_COMMANDS = [ |
| 50 | - 'preset', | |
| 51 | 50 | 'api', |
| 51 | + 'preset', | |
| 52 | 52 | 'api-url', |
| 53 | 53 | 'model', |
| 54 | 54 | 'sysprompt', |
| @@ -27,7 +27,6 @@ import { oai_settings, openai_setting_names, openai_settings } from './openai.js | ||
| 27 | 27 | import { POPUP_RESULT, POPUP_TYPE, Popup } from './popup.js'; |
| 28 | 28 | import { context_presets, getContextSettings, power_user } from './power-user.js'; |
| 29 | 29 | import { reasoning_templates } from './reasoning.js'; |
| 30 | -import { getManualPresetSamplers, resetPresetSelectedSamplers, setPresetSamplersState } from './samplerSelect.js'; | |
| 31 | 30 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 32 | 31 | import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js'; |
| 33 | 32 | import { enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| @@ -1072,16 +1071,6 @@ export async function initPresetManager() { | ||
| 1072 | 1071 | return; |
| 1073 | 1072 | } |
| 1074 | 1073 | |
| 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 | - | |
| 1085 | 1074 | const successToast = !presetManager.isAdvancedFormatting() ? t`Preset renamed` : t`Template renamed`; |
| 1086 | 1075 | toastr.success(successToast); |
| 1087 | 1076 | }); |
| @@ -2,7 +2,6 @@ import { | ||
| 2 | 2 | main_api, |
| 3 | 3 | saveSettingsDebounced, |
| 4 | 4 | } from '../script.js'; |
| 5 | -import { power_user } from './power-user.js'; | |
| 6 | 5 | //import { BIAS_CACHE, displayLogitBias, getLogitBiasListResult } from './logit-bias.js'; |
| 7 | 6 | //import { getEventSourceStream } from './sse-stream.js'; |
| 8 | 7 | //import { getSortableDelay, onlyUnique } from './utils.js'; |
| @@ -14,8 +13,11 @@ import { localforage } from '../lib.js'; | ||
| 14 | 13 | |
| 15 | 14 | const forcedOnColoring = 'color: #89db35;'; |
| 16 | 15 | const forcedOffColoring = 'color: #e84f62;'; |
| 17 | - | |
| 16 | +const SELECT_SAMPLER = { | |
| 18 | -let userDisabledSamplers, userShownSamplers; | |
| 17 | + DATA: 'selectsampler', | |
| 18 | + SHOWN: 'shown', | |
| 19 | + HIDDEN: 'hidden', | |
| 20 | +}; | |
| 19 | 21 | |
| 20 | 22 | const textGenObjectStore = localforage.createInstance({ name: 'SillyTavern_TextCompletions' }); |
| 21 | 23 | let selectedSamplers = {}; |
| @@ -38,28 +40,15 @@ async function showSamplerSelectPopup() { | ||
| 38 | 40 | |
| 39 | 41 | $('#resetSelectedSamplers').off('click').on('click', async function () { |
| 40 | 42 | console.log('saw sampler select reset click'); |
| 41 | - userDisabledSamplers = []; | |
| 42 | - userShownSamplers = []; | |
| 43 | - power_user.selectSamplers.forceShown = []; | |
| 44 | - power_user.selectSamplers.forceHidden = []; | |
| 45 | 43 | |
| 46 | 44 | if (main_api === 'textgenerationwebui') { |
| 47 | 45 | $('#prioritizeManuallySelectedSamplers').toggleClass('toggleEnabled', false); |
| 48 | 46 | await resetPresetSelectedSamplersresetApiSelectedSamplers(null, true); |
| 49 | 47 | } |
| 50 | 48 | |
| 51 | 49 | await validateDisabledSamplers(true); |
| 52 | 50 | }); |
| 53 | 51 | |
| 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 | - | |
| 63 | 52 | if (main_api === 'textgenerationwebui') { |
| 64 | 53 | $('#prioritizeManuallySelectedSamplers').show(); |
| 65 | 54 | $('#prioritizeManuallySelectedSamplers').toggleClass('toggleEnabled', isSamplerManualPriorityEnabled()); |
| @@ -76,51 +65,54 @@ async function showSamplerSelectPopup() { | ||
| 76 | 65 | } |
| 77 | 66 | |
| 78 | 67 | await showPromise; |
| 79 | 68 | if (main_api === 'textgenerationwebui') await savePresetSelectedSamplerssaveApiSelectedSamplers(); |
| 80 | 69 | } |
| 81 | 70 | |
| 82 | 71 | function 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', ''); | |
| 88 | 72 | let relatedDOMElement = $(`#${samplerName}_${main_api}`).parent(); |
| 89 | 73 | let targetDisplayType = 'flex'; |
| 74 | + let displayname; | |
| 90 | 75 | |
| 91 | 76 | if (samplerName === 'json_schema') { |
| 92 | 77 | relatedDOMElement = $('#json_schema_block'); |
| 93 | 78 | targetDisplayType = 'block'; |
| 79 | + displayname = 'JSON Schema Block'; | |
| 94 | 80 | } |
| 95 | 81 | |
| 96 | 82 | if (samplerName === 'grammar_string') { |
| 97 | 83 | relatedDOMElement = $('#grammar_block_ooba'); |
| 98 | 84 | targetDisplayType = 'block'; |
| 85 | + displayname = 'Grammar Block'; | |
| 99 | 86 | } |
| 100 | 87 | |
| 101 | 88 | if (samplerName === 'guidance_scale') { |
| 102 | 89 | relatedDOMElement = $('#cfg_block_ooba'); |
| 103 | 90 | targetDisplayType = 'block'; |
| 91 | + displayname = 'CFG Block'; | |
| 104 | 92 | } |
| 105 | 93 | |
| 106 | 94 | if (samplerName === 'mirostat_mode') { |
| 107 | 95 | relatedDOMElement = $('#mirostat_block_ooba'); |
| 108 | 96 | targetDisplayType = 'block'; |
| 97 | + displayname = 'Mirostat Block'; | |
| 109 | 98 | } |
| 110 | 99 | |
| 111 | 100 | if (samplerName === 'dry_multiplier') { |
| 112 | 101 | relatedDOMElement = $('#dryBlock'); |
| 113 | 102 | targetDisplayType = 'block'; |
| 103 | + displayname = 'DRY Rep Pen Block'; | |
| 114 | 104 | } |
| 115 | 105 | |
| 116 | 106 | if (samplerName === 'xtc_probability') { |
| 117 | 107 | relatedDOMElement = $('#xtc_block'); |
| 118 | 108 | targetDisplayType = 'block'; |
| 109 | + displayname = 'XTC Block'; | |
| 119 | 110 | } |
| 120 | 111 | |
| 121 | 112 | if (samplerName === 'dynatemp') { |
| 122 | 113 | relatedDOMElement = $('#dynatemp_block_ooba'); |
| 123 | 114 | targetDisplayType = 'block'; |
| 115 | + displayname = 'DynaTemp Block'; | |
| 124 | 116 | } |
| 125 | 117 | |
| 126 | 118 | if (samplerName === 'banned_tokens') { |
| @@ -130,84 +122,86 @@ function setSamplerListListeners() { | ||
| 130 | 122 | |
| 131 | 123 | if (samplerName === 'sampler_order') { //this is for kcpp sampler order |
| 132 | 124 | relatedDOMElement = $('#sampler_order_block_kcpp'); |
| 125 | + displayname = 'KCPP Sampler Order Block'; | |
| 133 | 126 | } |
| 134 | 127 | |
| 135 | 128 | if (samplerName === 'samplers') { //this is for lcpp sampler order |
| 136 | 129 | relatedDOMElement = $('#sampler_order_block_lcpp'); |
| 130 | + displayname = 'LCPP Sampler Order Block'; | |
| 137 | 131 | } |
| 138 | 132 | |
| 139 | 133 | if (samplerName === 'sampler_priority') { //this is for ooba's sampler priority |
| 140 | 134 | relatedDOMElement = $('#sampler_priority_block_ooba'); |
| 135 | + displayname = 'Ooba Sampler Priority Block'; | |
| 141 | 136 | } |
| 142 | 137 | |
| 143 | 138 | if (samplerName === 'samplers_priorities') { //this is for aphrodite's sampler priority |
| 144 | 139 | relatedDOMElement = $('#sampler_priority_block_aphrodite'); |
| 140 | + displayname = 'Aphrodite Sampler Priority Block'; | |
| 145 | 141 | } |
| 146 | 142 | |
| 147 | 143 | if (samplerName === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block? |
| 148 | 144 | relatedDOMElement = $('#contrastiveSearchBlock'); |
| 145 | + displayname = 'Contrast Search Block'; | |
| 149 | 146 | } |
| 150 | 147 | |
| 151 | 148 | if (samplerName === 'num_beams') { // num_beams is the killswitch for Beam Search |
| 152 | 149 | relatedDOMElement = $('#beamSearchBlock'); |
| 153 | 150 | targetDisplayType = 'block'; |
| 151 | + displayname = 'Beam Search Block'; | |
| 154 | 152 | } |
| 155 | 153 | |
| 156 | 154 | if (samplerName === 'smoothing_factor') { // num_beams is the killswitch for Beam Search |
| 157 | 155 | relatedDOMElement = $('#smoothingBlock'); |
| 158 | 156 | targetDisplayType = 'block'; |
| 157 | + displayname = 'Smoothing Block'; | |
| 159 | 158 | } |
| 160 | 159 | |
| 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 | + | |
| 161 | 170 | // Get the current state of the custom data attribute |
| 162 | 171 | 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 | + | |
| 166 | 175 | if (previousStateisChecked === 'shown'false) { |
| 167 | - console.log('saw previously custom shown sampler'); | |
| 176 | + if (previousState === SELECT_SAMPLER.SHOWN) { | |
| 168 | 177 | //console.log('removingsaw frompreviously custom forceshown showsampler list=> new state:', isChecked, samplerName); |
| 169 | 178 | relatedDOMElement.removeData('selectsampler'SELECT_SAMPLER.DATA); |
| 170 | 179 | $(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 | + } | |
| 173 | 185 | } 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); | |
| 177 | 189 | 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); | |
| 191 | 190 | } else { |
| 192 | 191 | 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); | |
| 194 | 193 | 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); | |
| 199 | 194 | } |
| 200 | 195 | } |
| 196 | + | |
| 201 | 197 | await saveSettingsDebounced(); |
| 202 | 198 | |
| 203 | 199 | const shouldDisplay = $(this).prop('checked')isChecked ? targetDisplayType : 'none'; |
| 204 | 200 | relatedDOMElement.css('display', shouldDisplay); |
| 205 | 201 | |
| 206 | 202 | if (main_api === 'textgenerationwebui') {setApiSamplersState(samplerName, shouldDisplay !== 'none'); |
| 207 | - setPresetSamplersState(samplerName, shouldDisplay !== 'none'); | |
| 208 | - } | |
| 209 | 203 | |
| 210 | 204 | console.log(samplerName, relatedDOMElement.data('selectsampler'SELECT_SAMPLER.DATA), shouldDisplay); |
| 211 | 205 | }); |
| 212 | 206 | |
| 213 | 207 | } |
| @@ -237,115 +231,42 @@ async function listSamplers(main_api, arrayOnly = false) { | ||
| 237 | 231 | return availableSamplers; |
| 238 | 232 | } |
| 239 | 233 | |
| 240 | 234 | const samplersActivatedManually = (main_api === 'textgenerationwebui') ? getManualActivePresetSamplersgetActiveManualApiSamplers() : []; |
| 241 | 235 | const prioritizeManualSamplerSelect = (main_api === 'textgenerationwebui') ? isSamplerManualPriorityEnabled() : false; |
| 242 | 236 | |
| 243 | 237 | const samplersListHTML = availableSamplers.reduce((html, sampler) => { |
| 244 | 238 | 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 | - } | |
| 281 | 240 | |
| 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 | - } | |
| 290 | 244 | |
| 291 | 245 | ifconst (samplershouldBeChecked === 'dynatemp'() => { |
| 292 | 246 | targetDOMelementlet finalState = $isElementVisibleInDOM('#dynatemp_block_ooba'relatedDOMElement[0]); |
| 293 | - displayname = 'DynaTemp Block'; | |
| 294 | - } | |
| 295 | 247 | |
| 296 | 248 | if (sampler === 'json_schema'prioritizeManualSamplerSelect) { |
| 297 | - targetDOMelement = $('#json_schema_block'); | |
| 249 | + finalState = isManuallyActivated; | |
| 298 | - displayname = 'JSON Schema Block'; | |
| 299 | 250 | } |
| 300 | 251 | |
| 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; | |
| 304 | 255 | } |
| 305 | 256 | |
| 306 | - if (sampler === 'guidance_scale') { | |
| 257 | + return finalState; | |
| 307 | - targetDOMelement = $('#cfg_block_ooba'); | |
| 258 | + }; | |
| 308 | - displayname = 'CFG Block'; | |
| 309 | - } | |
| 310 | 259 | |
| 311 | - if (sampler === 'mirostat_mode') { | |
| 260 | + console.log(sampler, relatedDOMElement.prop('id'), isInDefaultState, shouldBeChecked()); | |
| 312 | - targetDOMelement = $('#mirostat_block_ooba'); | |
| 313 | - displayname = 'Mirostat Block'; | |
| 314 | - } | |
| 315 | 261 | |
| 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 | - }; | |
| 325 | 264 | |
| 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()); | |
| 343 | 265 | return html + ` |
| 344 | 266 | <divlabel class="sampler_view_list_item wide50p flex-container"> |
| 345 | 267 | <input type="checkbox" name="${sampler}_checkbox" ${shouldBeChecked() ? 'checked' : ''}> |
| 346 | 268 | <small class="sampler_name" style="${customColor}">${displayname}</small> |
| 347 | 269 | </divlabel>`; |
| 348 | - `; | |
| 349 | 270 | }, ''); |
| 350 | 271 | |
| 351 | 272 | return samplersListHTML; |
| @@ -361,109 +282,28 @@ export async function validateDisabledSamplers(redraw = false) { | ||
| 361 | 282 | return; |
| 362 | 283 | } |
| 363 | 284 | |
| 364 | 285 | const samplersActivatedManually = (main_api === 'textgenerationwebui') ? getManualActivePresetSamplersgetActiveManualApiSamplers() : []; |
| 365 | 286 | const prioritizeManualSamplerSelect = (main_api === 'textgenerationwebui') ? isSamplerManualPriorityEnabled() : false; |
| 366 | 287 | |
| 367 | 288 | 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 | - } | |
| 457 | 290 | |
| 458 | 291 | if (prioritizeManualSamplerSelect) { |
| 459 | 292 | const isManuallyActivated = samplersActivatedManually.includes(sampler); |
| 460 | 293 | 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'); | |
| 461 | 297 | } |
| 298 | + | |
| 299 | + relatedDOMElement.removeData(SELECT_SAMPLER.DATA); | |
| 462 | 300 | } |
| 463 | 301 | |
| 464 | - if (redraw) { | |
| 302 | + if (!prioritizeManualSamplerSelect && main_api === 'textgenerationwebui') { | |
| 465 | - if (main_api === 'textgenerationwebui') showTGSamplerControls(); | |
| 303 | + showTGSamplerControls(); | |
| 304 | + } | |
| 466 | 305 | |
| 306 | + if (redraw) { | |
| 467 | 307 | let samplersHTML = await listSamplers(main_api); |
| 468 | 308 | $('#apiSamplersList').empty().append(samplersHTML.toString()); |
| 469 | 309 | setSamplerListListeners(); |
| @@ -474,8 +314,9 @@ export async function validateDisabledSamplers(redraw = false) { | ||
| 474 | 314 | |
| 475 | 315 | /** |
| 476 | 316 | * Initializes the configuration object for manually selected samplers. |
| 317 | + * @returns void | |
| 477 | 318 | */ |
| 478 | 319 | export async function loadPresetSelectedSamplersloadApiSelectedSamplers() { |
| 479 | 320 | try { |
| 480 | 321 | console.debug('Text Completions: loading selected samplers'); |
| 481 | 322 | selectedSamplers = await textGenObjectStore.getItem('selectedSamplers') || {}; |
| @@ -487,8 +328,9 @@ export async function loadPresetSelectedSamplers() { | ||
| 487 | 328 | |
| 488 | 329 | /** |
| 489 | 330 | * Synchronizes the local forage instance with the selected samplers configuration object. |
| 331 | + * @returns void | |
| 490 | 332 | */ |
| 491 | 333 | export async function savePresetSelectedSamplerssaveApiSelectedSamplers() { |
| 492 | 334 | try { |
| 493 | 335 | console.debug('Text Completions: saving selected samplers'); |
| 494 | 336 | await textGenObjectStore.setItem('selectedSamplers', selectedSamplers); |
| @@ -499,18 +341,19 @@ export async function savePresetSelectedSamplers() { | ||
| 499 | 341 | |
| 500 | 342 | /** |
| 501 | 343 | * Resets the selected samplers configuration object from the local forage instance. |
| 502 | 344 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 503 | 345 | * @param {boolean} silent Suppresses the toastr message confirming that the data was deleted. |
| 346 | + * @returns void | |
| 504 | 347 | */ |
| 505 | 348 | export async function resetPresetSelectedSamplersresetApiSelectedSamplers(presetNametcApiType = '', silent = false) { |
| 506 | 349 | try { |
| 507 | 350 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return; |
| 508 | 351 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 509 | 352 | if (!selectedSamplers[presetNametcApiType]) return; |
| 510 | 353 | |
| 511 | 354 | console.debug('Text Completions: resetting selected samplers'); |
| 512 | 355 | delete selectedSamplers[presetNametcApiType]; |
| 513 | 356 | await savePresetSelectedSamplerssaveApiSelectedSamplers(); |
| 514 | 357 | if (!silent) toastr.success('Selected samplers cleared.'); |
| 515 | 358 | } catch (error) { |
| 516 | 359 | console.log('Text Completions: unable to reset selected preset samplers', error); |
| @@ -521,43 +364,43 @@ export async function resetPresetSelectedSamplers(presetName = '', silent = fals | ||
| 521 | 364 | * Saves the visibility state for selected samplers into the configuration object. |
| 522 | 365 | * @param {string} samplerName Target sampler key name |
| 523 | 366 | * @param {string|boolean} state Visibility state of the target sampler |
| 524 | 367 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 525 | 368 | * @returns void |
| 526 | 369 | */ |
| 527 | 370 | export function setPresetSamplersStatesetApiSamplersState(samplerName, state, presetNametcApiType = '') { |
| 528 | 371 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return; |
| 529 | 372 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 530 | 373 | if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {}; |
| 531 | 374 | |
| 532 | 375 | const presetSamplers = selectedSamplers[presetNametcApiType]; |
| 533 | 376 | presetSamplers[samplerName] = String(state) === 'true'; |
| 534 | 377 | } |
| 535 | 378 | |
| 536 | 379 | /** |
| 537 | 380 | * Returns the local forage object belonging to the active/selected TC presetAPI Type |
| 538 | 381 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 539 | 382 | * @returns {object} Full localforage object with manual selections |
| 540 | 383 | */ |
| 541 | 384 | export function getManualPresetSamplersgetAllManualApiSamplers(presetNametcApiType = '') { |
| 542 | 385 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return {}; |
| 543 | 386 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 544 | 387 | if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {}; |
| 545 | 388 | |
| 546 | 389 | return selectedSamplers[presetNametcApiType]; |
| 547 | 390 | } |
| 548 | 391 | |
| 549 | 392 | /** |
| 550 | 393 | * Returns the key names of all the preset samplersmanually activated manuallyAPI Type samplers. |
| 551 | 394 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 552 | 395 | * @returns {string[]} Array of sampler key names |
| 553 | 396 | */ |
| 554 | 397 | export function getManualActivePresetSamplersgetActiveManualApiSamplers(presetNametcApiType = '') { |
| 555 | 398 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return []; |
| 556 | 399 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 557 | 400 | if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {}; |
| 558 | 401 | |
| 559 | 402 | try { |
| 560 | 403 | const presetSamplers = Object.entries(selectedSamplers[presetNametcApiType]); |
| 561 | 404 | |
| 562 | 405 | return presetSamplers |
| 563 | 406 | .filter(([key, val]) => val === true && key !== 'st_manual_priority') |
| @@ -570,36 +413,31 @@ export function getManualActivePresetSamplers(presetName = '') { | ||
| 570 | 413 | |
| 571 | 414 | /** |
| 572 | 415 | * @param {string|boolean} state Target state of the feature |
| 573 | 416 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 574 | 417 | * @returns void |
| 575 | 418 | */ |
| 576 | 419 | export function toggleSamplerManualPriority(state = false, presetNametcApiType = '') { |
| 577 | 420 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return; |
| 578 | 421 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 579 | 422 | if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {}; |
| 580 | 423 | |
| 581 | 424 | const presetSamplers = selectedSamplers[presetNametcApiType]; |
| 582 | 425 | presetSamplers.st_manual_priority = String(state) === 'true'; |
| 583 | 426 | } |
| 584 | 427 | |
| 585 | 428 | /** |
| 586 | 429 | * @param {string?} presetNametcApiType Name of the target presetAPI Type - It picks the currentcurrently active TC presetAPI type name by default |
| 587 | 430 | * @returns {boolean} |
| 588 | 431 | */ |
| 589 | 432 | export function isSamplerManualPriorityEnabled(presetNametcApiType = '') { |
| 590 | 433 | if (!textgenerationwebui_settings?.presettype && !presetNametcApiType) return false; |
| 591 | 434 | if (!presetNametcApiType) presetNametcApiType = textgenerationwebui_settings.presettype; |
| 592 | 435 | if (!selectedSamplers[presetNametcApiType]) selectedSamplers[presetNametcApiType] = {}; |
| 593 | 436 | |
| 594 | 437 | return selectedSamplers[presetNametcApiType]?.st_manual_priority ?? false; |
| 595 | 438 | } |
| 596 | 439 | |
| 597 | 440 | export 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; | |
| 603 | 441 | await saveSettingsDebounced(); |
| 604 | 442 | $('#samplerSelectButton').off('click').on('click', showSamplerSelectPopup); |
| 605 | 443 | } |
| @@ -10,7 +10,7 @@ | ||
| 10 | 10 | <i class="fa-solid fa-lock"></i> |
| 11 | 11 | <span data-i18n="Prioritize">Prioritize</span> |
| 12 | 12 | </div> |
| 13 | 13 | <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> |
| 14 | 14 | </div> |
| 15 | 15 | <!--<div class="flex-container alignItemsBaseline"> |
| 16 | 16 | <div class="menu_button menu_button_icon" title="Create a new sampler"> |
| @@ -20,7 +20,7 @@ import { autoSelectInstructPreset, selectContextPreset, selectInstructPreset } f | ||
| 20 | 20 | import { BIAS_CACHE, createNewLogitBiasEntry, displayLogitBias, getLogitBiasListResult } from './logit-bias.js'; |
| 21 | 21 | |
| 22 | 22 | import { power_user, registerDebugFunction } from './power-user.js'; |
| 23 | 23 | import { getManualActivePresetSamplersgetActiveManualApiSamplers, isSamplerManualPriorityEnabledloadApiSelectedSamplers, loadPresetSelectedSamplersisSamplerManualPriorityEnabled } from './samplerSelect.js'; |
| 24 | 24 | import { SECRET_KEYS, writeSecret } from './secrets.js'; |
| 25 | 25 | import { getEventSourceStream } from './sse-stream.js'; |
| 26 | 26 | import { 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) { | ||
| 372 | 372 | setSettingByName(name, value, true); |
| 373 | 373 | } |
| 374 | 374 | setGenerationParamsFromPreset(preset); |
| 375 | - showSamplerControls(null, true); | |
| 376 | 375 | BIAS_CACHE.delete(BIAS_KEY); |
| 377 | 376 | displayLogitBias(preset.logit_bias, BIAS_KEY); |
| 378 | 377 | saveSettingsDebounced(); |
| @@ -530,7 +529,8 @@ function calculateLogitBias() { | ||
| 530 | 529 | return result; |
| 531 | 530 | } |
| 532 | 531 | |
| 533 | 532 | export async function loadTextGenSettings(data, loadedSettings) { |
| 533 | + await loadApiSelectedSamplers(); | |
| 534 | 534 | textgenerationwebui_presets = convertPresets(data.textgenerationwebui_presets); |
| 535 | 535 | textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? []; |
| 536 | 536 | Object.assign(settings, loadedSettings.textgenerationwebui_settings ?? {}); |
| @@ -572,8 +572,7 @@ export function loadTextGenSettings(data, loadedSettings) { | ||
| 572 | 572 | |
| 573 | 573 | $('#textgen_type').val(settings.type); |
| 574 | 574 | $('#openrouter_providers_text').val(settings.openrouter_providers).trigger('change'); |
| 575 | 575 | loadPresetSelectedSamplersshowSamplerControls(settings.type); |
| 576 | - showSamplerControls(); | |
| 577 | 576 | BIAS_CACHE.delete(BIAS_KEY); |
| 578 | 577 | displayLogitBias(settings.logit_bias, BIAS_KEY); |
| 579 | 578 | |
| @@ -779,8 +778,6 @@ async function getStatusTextgen() { | ||
| 779 | 778 | } |
| 780 | 779 | |
| 781 | 780 | export function initTextGenSettings() { |
| 782 | - loadPresetSelectedSamplers(); | |
| 783 | - | |
| 784 | 781 | $('#send_banned_tokens_textgenerationwebui').on('change', function () { |
| 785 | 782 | const checked = !!$(this).prop('checked'); |
| 786 | 783 | toggleBannedStringsKillSwitch(checked, |
| @@ -1078,21 +1075,19 @@ export function initTextGenSettings() { | ||
| 1078 | 1075 | /** |
| 1079 | 1076 | * Hides and shows preset samplers from the left panel. |
| 1080 | 1077 | * @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 | |
| 1082 | 1078 | * @returns void |
| 1083 | 1079 | */ |
| 1084 | 1080 | function 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; | |
| 1088 | 1083 | |
| 1089 | - $('#textgenerationwebui_api-settings [data-tg-samplers]:not([data-tg-type])').each(function() { | |
| 1084 | + if (!typeSpecificControlled) $(this).show(); | |
| 1090 | - $(this).show(); | |
| 1091 | 1085 | }); |
| 1092 | 1086 | |
| 1093 | 1087 | showTypeSpecificControls(apiType ?? settings.type); |
| 1094 | 1088 | |
| 1095 | 1089 | const samplersActivatedManuallyprioritizeManualSamplerSelect = getManualActivePresetSamplersisSamplerManualPriorityEnabled(apiType ?? settings.type); |
| 1090 | + const samplersActivatedManually = getActiveManualApiSamplers(apiType ?? settings.type); | |
| 1096 | 1091 | |
| 1097 | 1092 | if (!samplersActivatedManually?.length || !prioritizeManualSamplerSelect) return; |
| 1098 | 1093 | |
| @@ -1110,18 +1105,18 @@ function showSamplerControls(apiType = null, isPresetSwitch = false) { | ||
| 1110 | 1105 | }); |
| 1111 | 1106 | } |
| 1112 | 1107 | |
| 1113 | 1108 | function showTypeSpecificControls(typeapiType) { |
| 1114 | 1109 | $('[data-tg-type]').each(function () { |
| 1115 | 1110 | const mode = String($(this).attr('data-tg-type-mode') ?? '').toLowerCase().trim(); |
| 1116 | 1111 | const tgTypes = $(this).attr('data-tg-type').split(',').map(x => x.trim()); |
| 1117 | 1112 | |
| 1118 | 1113 | if (mode === 'except') { |
| 1119 | 1114 | $(this)[tgTypes.includes(typeapiType) ? 'hide' : 'show'](); |
| 1120 | 1115 | return; |
| 1121 | 1116 | } |
| 1122 | 1117 | |
| 1123 | 1118 | for (const tgType of tgTypes) { |
| 1124 | 1119 | if (tgType === typeapiType || tgType == 'all') { |
| 1125 | 1120 | $(this).show(); |
| 1126 | 1121 | return; |
| 1127 | 1122 | } else { |