2023-08-09 05:22:25 +02:00
|
|
|
import {
|
|
|
|
chat_metadata,
|
|
|
|
eventSource,
|
|
|
|
event_types,
|
|
|
|
saveSettingsDebounced,
|
|
|
|
this_chid,
|
|
|
|
} from "../../../script.js";
|
|
|
|
import { selected_group } from "../../group-chats.js";
|
2023-08-11 07:35:22 +02:00
|
|
|
import { extension_settings, saveMetadataDebounced } from "../../extensions.js";
|
|
|
|
import { getCharaFilename, delay } from "../../utils.js";
|
2023-08-09 05:22:25 +02:00
|
|
|
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 defaultSettings = {
|
|
|
|
"global": {
|
|
|
|
"guidance_scale": 1,
|
|
|
|
"negative_prompt": ''
|
|
|
|
},
|
|
|
|
"chara": []
|
|
|
|
};
|
2023-08-10 05:42:04 +02:00
|
|
|
const settingType = {
|
|
|
|
"guidance_scale": 0,
|
|
|
|
"negative_prompt": 1
|
|
|
|
}
|
2023-08-09 05:22:25 +02:00
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
// Used for character and chat CFG values
|
2023-08-09 05:22:25 +02:00
|
|
|
function updateSettings() {
|
|
|
|
saveSettingsDebounced();
|
|
|
|
loadSettings();
|
|
|
|
}
|
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
function setCharCfg(tempValue, setting) {
|
|
|
|
const avatarName = getCharaFilename();
|
|
|
|
|
|
|
|
// Assign temp object
|
|
|
|
let tempCharaCfg;
|
|
|
|
switch(setting) {
|
|
|
|
case settingType.guidance_scale:
|
|
|
|
tempCharaCfg = {
|
|
|
|
"name": avatarName,
|
|
|
|
"guidance_scale": Number(tempValue)
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case settingType.negative_prompt:
|
|
|
|
tempCharaCfg = {
|
|
|
|
"name": avatarName,
|
|
|
|
"negative_prompt": tempValue
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2023-08-11 07:35:22 +02:00
|
|
|
return false;
|
2023-08-10 05:42:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
let existingCharaCfgIndex;
|
|
|
|
let existingCharaCfg;
|
|
|
|
|
|
|
|
if (extension_settings.cfg.chara) {
|
|
|
|
existingCharaCfgIndex = extension_settings.cfg.chara.findIndex((e) => e.name === avatarName);
|
|
|
|
existingCharaCfg = extension_settings.cfg.chara[existingCharaCfgIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (extension_settings.cfg.chara && existingCharaCfg) {
|
|
|
|
const tempAssign = Object.assign(existingCharaCfg, tempCharaCfg);
|
|
|
|
|
|
|
|
// if both values are default, remove the entry
|
2023-08-11 07:35:22 +02:00
|
|
|
if (!existingCharaCfg.useChara && (tempAssign.guidance_scale ?? 1.00) === 1.00 && (tempAssign.negative_prompt?.length ?? 0) === 0) {
|
2023-08-10 05:42:04 +02:00
|
|
|
extension_settings.cfg.chara.splice(existingCharaCfgIndex, 1);
|
|
|
|
}
|
|
|
|
} else if (avatarName && tempValue.length > 0) {
|
|
|
|
if (!extension_settings.cfg.chara) {
|
|
|
|
extension_settings.cfg.chara = []
|
|
|
|
}
|
|
|
|
|
|
|
|
Object.assign(tempCharaCfg, { useChara: false })
|
|
|
|
|
|
|
|
extension_settings.cfg.chara.push(tempCharaCfg);
|
|
|
|
} else {
|
|
|
|
console.log("Character CFG error: No avatar name key could be found.");
|
|
|
|
|
|
|
|
// Don't save settings if something went wrong
|
2023-08-11 07:35:22 +02:00
|
|
|
return false;
|
2023-08-10 05:42:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
updateSettings();
|
2023-08-11 07:35:22 +02:00
|
|
|
|
|
|
|
return true;
|
2023-08-09 05:22:25 +02:00
|
|
|
}
|
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
function setCharCfgCheckbox() {
|
|
|
|
const value = !!$(this).prop('checked');
|
2023-08-11 07:35:22 +02:00
|
|
|
const charaCfgIndex = extension_settings.cfg.chara.findIndex((e) => e.name === getCharaFilename());
|
|
|
|
const charaCfg = extension_settings.cfg.chara[charaCfgIndex];
|
2023-08-10 05:42:04 +02:00
|
|
|
if (charaCfg) {
|
2023-08-11 07:35:22 +02:00
|
|
|
if (!value && (charaCfg.guidance_scale ?? 1.00) === 1.00 && (charaCfg.negative_prompt?.length ?? 0) === 0) {
|
|
|
|
extension_settings.cfg.chara.splice(charaCfgIndex, 1);
|
|
|
|
} else {
|
|
|
|
charaCfg.useChara = value;
|
|
|
|
}
|
2023-08-09 05:22:25 +02:00
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
updateSettings();
|
|
|
|
}
|
2023-08-09 05:22:25 +02:00
|
|
|
}
|
|
|
|
|
2023-08-11 07:35:22 +02:00
|
|
|
function setChatCfg(tempValue, setting) {
|
|
|
|
switch(setting) {
|
|
|
|
case settingType.guidance_scale:
|
|
|
|
chat_metadata['guidance_scale'] = tempValue;
|
|
|
|
break;
|
|
|
|
case settingType.negative_prompt:
|
|
|
|
chat_metadata['negative_prompt'] = tempValue;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2023-08-09 05:22:25 +02:00
|
|
|
|
2023-08-11 07:35:22 +02:00
|
|
|
saveMetadataDebounced();
|
2023-08-09 05:22:25 +02:00
|
|
|
|
2023-08-11 07:35:22 +02:00
|
|
|
return true;
|
2023-08-09 05:22:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Only change CFG when character is selected
|
|
|
|
function onCfgMenuItemClick() {
|
2023-08-10 05:42:04 +02:00
|
|
|
if (selected_group || this_chid) {
|
2023-08-09 05:22:25 +02:00
|
|
|
//show CFG config if it's hidden
|
|
|
|
if ($("#cfgConfig").css("display") !== 'flex') {
|
|
|
|
$("#cfgConfig").addClass('resizing')
|
|
|
|
$("#cfgConfig").css("display", "flex");
|
|
|
|
$("#cfgConfig").css("opacity", 0.0);
|
|
|
|
$("#cfgConfig").transition({
|
|
|
|
opacity: 1.0,
|
|
|
|
duration: 250,
|
|
|
|
}, async function () {
|
|
|
|
await delay(50);
|
|
|
|
$("#cfgConfig").removeClass('resizing')
|
|
|
|
});
|
|
|
|
|
|
|
|
//auto-open the main AN inline drawer
|
|
|
|
if ($("#CFGBlockToggle")
|
|
|
|
.siblings('.inline-drawer-content')
|
|
|
|
.css('display') !== 'block') {
|
|
|
|
$("#floatingPrompt").addClass('resizing')
|
|
|
|
$("#CFGBlockToggle").click();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//hide AN if it's already displayed
|
|
|
|
$("#cfgConfig").addClass('resizing')
|
|
|
|
$("#cfgConfig").transition({
|
|
|
|
opacity: 0.0,
|
|
|
|
duration: 250,
|
|
|
|
},
|
|
|
|
async function () {
|
|
|
|
await delay(50);
|
|
|
|
$("#cfgConfig").removeClass('resizing')
|
|
|
|
});
|
|
|
|
setTimeout(function () {
|
|
|
|
$("#cfgConfig").hide();
|
|
|
|
}, 250);
|
|
|
|
|
|
|
|
}
|
|
|
|
//duplicate options menu close handler from script.js
|
|
|
|
//because this listener takes priority
|
|
|
|
$("#options").stop().fadeOut(250);
|
|
|
|
} else {
|
|
|
|
toastr.warning(`Select a character before trying to configure CFG`, '', { timeOut: 2000 });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Load character-specific settings here and set the relevant HTML
|
|
|
|
function onChatChanged() {
|
2023-08-10 05:42:04 +02:00
|
|
|
loadSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reloads chat-specific settings
|
|
|
|
function loadSettings() {
|
2023-08-11 07:35:22 +02:00
|
|
|
// Set chat CFG if it exists
|
|
|
|
$('#chat_cfg_guidance_scale').val(chat_metadata['guidance_scale'] ?? 1.00);
|
|
|
|
$('#chat_cfg_guidance_scale_counter').text(chat_metadata['guidance_scale']?.toFixed(2) ?? 1.00);
|
|
|
|
$('#chat_cfg_negative_prompt').val(chat_metadata['negative_prompt'] ?? '');
|
2023-08-10 05:42:04 +02:00
|
|
|
|
|
|
|
// Set character CFG if it exists
|
|
|
|
const charaCfg = extension_settings.cfg.chara.find((e) => e.name === getCharaFilename());
|
|
|
|
$('#chara_cfg_guidance_scale').val(charaCfg?.guidance_scale ?? 1.00);
|
|
|
|
$('#chara_cfg_guidance_scale_counter').text(charaCfg?.guidance_scale?.toFixed(2) ?? 1.00);
|
|
|
|
$('#chara_cfg_negative_prompt').val(charaCfg?.negative_prompt ?? '');
|
|
|
|
$('#use_chara_cfg').prop('checked', charaCfg?.useChara ?? false);
|
2023-08-09 05:22:25 +02:00
|
|
|
}
|
2023-08-10 05:42:04 +02:00
|
|
|
|
|
|
|
// Load initial extension settings
|
|
|
|
async function initialLoadSettings() {
|
2023-08-09 05:22:25 +02:00
|
|
|
// Create the settings if they don't exist
|
|
|
|
extension_settings[extensionName] = extension_settings[extensionName] || {};
|
|
|
|
if (Object.keys(extension_settings[extensionName]).length === 0) {
|
|
|
|
Object.assign(extension_settings[extensionName], defaultSettings);
|
|
|
|
saveSettingsDebounced();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set global CFG values on load
|
|
|
|
$('#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_negative_prompt').val(extension_settings.cfg.global.negative_prompt);
|
|
|
|
}
|
|
|
|
|
|
|
|
function migrateSettings() {
|
|
|
|
let performSave = false;
|
|
|
|
|
|
|
|
if (power_user.guidance_scale) {
|
|
|
|
extension_settings.cfg.global.guidance_scale = power_user.guidance_scale;
|
|
|
|
delete power_user['guidance_scale'];
|
|
|
|
performSave = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (power_user.negative_prompt) {
|
|
|
|
extension_settings.cfg.global.negative_prompt = power_user.negative_prompt;
|
|
|
|
delete power_user['negative_prompt'];
|
|
|
|
performSave = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (performSave) {
|
|
|
|
saveSettingsDebounced();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 () {
|
|
|
|
$("#cfgConfig").transition({
|
|
|
|
opacity: 0,
|
|
|
|
duration: 200,
|
|
|
|
easing: 'ease-in-out',
|
|
|
|
});
|
|
|
|
setTimeout(function () { $('#cfgConfig').hide() }, 200);
|
|
|
|
})
|
|
|
|
|
2023-08-11 07:35:22 +02:00
|
|
|
windowHtml.find('#chat_cfg_guidance_scale').on('input', function() {
|
|
|
|
const numberValue = Number($(this).val());
|
|
|
|
const success = setChatCfg(numberValue, settingType.guidance_scale);
|
|
|
|
if (success) {
|
|
|
|
$('#chat_cfg_guidance_scale_counter').text(numberValue.toFixed(2));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
windowHtml.find('#chat_cfg_negative_prompt').on('input', function() {
|
|
|
|
setChatCfg($(this).val(), settingType.negative_prompt);
|
|
|
|
});
|
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
windowHtml.find('#chara_cfg_guidance_scale').on('input', function() {
|
2023-08-11 07:35:22 +02:00
|
|
|
const value = $(this).val();
|
|
|
|
const success = setCharCfg(value, settingType.guidance_scale);
|
|
|
|
if (success) {
|
|
|
|
$('#chara_cfg_guidance_scale_counter').text(Number(value).toFixed(2));
|
|
|
|
}
|
2023-08-10 05:42:04 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
windowHtml.find('#chara_cfg_negative_prompt').on('input', function() {
|
|
|
|
setCharCfg($(this).val(), settingType.negative_prompt);
|
|
|
|
});
|
|
|
|
|
|
|
|
windowHtml.find('#use_chara_cfg').on('input', setCharCfgCheckbox);
|
|
|
|
|
2023-08-09 05:22:25 +02:00
|
|
|
windowHtml.find('#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));
|
|
|
|
console.log(extension_settings.cfg.global.guidance_scale)
|
|
|
|
saveSettingsDebounced();
|
|
|
|
});
|
|
|
|
|
|
|
|
windowHtml.find('#global_cfg_negative_prompt').on('input', function() {
|
|
|
|
extension_settings.cfg.global.negative_prompt = $(this).val();
|
|
|
|
saveSettingsDebounced();
|
|
|
|
});
|
|
|
|
|
|
|
|
$("#movingDivs").append(windowHtml);
|
|
|
|
|
2023-08-10 05:42:04 +02:00
|
|
|
initialLoadSettings();
|
2023-08-09 05:22:25 +02:00
|
|
|
|
|
|
|
if (extension_settings.cfg) {
|
|
|
|
migrateSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
const buttonHtml = $(await $.get(`${extensionFolderPath}/menuButton.html`));
|
|
|
|
buttonHtml.on('click', onCfgMenuItemClick)
|
|
|
|
buttonHtml.insertAfter("#option_toggle_AN");
|
|
|
|
|
|
|
|
// Hook events
|
|
|
|
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
|
|
|
});
|