Merge branch 'staging' into backgrounds-endpoint

This commit is contained in:
Cohee 2023-12-07 23:16:33 +02:00
commit 7f7ad6f523
6 changed files with 133 additions and 26 deletions

View File

@ -4122,7 +4122,8 @@
<div class="world_entry_thin_controls commentContainer">
</div>
</div>
<div class="flex-container flexFlowColumn flexNoGap wide100p">
<div class="flex-container wide100p flexGap10">
<div class="flex1 flex-container flexFlowColumn flexNoGap">
<div class="flex-container justifySpaceBetween">
<label for="characterFilter" class="">
<small data-i18n="Filter to Character(s)">Filter to Character(s)</small>
@ -4142,6 +4143,13 @@
</select>
</div>
</div>
<div class="flex1 flex-container flexFlowColumn flexNoGap">
<label for="group">
<small data-i18n="">Inclusion Group</small>
</label>
<input type="text" class="text_pole" name="group" rows="1" data-i18n="[placeholder]Only one entry with the same label will be activated" placeholder="Only one entry with the same label will be activated">
</div>
</div>
<div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
<label class="checkbox flex-container">

View File

@ -1291,7 +1291,7 @@ async function replaceCurrentChat() {
// start new chat
else {
characters[this_chid].chat = name2 + ' - ' + humanizedDateTime();
characters[this_chid].chat = `${name2} - ${humanizedDateTime()}`;
$('#selected_chat_pole').val(characters[this_chid].chat);
saveCharacterDebounced();
await getChat();
@ -8026,7 +8026,7 @@ jQuery(async function () {
else {
//RossAscends: added character name to new chat filenames and replaced Date.now() with humanizedDateTime;
chat_metadata = {};
characters[this_chid].chat = name2 + '-' + humanizedDateTime();
characters[this_chid].chat = `${name2} - ${humanizedDateTime()}`;
$('#selected_chat_pole').val(characters[this_chid].chat);
await getChat();
await createOrEditCharacter();
@ -8427,6 +8427,7 @@ jQuery(async function () {
select_rm_characters();
sendSystemMessage(system_message_types.WELCOME);
eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
await getClientVersion();
} else {
toastr.info('Please stop the message generation first.');
}

View File

@ -1176,7 +1176,7 @@ async function sendWindowAIRequest(messages, signal, stream) {
await delay(1);
if (lastContent !== content) {
yield content;
yield { text: content, swipes: [] };
}
lastContent = content;

View File

@ -597,7 +597,7 @@ async function generateCallback(args, value) {
}
async function echoCallback(args, value) {
const safeValue = DOMPurify.sanitize(value || '');
const safeValue = DOMPurify.sanitize(String(value) || '');
if (safeValue === '') {
console.warn('WARN: No argument provided for /echo command');
return;
@ -619,6 +619,7 @@ async function echoCallback(args, value) {
toastr.info(safeValue, title);
break;
}
return value;
}
async function addSwipeCallback(_, arg) {

View File

@ -11,7 +11,15 @@ function getLocalVariable(name, args = {}) {
if (args.index !== undefined) {
try {
localVariable = JSON.parse(localVariable);
const numIndex = Number(args.index);
if (Number.isNaN(numIndex)) {
localVariable = localVariable[args.index];
} else {
localVariable = localVariable[Number(args.index)];
}
if (typeof localVariable == 'object') {
localVariable = JSON.stringify(localVariable);
}
} catch {
// that didn't work
}
@ -35,7 +43,15 @@ function getGlobalVariable(name, args = {}) {
if (args.index !== undefined) {
try {
globalVariable = JSON.parse(globalVariable);
const numIndex = Number(args.index);
if (Number.isNaN(numIndex)) {
globalVariable = globalVariable[args.index];
} else {
globalVariable = globalVariable[Number(args.index)];
}
if (typeof globalVariable == 'object') {
globalVariable = JSON.stringify(globalVariable);
}
} catch {
// that didn't work
}

View File

@ -295,7 +295,7 @@ function registerWorldInfoSlashCommands() {
return '';
}
const entry = entries.find(x => x.uid === uid);
const entry = entries.find(x => String(x.uid) === String(uid));
if (!entry) {
toastr.warning('Valid UID is required');
@ -1102,6 +1102,19 @@ function getWorldEntry(name, data, entry) {
orderInput.val(entry.order).trigger('input');
orderInput.css('width', 'calc(3em + 15px)');
// group
const groupInput = template.find('input[name="group"]');
groupInput.data('uid', entry.uid);
groupInput.on('input', function () {
const uid = $(this).data('uid');
const value = String($(this).val()).trim();
data.entries[uid].group = value;
setOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group);
saveWorldInfo(name, data);
});
groupInput.val(entry.group ?? '').trigger('input');
// probability
if (entry.probability === undefined) {
entry.probability = null;
@ -1810,8 +1823,8 @@ async function checkWorldInfo(chat, maxContext) {
console.debug(`(NOT ANY Check) Activating WI Entry ${entry.uid}, no secondary keywords found.`);
activatedNow.add(entry);
}
// Handle cases where secondary is empty
} else {
// Handle cases where secondary is empty
console.debug(`WI UID ${entry.uid}: Activated without filter logic.`);
activatedNow.add(entry);
break primary;
@ -1827,11 +1840,13 @@ async function checkWorldInfo(chat, maxContext) {
let newContent = '';
const textToScanTokens = getTokenCount(allActivatedText);
const probabilityChecksBefore = failedProbabilityChecks.size;
filterByInclusionGroups(newEntries, allActivatedEntries);
console.debug('-- PROBABILITY CHECKS BEGIN --');
for (const entry of newEntries) {
const rollValue = Math.random() * 100;
if (entry.useProbability && rollValue > entry.probability) {
console.debug(`WI entry ${entry.uid} ${entry.key} failed probability check, skipping`);
failedProbabilityChecks.add(entry);
@ -1939,6 +1954,72 @@ async function checkWorldInfo(chat, maxContext) {
return { worldInfoBefore, worldInfoAfter, WIDepthEntries };
}
/**
* Filters entries by inclusion groups.
* @param {object[]} newEntries Entries activated on current recursion level
* @param {Set<object>} allActivatedEntries Set of all activated entries
*/
function filterByInclusionGroups(newEntries, allActivatedEntries) {
console.debug('-- INCLUSION GROUP CHECKS BEGIN --');
const grouped = newEntries.filter(x => x.group).reduce((acc, item) => {
if (!acc[item.group]) {
acc[item.group] = [];
}
acc[item.group].push(item);
return acc;
}, {});
if (Object.keys(grouped).length === 0) {
console.debug('No inclusion groups found');
return;
}
for (const [key, group] of Object.entries(grouped)) {
console.debug(`Checking inclusion group '${key}' with ${group.length} entries`, group);
if (!Array.isArray(group) || group.length <= 1) {
console.debug('Skipping inclusion group check, only one entry');
continue;
}
if (Array.from(allActivatedEntries).some(x => x.group === key)) {
console.debug(`Skipping inclusion group check, group already activated '${key}'`);
continue;
}
// Do weighted random using probability of entry as weight
const totalWeight = group.reduce((acc, item) => acc + item.probability, 0);
const rollValue = Math.random() * totalWeight;
let currentWeight = 0;
let winner = null;
for (const entry of group) {
currentWeight += entry.probability;
if (rollValue <= currentWeight) {
console.debug(`Activated inclusion group '${key}' with entry '${entry.uid}'`, entry);
winner = entry;
break;
}
}
if (!winner) {
console.debug(`Failed to activate inclusion group '${key}', no winner found`);
continue;
}
// Remove every group item from newEntries but the winner
for (const entry of group) {
if (entry === winner) {
continue;
}
console.debug(`Removing loser from inclusion group '${key}' entry '${entry.uid}'`, entry);
newEntries.splice(newEntries.indexOf(entry), 1);
}
}
}
function matchKeys(haystack, needle) {
const transformedString = transformString(needle);