CFG: Add positive prompt support and fixes

Positive prompts are the opposite of negative prompts. This helps
make the mixing process more accurate by keeping the negative differences
as close as possible to the positive ones by including this prompt.

In addition, fix prompt insertion order at a depth of 0 by hijacking
the same function used for Author's Note as a zero depth anchor.

Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
kingbri 2023-08-20 02:19:25 -04:00
parent 92e6c6a998
commit ac319dbd30
4 changed files with 180 additions and 87 deletions

View File

@ -2720,6 +2720,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
is_send_press = true; is_send_press = true;
} }
console.log(cycleGenerationPromt)
generatedPromtCache += cycleGenerationPromt; generatedPromtCache += cycleGenerationPromt;
if (generatedPromtCache.length == 0 || type === 'continue') { if (generatedPromtCache.length == 0 || type === 'continue') {
if (main_api === 'openai') { if (main_api === 'openai') {
@ -2871,17 +2872,28 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
setPromtString(); setPromtString();
} }
// Fetches the combined prompt for both negative and positive prompts
const cfgGuidanceScale = getGuidanceScale(); const cfgGuidanceScale = getGuidanceScale();
function getCombinedPrompt(isNegative) { function getCombinedPrompt(isNegative) {
if (isNegative && cfgGuidanceScale !== 1) { // Use a negative mesSend if present
const negativePrompt = getCfgPrompt(cfgGuidanceScale); let negativeMesSend = [];
if (negativePrompt && negativePrompt?.value) { let cfgPrompt = {};
// TODO: kingbri: use the insertion depth method instead of splicing if (cfgGuidanceScale && cfgGuidanceScale?.value !== 1) {
mesSend.splice(mesSend.length - negativePrompt.depth, 0, `${negativePrompt.value}\n`); cfgPrompt = getCfgPrompt(cfgGuidanceScale, isNegative);
}
if (cfgPrompt && cfgPrompt?.value && cfgPrompt?.depth !== 0) {
const cfgPromptValue = `${cfgPrompt.value}\n`
// TODO: kingbri: use the insertion depth method instead of splicing
if (isNegative) {
negativeMesSend = [...mesSend];
negativeMesSend.splice(mesSend.length - cfgPrompt.depth, 0, cfgPromptValue);
} else {
mesSend.splice(mesSend.length - cfgPrompt.depth, 0, cfgPromptValue);
} }
} }
let mesSendString = mesSend.join(''); let mesSendString = isNegative ? negativeMesSend.join('') : mesSend.join('');
// add chat preamble // add chat preamble
mesSendString = addChatsPreamble(mesSendString); mesSendString = addChatsPreamble(mesSendString);
@ -2889,12 +2901,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
// add a custom dingus (if defined) // add a custom dingus (if defined)
mesSendString = addChatsSeparator(mesSendString); mesSendString = addChatsSeparator(mesSendString);
if (zeroDepthAnchor && zeroDepthAnchor.length) {
if (!isMultigenEnabled() || tokens_already_generated == 0) {
combinedPrompt = appendZeroDepthAnchor(force_name2, zeroDepthAnchor, combinedPrompt);
}
}
let combinedPrompt = let combinedPrompt =
storyString + storyString +
afterScenarioAnchor + afterScenarioAnchor +
@ -2902,6 +2908,19 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
mesSendString + mesSendString +
generatedPromtCache; generatedPromtCache;
if (zeroDepthAnchor && zeroDepthAnchor.length) {
if (!isMultigenEnabled() || tokens_already_generated == 0) {
combinedPrompt = appendZeroDepthAnchor(force_name2, zeroDepthAnchor, combinedPrompt);
}
}
// Append zero-depth anchor for CFG
if (cfgPrompt && cfgPrompt?.value && cfgPrompt?.depth === 0) {
if (!isMultigenEnabled() || tokens_already_generated == 0) {
combinedPrompt = appendZeroDepthAnchor(force_name2, cfgPrompt.value, combinedPrompt);
}
}
combinedPrompt = combinedPrompt.replace(/\r/gm, ''); combinedPrompt = combinedPrompt.replace(/\r/gm, '');
if (power_user.collapse_newlines) { if (power_user.collapse_newlines) {
@ -2911,15 +2930,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
return combinedPrompt; return combinedPrompt;
} }
let mesSendString = mesSend.join(''); // Get the negative prompt first since it has the unmodified mesSend array
// add chat preamble
mesSendString = addChatsPreamble(mesSendString);
// add a custom dingus (if defined)
mesSendString = addChatsSeparator(mesSendString);
let finalPromt = getCombinedPrompt(false);
let negativePrompt = getCombinedPrompt(true); let negativePrompt = getCombinedPrompt(true);
let finalPromt = getCombinedPrompt(false);
const cfgValues = { const cfgValues = {
guidanceScale: cfgGuidanceScale?.value, guidanceScale: cfgGuidanceScale?.value,
negativePrompt: negativePrompt negativePrompt: negativePrompt
@ -3018,7 +3031,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
storyString: storyString, storyString: storyString,
afterScenarioAnchor: afterScenarioAnchor, afterScenarioAnchor: afterScenarioAnchor,
examplesString: examplesString, examplesString: examplesString,
mesSendString: mesSendString, mesSendString: mesSend.join(''),
generatedPromtCache: generatedPromtCache, generatedPromtCache: generatedPromtCache,
promptBias: promptBias, promptBias: promptBias,
finalPromt: finalPromt, finalPromt: finalPromt,

View File

@ -23,7 +23,8 @@ const defaultSettings = {
}; };
const settingType = { const settingType = {
guidance_scale: 0, guidance_scale: 0,
negative_prompt: 1 negative_prompt: 1,
positive_prompt: 2
} }
// Used for character and chat CFG values // Used for character and chat CFG values
@ -36,19 +37,19 @@ function setCharCfg(tempValue, setting) {
const avatarName = getCharaFilename(); const avatarName = getCharaFilename();
// Assign temp object // Assign temp object
let tempCharaCfg; let tempCharaCfg = {
name: avatarName
};
switch(setting) { switch(setting) {
case settingType.guidance_scale: case settingType.guidance_scale:
tempCharaCfg = { tempCharaCfg["guidance_scale"] = Number(tempValue);
"name": avatarName,
"guidance_scale": Number(tempValue)
}
break; break;
case settingType.negative_prompt: case settingType.negative_prompt:
tempCharaCfg = { tempCharaCfg["negative_prompt"] = tempValue;
"name": avatarName, break;
"negative_prompt": tempValue case settingType.positive_prompt:
} tempCharaCfg["positive_prompt"] = tempValue;
break; break;
default: default:
return false; return false;
@ -66,7 +67,11 @@ function setCharCfg(tempValue, setting) {
const tempAssign = Object.assign(existingCharaCfg, tempCharaCfg); const tempAssign = Object.assign(existingCharaCfg, tempCharaCfg);
// If both values are default, remove the entry // If both values are default, remove the entry
if (!existingCharaCfg.useChara && (tempAssign.guidance_scale ?? 1.00) === 1.00 && (tempAssign.negative_prompt?.length ?? 0) === 0) { if (!existingCharaCfg.useChara &&
(tempAssign.guidance_scale ?? 1.00) === 1.00 &&
(tempAssign.negative_prompt?.length ?? 0) === 0 &&
(tempAssign.positive_prompt?.length ?? 0) === 0)
{
extension_settings.cfg.chara.splice(existingCharaCfgIndex, 1); extension_settings.cfg.chara.splice(existingCharaCfgIndex, 1);
} }
} else if (avatarName && tempValue.length > 0) { } else if (avatarName && tempValue.length > 0) {
@ -95,6 +100,9 @@ function setChatCfg(tempValue, setting) {
case settingType.negative_prompt: case settingType.negative_prompt:
chat_metadata[metadataKeys.negative_prompt] = tempValue; chat_metadata[metadataKeys.negative_prompt] = tempValue;
break; break;
case settingType.positive_prompt:
chat_metadata[metadataKeys.positive_prompt] = tempValue;
break;
default: default:
return false; return false;
} }
@ -174,31 +182,32 @@ function loadSettings() {
$('#chat_cfg_guidance_scale').val(chat_metadata[metadataKeys.guidance_scale] ?? 1.0.toFixed(2)); $('#chat_cfg_guidance_scale').val(chat_metadata[metadataKeys.guidance_scale] ?? 1.0.toFixed(2));
$('#chat_cfg_guidance_scale_counter').text(chat_metadata[metadataKeys.guidance_scale]?.toFixed(2) ?? 1.0.toFixed(2)); $('#chat_cfg_guidance_scale_counter').text(chat_metadata[metadataKeys.guidance_scale]?.toFixed(2) ?? 1.0.toFixed(2));
$('#chat_cfg_negative_prompt').val(chat_metadata[metadataKeys.negative_prompt] ?? ''); $('#chat_cfg_negative_prompt').val(chat_metadata[metadataKeys.negative_prompt] ?? '');
$('#chat_cfg_positive_prompt').val(chat_metadata[metadataKeys.positive_prompt] ?? '');
$('#groupchat_cfg_use_chara').prop('checked', chat_metadata[metadataKeys.groupchat_individual_chars] ?? false); $('#groupchat_cfg_use_chara').prop('checked', chat_metadata[metadataKeys.groupchat_individual_chars] ?? false);
if (chat_metadata[metadataKeys.negative_combine]?.length > 0) { if (chat_metadata[metadataKeys.prompt_combine]?.length > 0) {
chat_metadata[metadataKeys.negative_combine].forEach((element) => { chat_metadata[metadataKeys.prompt_combine].forEach((element) => {
$(`input[name="cfg_negative_combine"][value="${element}"]`) $(`input[name="cfg_prompt_combine"][value="${element}"]`)
.prop("checked", true); .prop("checked", true);
}); });
} }
// Display the negative separator in quotes if not quoted already // Display the negative separator in quotes if not quoted already
let negativeSeparatorDisplay = []; let promptSeparatorDisplay = [];
const negativeSeparator = chat_metadata[metadataKeys.negative_separator]; const promptSeparator = chat_metadata[metadataKeys.prompt_separator];
if (negativeSeparator) { if (promptSeparator) {
negativeSeparatorDisplay.push(negativeSeparator); promptSeparatorDisplay.push(promptSeparator);
if (!negativeSeparator.startsWith(`"`)) { if (!promptSeparator.startsWith(`"`)) {
negativeSeparatorDisplay.unshift(`"`); promptSeparatorDisplay.unshift(`"`);
} }
if (!negativeSeparator.endsWith(`"`)) { if (!promptSeparator.endsWith(`"`)) {
negativeSeparatorDisplay.push(`"`); promptSeparatorDisplay.push(`"`);
} }
} }
$('#cfg_negative_separator').val(negativeSeparatorDisplay.length === 0 ? '' : negativeSeparatorDisplay.join('')); $('#cfg_prompt_separator').val(promptSeparatorDisplay.length === 0 ? '' : promptSeparatorDisplay.join(''));
$('#cfg_negative_insertion_depth').val(chat_metadata[metadataKeys.negative_insertion_depth] ?? 1); $('#cfg_prompt_insertion_depth').val(chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1);
// Set character CFG if it exists // Set character CFG if it exists
if (!selected_group) { if (!selected_group) {
@ -206,6 +215,7 @@ function loadSettings() {
$('#chara_cfg_guidance_scale').val(charaCfg?.guidance_scale ?? 1.00); $('#chara_cfg_guidance_scale').val(charaCfg?.guidance_scale ?? 1.00);
$('#chara_cfg_guidance_scale_counter').text(charaCfg?.guidance_scale?.toFixed(2) ?? 1.0.toFixed(2)); $('#chara_cfg_guidance_scale_counter').text(charaCfg?.guidance_scale?.toFixed(2) ?? 1.0.toFixed(2));
$('#chara_cfg_negative_prompt').val(charaCfg?.negative_prompt ?? ''); $('#chara_cfg_negative_prompt').val(charaCfg?.negative_prompt ?? '');
$('#chara_cfg_positive_prompt').val(charaCfg?.positive_prompt ?? '');
} }
} }
@ -222,26 +232,50 @@ async function initialLoadSettings() {
$('#global_cfg_guidance_scale').val(extension_settings.cfg.global.guidance_scale); $('#global_cfg_guidance_scale').val(extension_settings.cfg.global.guidance_scale);
$('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2)); $('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2));
$('#global_cfg_negative_prompt').val(extension_settings.cfg.global.negative_prompt); $('#global_cfg_negative_prompt').val(extension_settings.cfg.global.negative_prompt);
$('#global_cfg_positive_prompt').val(extension_settings.cfg.global.positive_prompt);
} }
function migrateSettings() { function migrateSettings() {
let performSave = false; let performSettingsSave = false;
let performMetaSave = false;
if (power_user.guidance_scale) { if (power_user.guidance_scale) {
extension_settings.cfg.global.guidance_scale = power_user.guidance_scale; extension_settings.cfg.global.guidance_scale = power_user.guidance_scale;
delete power_user['guidance_scale']; delete power_user['guidance_scale'];
performSave = true; performSettingsSave = true;
} }
if (power_user.negative_prompt) { if (power_user.negative_prompt) {
extension_settings.cfg.global.negative_prompt = power_user.negative_prompt; extension_settings.cfg.global.negative_prompt = power_user.negative_prompt;
delete power_user['negative_prompt']; delete power_user['negative_prompt'];
performSave = true; performSettingsSave = true;
} }
if (performSave) { if (chat_metadata["cfg_negative_combine"]) {
chat_metadata[metadataKeys.prompt_combine] = chat_metadata["cfg_negative_combine"];
chat_metadata["cfg_negative_combine"] = undefined;
performMetaSave = true;
}
if (chat_metadata["cfg_negative_insertion_depth"]) {
chat_metadata[metadataKeys.prompt_insertion_depth] = chat_metadata["cfg_negative_insertion_depth"];
chat_metadata["cfg_negative_insertion_depth"] = undefined;
performMetaSave = true;
}
if (chat_metadata["cfg_negative_separator"]) {
chat_metadata[metadataKeys.prompt_separator] = chat_metadata["cfg_negative_separator"];
chat_metadata["cfg_negative_separator"] = undefined;
performMetaSave = true;
}
if (performSettingsSave) {
saveSettingsDebounced(); saveSettingsDebounced();
} }
if (performMetaSave) {
saveMetadataDebounced();
}
} }
// This function is called when the extension is loaded // This function is called when the extension is loaded
@ -273,6 +307,10 @@ jQuery(async () => {
setChatCfg($(this).val(), settingType.negative_prompt); setChatCfg($(this).val(), settingType.negative_prompt);
}); });
windowHtml.find('#chat_cfg_positive_prompt').on('input', function() {
setChatCfg($(this).val(), settingType.positive_prompt);
});
windowHtml.find('#chara_cfg_guidance_scale').on('input', function() { windowHtml.find('#chara_cfg_guidance_scale').on('input', function() {
const value = $(this).val(); const value = $(this).val();
const success = setCharCfg(value, settingType.guidance_scale); const success = setCharCfg(value, settingType.guidance_scale);
@ -285,6 +323,10 @@ jQuery(async () => {
setCharCfg($(this).val(), settingType.negative_prompt); setCharCfg($(this).val(), settingType.negative_prompt);
}); });
windowHtml.find('#chara_cfg_positive_prompt').on('input', function() {
setCharCfg($(this).val(), settingType.positive_prompt);
});
windowHtml.find('#global_cfg_guidance_scale').on('input', function() { windowHtml.find('#global_cfg_guidance_scale').on('input', function() {
extension_settings.cfg.global.guidance_scale = Number($(this).val()); extension_settings.cfg.global.guidance_scale = Number($(this).val());
$('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2)); $('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2));
@ -296,24 +338,29 @@ jQuery(async () => {
saveSettingsDebounced(); saveSettingsDebounced();
}); });
windowHtml.find(`input[name="cfg_negative_combine"]`).on('input', function() { windowHtml.find('#global_cfg_positive_prompt').on('input', function() {
const values = windowHtml.find(`input[name="cfg_negative_combine"]`) 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"]`)
.filter(":checked") .filter(":checked")
.map(function() { return parseInt($(this).val()) }) .map(function() { return parseInt($(this).val()) })
.get() .get()
.filter((e) => e !== NaN) || []; .filter((e) => e !== NaN) || [];
chat_metadata[metadataKeys.negative_combine] = values; chat_metadata[metadataKeys.prompt_combine] = values;
saveMetadataDebounced(); saveMetadataDebounced();
}); });
windowHtml.find(`#cfg_negative_insertion_depth`).on('input', function() { windowHtml.find(`#cfg_prompt_insertion_depth`).on('input', function() {
chat_metadata[metadataKeys.negative_insertion_depth] = Number($(this).val()); chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());
saveMetadataDebounced(); saveMetadataDebounced();
}); });
windowHtml.find(`#cfg_negative_separator`).on('input', function() { windowHtml.find(`#cfg_prompt_separator`).on('input', function() {
chat_metadata[metadataKeys.negative_separator] = $(this).val(); chat_metadata[metadataKeys.prompt_separator] = $(this).val();
saveMetadataDebounced(); saveMetadataDebounced();
}); });

View File

@ -11,14 +11,15 @@ export const cfgType = {
export const metadataKeys = { export const metadataKeys = {
guidance_scale: "cfg_guidance_scale", guidance_scale: "cfg_guidance_scale",
negative_prompt: "cfg_negative_prompt", negative_prompt: "cfg_negative_prompt",
negative_combine: "cfg_negative_combine", positive_prompt: "cfg_positive_prompt",
prompt_combine: "cfg_prompt_combine",
groupchat_individual_chars: "cfg_groupchat_individual_chars", groupchat_individual_chars: "cfg_groupchat_individual_chars",
negative_insertion_depth: "cfg_negative_insertion_depth", prompt_insertion_depth: "cfg_prompt_insertion_depth",
negative_separator: "cfg_negative_separator" prompt_separator: "cfg_prompt_separator"
} }
// Gets the CFG guidance scale // Gets the CFG guidance scale
// If the guidance scale is 1, ignore the CFG negative prompt since it won't be used anyways // If the guidance scale is 1, ignore the CFG prompt(s) since it won't be used anyways
export function getGuidanceScale() { export function getGuidanceScale() {
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid)); const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale]; const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
@ -44,32 +45,49 @@ export function getGuidanceScale() {
}; };
} }
// Gets the CFG prompt. Currently only gets the negative prompt // Gets the CFG prompt
export function getCfgPrompt(guidanceScale) { export function getCfgPrompt(guidanceScale, isNegative) {
let splitNegativePrompt = []; let splitCfgPrompt = [];
const chatNegativeCombine = chat_metadata[metadataKeys.negative_combine] ?? []; const cfgPromptCombine = chat_metadata[metadataKeys.prompt_combine] ?? [];
if (guidanceScale.type === cfgType.chat || chatNegativeCombine.includes(cfgType.chat)) { if (guidanceScale.type === cfgType.chat || cfgPromptCombine.includes(cfgType.chat)) {
splitNegativePrompt.unshift(substituteParams(chat_metadata[metadataKeys.negative_prompt])?.trim()); splitCfgPrompt.unshift(
substituteParams(
chat_metadata[isNegative ? metadataKeys.negative_prompt : metadataKeys.positive_prompt]
)
?.trim()
);
} }
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid)); const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
if (guidanceScale.type === cfgType.chara || chatNegativeCombine.includes(cfgType.chara)) { if (guidanceScale.type === cfgType.chara || cfgPromptCombine.includes(cfgType.chara)) {
splitNegativePrompt.unshift(substituteParams(charaCfg.negative_prompt)?.trim()) splitCfgPrompt.unshift(
substituteParams(
isNegative ? charaCfg.negative_prompt : charaCfg.positive_prompt
)
?.trim()
);
} }
if (guidanceScale.type === cfgType.global || chatNegativeCombine.includes(cfgType.global)) { console.log(guidanceScale.type);
splitNegativePrompt.unshift(substituteParams(extension_settings.cfg.global.negative_prompt)?.trim()); console.log(cfgPromptCombine);
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
)
?.trim()
);
} }
// This line is a bit hacky with a JSON.stringify and JSON.parse. Fix this if possible. // This line is a bit hacky with a JSON.stringify and JSON.parse. Fix this if possible.
const negativeSeparator = JSON.parse(chat_metadata[metadataKeys.negative_separator] || JSON.stringify("\n")) ?? "\n"; const customSeparator = JSON.parse(chat_metadata[metadataKeys.prompt_separator] || JSON.stringify("\n")) ?? "\n";
const combinedNegatives = splitNegativePrompt.filter((e) => e.length > 0).join(negativeSeparator); const combinedCfgPrompt = splitCfgPrompt.filter((e) => e.length > 0).join(customSeparator);
const insertionDepth = chat_metadata[metadataKeys.negative_insertion_depth] ?? 1; const insertionDepth = chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1;
console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedNegatives}`); console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedCfgPrompt}`);
return { return {
value: combinedNegatives, value: combinedCfgPrompt,
depth: insertionDepth depth: insertionDepth
}; };
} }

View File

@ -14,7 +14,7 @@
<small> <small>
<b>Unique to this chat.</b><br> <b>Unique to this chat.</b><br>
</small> </small>
<label for="chat_cfg_negative_prompt"> <label for="chat_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span> <span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small> <small data-i18n="1 = disabled">1 = disabled</small>
</label> </label>
@ -33,6 +33,11 @@
<span data-i18n="Negative Prompt">Negative Prompt</span> <span data-i18n="Negative Prompt">Negative Prompt</span>
</label> </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> <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>
<div id="groupchat_cfg_use_chara_container"> <div id="groupchat_cfg_use_chara_container">
<label class="checkbox_label" for="groupchat_cfg_use_chara"> <label class="checkbox_label" for="groupchat_cfg_use_chara">
@ -53,7 +58,7 @@
<div class="inline-drawer-content"> <div class="inline-drawer-content">
<small><b>Will be automatically added as the CFG for this character.</b></small> <small><b>Will be automatically added as the CFG for this character.</b></small>
<br /> <br />
<label for="chara_cfg_negative_prompt"> <label for="chara_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span> <span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small> <small data-i18n="1 = disabled">1 = disabled</small>
</label> </label>
@ -72,6 +77,11 @@
<span data-i18n="Negative Prompt">Negative Prompt</span> <span data-i18n="Negative Prompt">Negative Prompt</span>
</label> </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> <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> </div>
@ -86,7 +96,7 @@
<div class="inline-drawer-content"> <div class="inline-drawer-content">
<small><b>Will be used as the default CFG options for every chat unless overridden.</b></small> <small><b>Will be used as the default CFG options for every chat unless overridden.</b></small>
<br /> <br />
<label for="global_cfg_negative_prompt"> <label for="global_cfg_guidance_scale">
<span data-i18n="Scale">Scale</span> <span data-i18n="Scale">Scale</span>
<small data-i18n="1 = disabled">1 = disabled</small> <small data-i18n="1 = disabled">1 = disabled</small>
</label> </label>
@ -105,49 +115,54 @@
<span data-i18n="Negative Prompt">Negative Prompt</span> <span data-i18n="Negative Prompt">Negative Prompt</span>
</label> </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> <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">Negative 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> </div>
</div> </div>
<div id="cfg_negative_combine_container"> <div id="cfg_prompt_combine_container">
<hr class="sysHR"> <hr class="sysHR">
<div class="inline-drawer"> <div class="inline-drawer">
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header"> <div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
<b>Negative Cascading</b> <b>CFG Prompt Cascading</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div> <div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div> </div>
<div class="inline-drawer-content"> <div class="inline-drawer-content">
<div class="flex-container flexFlowColumn"> <div class="flex-container flexFlowColumn">
<small> <small>
<b>Combine negative prompts from other boxes.</b> <b>Combine positive/negative prompts from other boxes.</b>
<br /> <br />
For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string. For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.
</small> </small>
</div> </div>
<br /> <br />
<div class="flex-container flexFlowColumn"> <div class="flex-container flexFlowColumn">
<label for="cfg_negative_combine"> <label for="cfg_prompt_combine">
<span data-i18n="Scale">Always Include</span> <span data-i18n="Scale">Always Include</span>
</label> </label>
<label class="checkbox_label"> <label class="checkbox_label">
<input type="checkbox" name="cfg_negative_combine" value="0" /> <input type="checkbox" name="cfg_prompt_combine" value="0" />
<span data-i18n="Chat Negatives">Chat Negatives</span> <span data-i18n="Chat Negatives">Chat Negatives</span>
</label> </label>
<label class="checkbox_label"> <label class="checkbox_label">
<input type="checkbox" name="cfg_negative_combine" value="1" /> <input type="checkbox" name="cfg_prompt_combine" value="1" />
<span data-i18n="Character Negatives">Character Negatives</span> <span data-i18n="Character Negatives">Character Negatives</span>
</label> </label>
<label class="checkbox_label"> <label class="checkbox_label">
<input type="checkbox" name="cfg_negative_combine" value="2" /> <input type="checkbox" name="cfg_prompt_combine" value="2" />
<span data-i18n="Global Negatives">Global Negatives</span> <span data-i18n="Global Negatives">Global Negatives</span>
</label> </label>
</div> </div>
<div class="flex-container flexFlowColumn"> <div class="flex-container flexFlowColumn">
<label> <label>
Custom Separator: <input id="cfg_negative_separator" class="text_pole textarea_compact widthUnset" placeholder="&quot;\n&quot;" type="text" /> Custom Separator: <input id="cfg_prompt_separator" class="text_pole textarea_compact widthUnset" placeholder="&quot;\n&quot;" type="text" />
</label> </label>
<label> <label>
Insertion Depth: <input id="cfg_negative_insertion_depth" class="text_pole widthUnset" type="number" min="0" max="99" /> Insertion Depth: <input id="cfg_prompt_insertion_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
</label> </label>
</div> </div>
</div> </div>