AND/NOT logic for selective WI

This commit is contained in:
RossAscends
2023-07-06 01:30:37 +09:00
parent df6b87fa23
commit cb741fd954
3 changed files with 87 additions and 26 deletions

View File

@@ -3089,7 +3089,8 @@
<div class="inline-drawer-toggle inline-drawer-header gap5px">
<span class="drag-handle">&#9776;</span>
<div class="gap5px world_entry_thin_controls wide100p">
<div class="world_entry_form_control">
<div class="world_entry_form_control flex1">
<label for="key">
<small>
<span data-i18n="Keywords">
@@ -3108,11 +3109,18 @@
</label>
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="Comma separated (required)" maxlength="1000"></textarea>
</div>
<div class="world_entry_form_control keysecondary">
<div class="flex-container widthFitContent alignItemsFlexEnd">
<select name="entryLogicType" class="height32px widthFitContent margin0">
<option value="0">AND</option>
<option value="1">NOT</option>
</select>
</div>
<div class="world_entry_form_control keysecondary flex1">
<label for="keysecondary">
<small>
<span data-i18n="Secondary Required Keywords">
Secondary Required Keywords
Optional Filter
</span>
</small>
<small class="displayNone">
@@ -3129,7 +3137,7 @@
<div class="inline-drawer-content flex-container">
<div class="WIEntryContentAndMemo flex-container">
<div class="world_entry_thin_controls flex2">
<div class="world_entry_form_control">
<div class="world_entry_form_control flex1">
<label for="content ">
<small>
<span data-i18n="Content">
@@ -3150,7 +3158,7 @@
</div>
</div>
<div class="world_entry_thin_controls commentContainer">
<div class="world_entry_form_control">
<div class="world_entry_form_control flex1">
<label for="comment">
<small>
<span data-i18n="Memo/Note">
@@ -3189,18 +3197,16 @@
<input type="checkbox" name="addMemo">
<span data-i18n="Add Memo">Add Memo</span>
</label>
<label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="exclude_recursion" />
<span data-i18n="Exclude from recursion">
Non-recursable
</span>
</label>
</div>
<!-- <div name="injectioStratBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<!--
<div name="injectioStratBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<label for="injectionStrat">Injection:</label>
<small>
<select name="injectionStrat">
@@ -3209,7 +3215,8 @@
<option value="2">Disabled</option>
</select>
</small>
</div> -->
</div>
-->
<div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<label for="position">Position:</label>

View File

@@ -363,6 +363,24 @@ function appendWorldEntry(name, data, entry) {
keyInput.val(entry.key.join(",")).trigger("input");
initScrollHeight(keyInput);
// logic AND/NOT
const selectiveLogicDropdown = template.find('select[name="entryLogicType"]');
selectiveLogicDropdown.data("uid", entry.uid);
selectiveLogicDropdown.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
console.debug(`logic for ${entry.uid} set to ${value}`)
data.entries[uid].selectiveLogic = !isNaN(value) ? value : 0;
setOriginalDataValue(data, uid, "selectiveLogic", data.entries[uid].selectiveLogic);
saveWorldInfo(name, data);
});
template
.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`)
.prop("selected", true)
.trigger("input");
// keysecondary
const keySecondaryInput = template.find('textarea[name="keysecondary"]');
keySecondaryInput.data("uid", entry.uid);
@@ -465,6 +483,7 @@ function appendWorldEntry(name, data, entry) {
value ? keysecondary.show() : keysecondary.hide();
});
//forced on, ignored if empty
selectiveInput.prop("checked", true /* entry.selective */).trigger("input");
selectiveInput.parent().hide();
@@ -548,6 +567,7 @@ function appendWorldEntry(name, data, entry) {
probabilityInput.val(data.entries[uid].probability).trigger("input");
});
//forced on, 100% by default
probabilityToggle.prop("checked", true /* entry.useProbability */).trigger("input");
probabilityToggle.parent().hide();
@@ -632,14 +652,15 @@ function createWorldInfoEntry(name, data) {
comment: "",
content: "",
constant: false,
selective: false,
selective: true,
selectiveLogic: 0,
addMemo: false,
order: 100,
position: 0,
disable: false,
excludeRecursion: false,
probability: null,
useProbability: false,
probability: 100,
useProbability: true,
};
const newUid = getFreeWorldEntryUid(data);
@@ -923,27 +944,51 @@ async function checkWorldInfo(chat, maxContext) {
continue;
}
if (Array.isArray(entry.key) && entry.key.length) {
if (Array.isArray(entry.key) && entry.key.length) { //check for keywords existing
primary: for (let key of entry.key) {
const substituted = substituteParams(key);
console.debug(`${entry.uid}: ${substituted}`)
if (substituted && matchKeys(textToScan, substituted.trim())) {
console.debug(`${entry.uid}: got primary match`)
//selective logic begins
if (
entry.selective &&
Array.isArray(entry.keysecondary) &&
entry.keysecondary.length
entry.selective && //all entries are selective now
Array.isArray(entry.keysecondary) && //always true
entry.keysecondary.length //ignore empties
) {
console.debug(`uid:${entry.uid}: checking logic: ${entry.selectiveLogic}`)
secondary: for (let keysecondary of entry.keysecondary) {
const secondarySubstituted = substituteParams(keysecondary);
if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) {
activatedNow.add(entry);
break secondary;
console.debug(`uid:${entry.uid}: filtering ${secondarySubstituted}`)
//AND operator
if (entry.selectiveLogic === 0) {
console.debug('saw AND logic, checking..')
if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) {
console.log(`activating entry ${entry.uid} with AND found`)
activatedNow.add(entry);
break secondary;
}
}
//NOT operator
if (entry.selectiveLogic === 1) {
console.debug(`uid ${entry.uid}: checking NOT logic for ${secondarySubstituted}`)
if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) {
console.debug(`uid ${entry.uid}: canceled; filtered out by ${secondarySubstituted}`)
break primary;
} else {
console.debug(`${entry.uid}: activated; passed NOT filter`)
activatedNow.add(entry);
break secondary;
}
}
}
//handle cases where secondary is empty
} else {
console.debug(`uid ${entry.uid}: activated without filter logic`)
activatedNow.add(entry);
break primary;
}
}
} else { console.debug('no active entries for logic checks yet') }
}
}
}
@@ -954,15 +999,16 @@ async function checkWorldInfo(chat, maxContext) {
let newContent = "";
const textToScanTokens = getTokenCount(allActivatedText);
const probabilityChecksBefore = failedProbabilityChecks.size;
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.key} failed probability check, skipping`);
console.debug(`WI entry ${entry.uid} ${entry.key} failed probability check, skipping`);
failedProbabilityChecks.add(entry);
continue;
}
} else { console.debug(`uid:${entry.uid} passed probability check, inserting to prompt`) }
newContent += `${substituteParams(entry.content)}\n`;

View File

@@ -1408,6 +1408,10 @@ body.big-avatars .ch_description {
align-items: flex-start !important;
}
.alignItemsFlexEnd {
align-items: flex-end !important;
}
.alignSelfStart {
align-self: start;
}
@@ -1885,6 +1889,10 @@ grammarly-extension {
background-color: var(--white30a);
}
.height32px {
height: 32px;
}
@@ -2127,9 +2135,9 @@ grammarly-extension {
flex-direction: row;
}
.world_entry_thin_controls>div {
/* .world_entry_thin_controls>div {
flex: 1;
}
} */
.world_entry_form_control label h4 {
margin-bottom: 0;