Move CFG scale to built-in functionality

This commit is contained in:
Cohee 2023-10-21 22:19:49 +03:00
parent ed8f5ddc33
commit a4ab898933
9 changed files with 321 additions and 328 deletions

View File

@ -88,6 +88,7 @@
<script type="module" src="scripts/server-history.js"></script>
<script type="module" src="scripts/setting-search.js"></script>
<script type="module" src="scripts/bulk-edit.js"></script>
<script type="module" src="scripts/cfg-scale.js"></script>
<title>SillyTavern</title>
</head>
@ -4751,6 +4752,178 @@
</div>
</div>
</div>
<div id="cfgConfig" class="drawer-content flexGap5">
<div class="panelControlBar flex-container">
<div id="cfgConfigHeader" class="fa-solid fa-grip drag-grabber"></div>
<div id="CFGClose" class="fa-solid fa-circle-xmark"></div>
</div>
<div name="cfgConfigHolder" class="scrollY">
<div id="chat_cfg_container">
<div class="inline-drawer">
<div id="CFGBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Chat CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small>
<b>Unique to this chat.</b><br>
</small>
<label for="chat_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="chat_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="chat_cfg_guidance_scale" id="chat_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="chat_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="chat_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="chat_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="chat_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
<div id="groupchat_cfg_use_chara_container">
<label class="checkbox_label" for="groupchat_cfg_use_chara">
<input type="checkbox" id="groupchat_cfg_use_chara" />
<span data-i18n="Use character CFG scales">Use character CFG scales</span>
</label>
</div>
</div>
</div>
</div>
<div id="chara_cfg_container" style="display: none;">
<hr class="sysHR">
<div class="inline-drawer">
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Character CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small><b>Will be automatically added as the CFG for this character.</b></small>
<br />
<label for="chara_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="chara_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="chara_cfg_guidance_scale" id="chara_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="chara_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="chara_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="chara_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="chara_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
</div>
</div>
</div>
<div id="global_cfg_container">
<hr class="sysHR">
<div class="inline-drawer">
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Global CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small><b>Will be used as the default CFG options for every chat unless overridden.</b></small>
<br />
<label for="global_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="global_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="global_cfg_guidance_scale" id="global_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="global_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="global_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="global_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="global_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
</div>
</div>
</div>
<div id="cfg_prompt_combine_container">
<hr class="sysHR">
<div class="inline-drawer">
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>CFG Prompt Cascading</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div class="flex-container flexFlowColumn">
<small>
<b>Combine positive/negative prompts from other boxes.</b>
<br />
For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.
</small>
</div>
<br />
<div class="flex-container flexFlowColumn">
<label for="cfg_prompt_combine">
<span data-i18n="Scale">Always Include</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="0" />
<span data-i18n="Chat Negatives">Chat Negatives</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="1" />
<span data-i18n="Character Negatives">Character Negatives</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="2" />
<span data-i18n="Global Negatives">Global Negatives</span>
</label>
</div>
<div class="flex-container flexFlowColumn">
<label>
Custom Separator: <input id="cfg_prompt_separator" class="text_pole textarea_compact widthUnset" placeholder="&quot;\n&quot;" type="text" />
</label>
<label>
Insertion Depth: <input id="cfg_prompt_insertion_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="sheld">
<div id="sheldheader" class="fa-solid fa-grip drag-grabber"></div>
@ -4790,9 +4963,10 @@
<i class="fa-lg fa-solid fa-note-sticky"></i>
<span data-i18n="Author's Note">Author's Note</span>
</a>
<div data-newbie-hidden id="options_advanced">
</div>
<a data-newbie-hidden id="option_toggle_CFG">
<i class="fa-lg fa-solid fa-scale-balanced"></i>
<span data-i18n="CFG Scale">CFG Scale</span>
</a>
<a id="option_back_to_main">
<i class="fa-lg fa-solid fa-left-long"></i>
<span data-i18n="Back to parent chat">Back to parent chat</span>

View File

@ -169,7 +169,7 @@ import { getDeviceInfo } from "./scripts/RossAscends-mods.js";
import { registerPromptManagerMigration } from "./scripts/PromptManager.js";
import { getRegexedString, regex_placement } from "./scripts/extensions/regex/engine.js";
import { FILTER_TYPES, FilterHelper } from "./scripts/filters.js";
import { getCfgPrompt, getGuidanceScale } from "./scripts/extensions/cfg/util.js";
import { getCfgPrompt, getGuidanceScale, initCfg } from "./scripts/cfg-scale.js";
import {
force_output_sequence,
formatInstructModeChat,
@ -724,6 +724,7 @@ async function firstLoadInit() {
initPersonas();
initRossMods();
initStats();
initCfg();
}
function checkOnlineStatus() {
@ -3017,7 +3018,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
: ` ${cfgPrompt.value}`;
} else {
// TODO: Make all extension prompts use an array/splice method
finalMesSend[mesSend.length - cfgPrompt.depth].extensionPrompts.push(`${cfgPrompt.value}\n`);
const lengthDiff = mesSend.length - cfgPrompt.depth;
const cfgDepth = lengthDiff >= 0 ? lengthDiff : 0;
finalMesSend[cfgDepth].extensionPrompts.push(`${cfgPrompt.value}\n`);
}
}

View File

@ -1,19 +1,17 @@
import {
chat_metadata,
substituteParams,
this_chid,
eventSource,
event_types,
saveSettingsDebounced,
this_chid,
} from "../../../script.js";
import { selected_group } from "../../group-chats.js";
import { extension_settings, saveMetadataDebounced } from "../../extensions.js";
import { getCharaFilename, delay } from "../../utils.js";
import { power_user } from "../../power-user.js";
import { metadataKeys } from "./util.js";
} from "../script.js";
import { extension_settings, saveMetadataDebounced } from "./extensions.js"
import { selected_group } from "./group-chats.js";
import { getCharaFilename, delay } from "./utils.js";
import { power_user } from "./power-user.js";
// Keep track of where your extension is located, name should match repo name
const extensionName = "cfg";
const extensionFolderPath = `scripts/extensions/${extensionName}`;
const extensionName = 'cfg';
const defaultSettings = {
global: {
"guidance_scale": 1,
@ -199,7 +197,7 @@ function loadSettings() {
if (!promptSeparator.startsWith(`"`)) {
promptSeparatorDisplay.unshift(`"`);
}
if (!promptSeparator.endsWith(`"`)) {
promptSeparatorDisplay.push(`"`);
}
@ -279,14 +277,8 @@ function migrateSettings() {
}
// This function is called when the extension is loaded
jQuery(async () => {
// This is an example of loading HTML from a file
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
// Append settingsHtml to extensions_settings
// extension_settings and extensions_settings2 are the left and right columns of the settings menu
// Left should be extensions that deal with system functions and right should be visual/UI related
windowHtml.find('#CFGClose').on('click', function () {
export function initCfg() {
$('#CFGClose').on('click', function () {
$("#cfgConfig").transition({
opacity: 0,
duration: 200,
@ -295,7 +287,7 @@ jQuery(async () => {
setTimeout(function () { $('#cfgConfig').hide() }, 200);
});
windowHtml.find('#chat_cfg_guidance_scale').on('input', function() {
$('#chat_cfg_guidance_scale').on('input', function() {
const numberValue = Number($(this).val());
const success = setChatCfg(numberValue, settingType.guidance_scale);
if (success) {
@ -303,15 +295,15 @@ jQuery(async () => {
}
});
windowHtml.find('#chat_cfg_negative_prompt').on('input', function() {
$('#chat_cfg_negative_prompt').on('input', function() {
setChatCfg($(this).val(), settingType.negative_prompt);
});
windowHtml.find('#chat_cfg_positive_prompt').on('input', function() {
$('#chat_cfg_positive_prompt').on('input', function() {
setChatCfg($(this).val(), settingType.positive_prompt);
});
windowHtml.find('#chara_cfg_guidance_scale').on('input', function() {
$('#chara_cfg_guidance_scale').on('input', function() {
const value = $(this).val();
const success = setCharCfg(value, settingType.guidance_scale);
if (success) {
@ -319,34 +311,34 @@ jQuery(async () => {
}
});
windowHtml.find('#chara_cfg_negative_prompt').on('input', function() {
$('#chara_cfg_negative_prompt').on('input', function() {
setCharCfg($(this).val(), settingType.negative_prompt);
});
windowHtml.find('#chara_cfg_positive_prompt').on('input', function() {
$('#chara_cfg_positive_prompt').on('input', function() {
setCharCfg($(this).val(), settingType.positive_prompt);
});
windowHtml.find('#global_cfg_guidance_scale').on('input', function() {
$('#global_cfg_guidance_scale').on('input', function() {
extension_settings.cfg.global.guidance_scale = Number($(this).val());
$('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2));
saveSettingsDebounced();
});
windowHtml.find('#global_cfg_negative_prompt').on('input', function() {
$('#global_cfg_negative_prompt').on('input', function() {
extension_settings.cfg.global.negative_prompt = $(this).val();
saveSettingsDebounced();
});
windowHtml.find('#global_cfg_positive_prompt').on('input', function() {
$('#global_cfg_positive_prompt').on('input', function() {
extension_settings.cfg.global.positive_prompt = $(this).val();
saveSettingsDebounced();
});
windowHtml.find(`input[name="cfg_prompt_combine"]`).on('input', function() {
const values = windowHtml.find(`input[name="cfg_prompt_combine"]`)
$(`input[name="cfg_prompt_combine"]`).on('input', function() {
const values = $('#cfgConfig').find(`input[name="cfg_prompt_combine"]`)
.filter(":checked")
.map(function() { return parseInt($(this).val()) })
.map(function() { return Number($(this).val()) })
.get()
.filter((e) => !Number.isNaN(e)) || [];
@ -354,17 +346,17 @@ jQuery(async () => {
saveMetadataDebounced();
});
windowHtml.find(`#cfg_prompt_insertion_depth`).on('input', function() {
$(`#cfg_prompt_insertion_depth`).on('input', function() {
chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());
saveMetadataDebounced();
});
windowHtml.find(`#cfg_prompt_separator`).on('input', function() {
$(`#cfg_prompt_separator`).on('input', function() {
chat_metadata[metadataKeys.prompt_separator] = $(this).val();
saveMetadataDebounced();
});
windowHtml.find('#groupchat_cfg_use_chara').on('input', function() {
$('#groupchat_cfg_use_chara').on('input', function() {
const checked = !!$(this).prop('checked');
chat_metadata[metadataKeys.groupchat_individual_chars] = checked
@ -375,20 +367,126 @@ jQuery(async () => {
saveMetadataDebounced();
});
$("#movingDivs").append(windowHtml);
initialLoadSettings();
if (extension_settings.cfg) {
migrateSettings();
}
const buttonHtml = $(await $.get(`${extensionFolderPath}/menuButton.html`));
buttonHtml.on('click', onCfgMenuItemClick)
buttonHtml.appendTo("#options_advanced");
$('#option_toggle_CFG').on('click', onCfgMenuItemClick);
// Hook events
eventSource.on(event_types.CHAT_CHANGED, async () => {
await onChatChanged();
});
});
}
export const cfgType = {
chat: 0,
chara: 1,
global: 2
}
export const metadataKeys = {
guidance_scale: "cfg_guidance_scale",
negative_prompt: "cfg_negative_prompt",
positive_prompt: "cfg_positive_prompt",
prompt_combine: "cfg_prompt_combine",
groupchat_individual_chars: "cfg_groupchat_individual_chars",
prompt_insertion_depth: "cfg_prompt_insertion_depth",
prompt_separator: "cfg_prompt_separator"
}
// Gets the CFG guidance scale
// If the guidance scale is 1, ignore the CFG prompt(s) since it won't be used anyways
export function getGuidanceScale() {
if (!extension_settings.cfg) {
console.warn("CFG extension is not enabled. Skipping CFG guidance.");
return;
}
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
const groupchatCharOverride = chat_metadata[metadataKeys.groupchat_individual_chars] ?? false;
if (chatGuidanceScale && chatGuidanceScale !== 1 && !groupchatCharOverride) {
return {
type: cfgType.chat,
value: chatGuidanceScale
};
}
if ((!selected_group && charaCfg || groupchatCharOverride) && charaCfg?.guidance_scale !== 1) {
return {
type: cfgType.chara,
value: charaCfg.guidance_scale
};
}
if (extension_settings.cfg.global && extension_settings.cfg.global?.guidance_scale !== 1) {
return {
type: cfgType.global,
value: extension_settings.cfg.global.guidance_scale
};
}
}
/**
* Gets the CFG prompt separator.
* @returns {string} The CFG prompt separator
*/
function getCustomSeparator() {
const defaultSeparator = "\n";
try {
if (chat_metadata[metadataKeys.prompt_separator]) {
return JSON.parse(chat_metadata[metadataKeys.prompt_separator]);
}
return defaultSeparator;
} catch {
console.warn("Invalid JSON detected for prompt separator. Using default separator.");
return defaultSeparator;
}
}
// Gets the CFG prompt
export function getCfgPrompt(guidanceScale, isNegative) {
let splitCfgPrompt = [];
const cfgPromptCombine = chat_metadata[metadataKeys.prompt_combine] ?? [];
if (guidanceScale.type === cfgType.chat || cfgPromptCombine.includes(cfgType.chat)) {
splitCfgPrompt.unshift(
substituteParams(
chat_metadata[isNegative ? metadataKeys.negative_prompt : metadataKeys.positive_prompt]
)
);
}
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
if (guidanceScale.type === cfgType.chara || cfgPromptCombine.includes(cfgType.chara)) {
splitCfgPrompt.unshift(
substituteParams(
isNegative ? charaCfg.negative_prompt : charaCfg.positive_prompt
)
);
}
if (guidanceScale.type === cfgType.global || cfgPromptCombine.includes(cfgType.global)) {
splitCfgPrompt.unshift(
substituteParams(
isNegative ? extension_settings.cfg.global.negative_prompt : extension_settings.cfg.global.positive_prompt
)
);
}
const customSeparator = getCustomSeparator();
const combinedCfgPrompt = splitCfgPrompt.filter((e) => e.length > 0).join(customSeparator);
const insertionDepth = chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1;
console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedCfgPrompt}`);
return {
value: combinedCfgPrompt,
depth: insertionDepth
};
}

View File

@ -1,11 +0,0 @@
{
"display_name": "CFG",
"loading_order": 1,
"requires": [],
"optional": [],
"js": "index.js",
"css": "style.css",
"author": "kingbri",
"version": "1.0.0",
"homePage": "https://github.com/SillyTavern/SillyTavern"
}

View File

@ -1,4 +0,0 @@
<a id="option_toggle_CFG">
<i class="fa-lg fa-solid fa-scale-balanced"></i>
<span data-i18n="CFG Scale">CFG Scale</span>
</a>

View File

@ -1,95 +0,0 @@
import { chat_metadata, substituteParams, this_chid } from "../../../script.js";
import { extension_settings, getContext } from "../../extensions.js"
import { selected_group } from "../../group-chats.js";
import { getCharaFilename } from "../../utils.js";
export const cfgType = {
chat: 0,
chara: 1,
global: 2
}
export const metadataKeys = {
guidance_scale: "cfg_guidance_scale",
negative_prompt: "cfg_negative_prompt",
positive_prompt: "cfg_positive_prompt",
prompt_combine: "cfg_prompt_combine",
groupchat_individual_chars: "cfg_groupchat_individual_chars",
prompt_insertion_depth: "cfg_prompt_insertion_depth",
prompt_separator: "cfg_prompt_separator"
}
// Gets the CFG guidance scale
// If the guidance scale is 1, ignore the CFG prompt(s) since it won't be used anyways
export function getGuidanceScale() {
if (!extension_settings.cfg) {
console.warn("CFG extension is not enabled. Skipping CFG guidance.");
return;
}
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
const groupchatCharOverride = chat_metadata[metadataKeys.groupchat_individual_chars] ?? false;
if (chatGuidanceScale && chatGuidanceScale !== 1 && !groupchatCharOverride) {
return {
type: cfgType.chat,
value: chatGuidanceScale
};
}
if ((!selected_group && charaCfg || groupchatCharOverride) && charaCfg?.guidance_scale !== 1) {
return {
type: cfgType.chara,
value: charaCfg.guidance_scale
};
}
if (extension_settings.cfg.global && extension_settings.cfg.global?.guidance_scale !== 1) {
return {
type: cfgType.global,
value: extension_settings.cfg.global.guidance_scale
};
}
}
// Gets the CFG prompt
export function getCfgPrompt(guidanceScale, isNegative) {
let splitCfgPrompt = [];
const cfgPromptCombine = chat_metadata[metadataKeys.prompt_combine] ?? [];
if (guidanceScale.type === cfgType.chat || cfgPromptCombine.includes(cfgType.chat)) {
splitCfgPrompt.unshift(
substituteParams(
chat_metadata[isNegative ? metadataKeys.negative_prompt : metadataKeys.positive_prompt]
)
);
}
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
if (guidanceScale.type === cfgType.chara || cfgPromptCombine.includes(cfgType.chara)) {
splitCfgPrompt.unshift(
substituteParams(
isNegative ? charaCfg.negative_prompt : charaCfg.positive_prompt
)
);
}
if (guidanceScale.type === cfgType.global || cfgPromptCombine.includes(cfgType.global)) {
splitCfgPrompt.unshift(
substituteParams(
isNegative ? extension_settings.cfg.global.negative_prompt : extension_settings.cfg.global.positive_prompt
)
);
}
// This line is a bit hacky with a JSON.stringify and JSON.parse. Fix this if possible.
const customSeparator = JSON.parse(chat_metadata[metadataKeys.prompt_separator] || JSON.stringify("\n")) ?? "\n";
const combinedCfgPrompt = splitCfgPrompt.filter((e) => e.length > 0).join(customSeparator);
const insertionDepth = chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1;
console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedCfgPrompt}`);
return {
value: combinedCfgPrompt,
depth: insertionDepth
};
}

View File

@ -1,172 +0,0 @@
<div id="cfgConfig" class="drawer-content flexGap5">
<div class="panelControlBar flex-container">
<div id="cfgConfigHeader" class="fa-solid fa-grip drag-grabber"></div>
<div id="CFGClose" class="fa-solid fa-circle-xmark"></div>
</div>
<div name="cfgConfigHolder" class="scrollY">
<div id="chat_cfg_container">
<div class="inline-drawer">
<div id="CFGBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Chat CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small>
<b>Unique to this chat.</b><br>
</small>
<label for="chat_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="chat_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="chat_cfg_guidance_scale" id="chat_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="chat_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="chat_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="chat_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="chat_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
<div id="groupchat_cfg_use_chara_container">
<label class="checkbox_label" for="groupchat_cfg_use_chara">
<input type="checkbox" id="groupchat_cfg_use_chara" />
<span data-i18n="Use character CFG scales">Use character CFG scales</span>
</label>
</div>
</div>
</div>
</div>
<div id="chara_cfg_container" style="display: none;">
<hr class="sysHR">
<div class="inline-drawer">
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Character CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small><b>Will be automatically added as the CFG for this character.</b></small>
<br />
<label for="chara_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="chara_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="chara_cfg_guidance_scale" id="chara_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="chara_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="chara_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="chara_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="chara_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
</div>
</div>
</div>
<div id="global_cfg_container">
<hr class="sysHR">
<div class="inline-drawer">
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Global CFG</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<small><b>Will be used as the default CFG options for every chat unless overridden.</b></small>
<br />
<label for="global_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small>
</label>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="global_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="global_cfg_guidance_scale" id="global_cfg_guidance_scale_counter">
select
</div>
</div>
</div>
<div>
<label for="global_cfg_negative_prompt">
<span data-i18n="Negative Prompt">Negative Prompt</span>
</label>
<textarea id="global_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
<label for="global_cfg_positive_prompt">
<span data-i18n="Positive Prompt">Positive Prompt</span>
</label>
<textarea id="global_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
</div>
</div>
</div>
</div>
<div id="cfg_prompt_combine_container">
<hr class="sysHR">
<div class="inline-drawer">
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>CFG Prompt Cascading</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div class="flex-container flexFlowColumn">
<small>
<b>Combine positive/negative prompts from other boxes.</b>
<br />
For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.
</small>
</div>
<br />
<div class="flex-container flexFlowColumn">
<label for="cfg_prompt_combine">
<span data-i18n="Scale">Always Include</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="0" />
<span data-i18n="Chat Negatives">Chat Negatives</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="1" />
<span data-i18n="Character Negatives">Character Negatives</span>
</label>
<label class="checkbox_label">
<input type="checkbox" name="cfg_prompt_combine" value="2" />
<span data-i18n="Global Negatives">Global Negatives</span>
</label>
</div>
<div class="flex-container flexFlowColumn">
<label>
Custom Separator: <input id="cfg_prompt_separator" class="text_pole textarea_compact widthUnset" placeholder="&quot;\n&quot;" type="text" />
</label>
<label>
Insertion Depth: <input id="cfg_prompt_insertion_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
</label>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -5,7 +5,7 @@ import {
saveSettingsDebounced,
setGenerationParamsFromPreset
} from "../script.js";
import { getCfgPrompt } from "./extensions/cfg/util.js";
import { getCfgPrompt } from "./cfg-scale.js";
import { MAX_CONTEXT_DEFAULT } from "./power-user.js";
import { getTextTokens, tokenizers } from "./tokenizers.js";
import {