mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
AND/NOT logic for selective WI
This commit is contained in:
@@ -3089,7 +3089,8 @@
|
||||
<div class="inline-drawer-toggle inline-drawer-header gap5px">
|
||||
<span class="drag-handle">☰</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>
|
||||
|
@@ -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);
|
||||
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`;
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user