mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-03-03 03:17:54 +01:00
CFG: Add groupchat support
Groupchats have their CFG defined a little differently. Chat and global CFGs are publicly accessible within the window. As a compromise, individual character CFGs can be injected as part of each character's prompt. However, these CFG settings need to be adjusted in the character's individual chats which will carry over to the group. In addition, make this character logic gated under a checkbox to always prefer chat unless explicitly specified. Negative cascading is still open, so individual character negatives can be included at any time. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
4a21ee0337
commit
43e91b150a
@ -7,7 +7,7 @@ import {
|
||||
} from "../../../script.js";
|
||||
import { selected_group } from "../../group-chats.js";
|
||||
import { extension_settings, saveMetadataDebounced } from "../../extensions.js";
|
||||
import { getCharaFilename, delay, debounce } from "../../utils.js";
|
||||
import { getCharaFilename, delay } from "../../utils.js";
|
||||
import { power_user } from "../../power-user.js";
|
||||
import { metadataKeys } from "./util.js";
|
||||
|
||||
@ -76,7 +76,7 @@ function setCharCfg(tempValue, setting) {
|
||||
|
||||
extension_settings.cfg.chara.push(tempCharaCfg);
|
||||
} else {
|
||||
console.log("Character CFG error: No avatar name key could be found.");
|
||||
console.debug("Character CFG error: No avatar name key could be found.");
|
||||
|
||||
// Don't save settings if something went wrong
|
||||
return false;
|
||||
@ -151,18 +151,30 @@ function onCfgMenuItemClick() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Load character-specific settings here and set the relevant HTML
|
||||
function onChatChanged() {
|
||||
async function onChatChanged() {
|
||||
loadSettings();
|
||||
await modifyCharaHtml();
|
||||
}
|
||||
|
||||
// Rearrange the panel if a group chat is present
|
||||
async function modifyCharaHtml() {
|
||||
if (selected_group) {
|
||||
$("#chara_cfg_container").hide();
|
||||
$("#groupchat_cfg_use_chara_container").show();
|
||||
} else {
|
||||
$("#chara_cfg_container").show();
|
||||
$("#groupchat_cfg_use_chara_container").hide();
|
||||
// TODO: Remove chat checkbox here
|
||||
}
|
||||
}
|
||||
|
||||
// Reloads chat-specific settings
|
||||
// TODO: Fix race condition bug where deleted chara CFG still loads previous prompts
|
||||
function loadSettings() {
|
||||
// Set chat CFG if it exists
|
||||
$('#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_negative_prompt').val(chat_metadata[metadataKeys.negative_prompt] ?? '');
|
||||
$('#groupchat_cfg_use_chara').prop('checked', chat_metadata[metadataKeys.groupchat_individual_chars] ?? false);
|
||||
if (chat_metadata[metadataKeys.negative_combine]?.length > 0) {
|
||||
chat_metadata[metadataKeys.negative_combine].forEach((element) => {
|
||||
$(`input[name="cfg_negative_combine"][value="${element}"]`)
|
||||
@ -171,11 +183,13 @@ function loadSettings() {
|
||||
}
|
||||
|
||||
// Set character CFG if it exists
|
||||
if (!selected_group) {
|
||||
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.0.toFixed(2));
|
||||
$('#chara_cfg_negative_prompt').val(charaCfg?.negative_prompt ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
// Load initial extension settings
|
||||
async function initialLoadSettings() {
|
||||
@ -227,7 +241,7 @@ jQuery(async () => {
|
||||
easing: 'ease-in-out',
|
||||
});
|
||||
setTimeout(function () { $('#cfgConfig').hide() }, 200);
|
||||
})
|
||||
});
|
||||
|
||||
windowHtml.find('#chat_cfg_guidance_scale').on('input', function() {
|
||||
const numberValue = Number($(this).val());
|
||||
@ -241,17 +255,6 @@ jQuery(async () => {
|
||||
setChatCfg($(this).val(), settingType.negative_prompt);
|
||||
});
|
||||
|
||||
windowHtml.find(`input[name="cfg_negative_combine"]`).on('input', function() {
|
||||
const values = windowHtml.find(`input[name="cfg_negative_combine"]`)
|
||||
.filter(":checked")
|
||||
.map(function() { return parseInt($(this).val()) })
|
||||
.get()
|
||||
.filter((e) => e !== NaN) || [];
|
||||
|
||||
chat_metadata[metadataKeys.negative_combine] = values;
|
||||
saveMetadataDebounced();
|
||||
});
|
||||
|
||||
windowHtml.find('#chara_cfg_guidance_scale').on('input', function() {
|
||||
const value = $(this).val();
|
||||
const success = setCharCfg(value, settingType.guidance_scale);
|
||||
@ -275,6 +278,28 @@ jQuery(async () => {
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
windowHtml.find(`input[name="cfg_negative_combine"]`).on('input', function() {
|
||||
const values = windowHtml.find(`input[name="cfg_negative_combine"]`)
|
||||
.filter(":checked")
|
||||
.map(function() { return parseInt($(this).val()) })
|
||||
.get()
|
||||
.filter((e) => e !== NaN) || [];
|
||||
|
||||
chat_metadata[metadataKeys.negative_combine] = values;
|
||||
saveMetadataDebounced();
|
||||
});
|
||||
|
||||
windowHtml.find('#groupchat_cfg_use_chara').on('input', function() {
|
||||
const checked = !!$(this).prop('checked');
|
||||
chat_metadata[metadataKeys.groupchat_individual_chars] = checked
|
||||
|
||||
if (checked) {
|
||||
toastr.info("You can edit character CFG values in their respective character chats.");
|
||||
}
|
||||
|
||||
saveMetadataDebounced();
|
||||
});
|
||||
|
||||
$("#movingDivs").append(windowHtml);
|
||||
|
||||
initialLoadSettings();
|
||||
@ -288,5 +313,7 @@ jQuery(async () => {
|
||||
buttonHtml.insertAfter("#option_toggle_AN");
|
||||
|
||||
// Hook events
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||
eventSource.on(event_types.CHAT_CHANGED, async () => {
|
||||
await onChatChanged();
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { chat_metadata } from "../../../script.js";
|
||||
import { extension_settings } from "../../extensions.js"
|
||||
import { chat_metadata, 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 = {
|
||||
@ -10,18 +11,17 @@ export const cfgType = {
|
||||
export const metadataKeys = {
|
||||
guidance_scale: "cfg_guidance_scale",
|
||||
negative_prompt: "cfg_negative_prompt",
|
||||
negative_combine: "cfg_negative_combine"
|
||||
negative_combine: "cfg_negative_combine",
|
||||
groupchat_individual_chars: "cfg_groupchat_individual_chars"
|
||||
}
|
||||
|
||||
// TODO: Add groupchat support and fetch the CFG values for the current character
|
||||
|
||||
// Gets the CFG value from hierarchy of chat -> character -> global
|
||||
// Returns undefined values which should be handled in the respective backend APIs
|
||||
export function getCfg() {
|
||||
let splitNegativePrompt = [];
|
||||
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename());
|
||||
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
|
||||
const guidanceScale = getGuidanceScale(charaCfg);
|
||||
const chatNegativeCombine = chat_metadata[metadataKeys.negative_combine];
|
||||
const chatNegativeCombine = chat_metadata[metadataKeys.negative_combine] ?? [];
|
||||
|
||||
// If there's a guidance scale, continue. Otherwise assume undefined
|
||||
if (guidanceScale?.value && guidanceScale?.value !== 1) {
|
||||
@ -37,9 +37,12 @@ export function getCfg() {
|
||||
splitNegativePrompt.push(extension_settings.cfg.global.negative_prompt?.trim());
|
||||
}
|
||||
|
||||
const combinedNegatives = splitNegativePrompt.filter((e) => e.length > 0).join(", ");
|
||||
console.debug(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedNegatives}`)
|
||||
|
||||
return {
|
||||
guidanceScale: guidanceScale.value,
|
||||
negativePrompt: splitNegativePrompt.filter((e) => e.length > 0).join(", ")
|
||||
negativePrompt: combinedNegatives
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,14 +50,15 @@ export function getCfg() {
|
||||
// If the guidance scale is 1, ignore the CFG negative prompt since it won't be used anyways
|
||||
function getGuidanceScale(charaCfg) {
|
||||
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
|
||||
if (chatGuidanceScale && chatGuidanceScale !== 1) {
|
||||
const groupchatCharOverride = chat_metadata[metadataKeys.groupchat_individual_chars] ?? false;
|
||||
if (chatGuidanceScale && chatGuidanceScale !== 1 && !groupchatCharOverride) {
|
||||
return {
|
||||
type: cfgType.chat,
|
||||
value: chatGuidanceScale
|
||||
};
|
||||
}
|
||||
|
||||
if (charaCfg && charaCfg.guidance_scale !== 1) {
|
||||
if ((!selected_group && charaCfg || groupchatCharOverride) && charaCfg?.guidance_scale !== 1) {
|
||||
return {
|
||||
type: cfgType.chara,
|
||||
value: charaCfg.guidance_scale
|
||||
|
@ -4,6 +4,7 @@
|
||||
<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>
|
||||
@ -11,7 +12,7 @@
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>
|
||||
<b>Unique to this chat</b>.<br>
|
||||
<b>Unique to this chat.</b><br>
|
||||
</small>
|
||||
<label for="chat_cfg_negative_prompt">
|
||||
<span data-i18n="Scale">Scale</span>
|
||||
@ -32,8 +33,16 @@
|
||||
</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>
|
||||
</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">
|
||||
@ -41,8 +50,7 @@
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be automatically added as the CFG for this character. Will be used in groups, but
|
||||
can't be modified when a group chat is open.</small>
|
||||
<small><b>Will be automatically added as the CFG for this character.</b></small>
|
||||
<br />
|
||||
<label for="chara_cfg_negative_prompt">
|
||||
<span data-i18n="Scale">Scale</span>
|
||||
@ -65,6 +73,8 @@
|
||||
</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">
|
||||
@ -72,7 +82,7 @@
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be used as the default CFG options for every chat unless overridden.</small>
|
||||
<small><b>Will be used as the default CFG options for every chat unless overridden.</b></small>
|
||||
<br />
|
||||
<label for="global_cfg_negative_prompt">
|
||||
<span data-i18n="Scale">Scale</span>
|
||||
@ -95,6 +105,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cfg_negative_combine_container">
|
||||
<hr class="sysHR">
|
||||
<div class="inline-drawer">
|
||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
@ -103,7 +115,9 @@
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>
|
||||
Combine negative prompts from other boxes. For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.
|
||||
<b>Combine 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>
|
||||
<br />
|
||||
<label for="cfg_negative_combine">
|
||||
@ -111,17 +125,18 @@
|
||||
</label>
|
||||
<label class="checkbox_label">
|
||||
<input type="checkbox" name="cfg_negative_combine" value="0" />
|
||||
<span data-i18n="Only Format Display">Chat Negatives</span>
|
||||
<span data-i18n="Chat Negatives">Chat Negatives</span>
|
||||
</label>
|
||||
<label class="checkbox_label">
|
||||
<input type="checkbox" name="cfg_negative_combine" value="1" />
|
||||
<span data-i18n="Only Format Display">Character Negatives</span>
|
||||
<span data-i18n="Character Negatives">Character Negatives</span>
|
||||
</label>
|
||||
<label class="checkbox_label">
|
||||
<input type="checkbox" name="cfg_negative_combine" value="2" />
|
||||
<span data-i18n="Use character CFG">Global Negatives</span>
|
||||
<span data-i18n="Global Negatives">Global Negatives</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user