mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Filter inclusion groups by timed effects (#2765)
* Filter inclusion groups by timed effects Closes #2762 * Skip group scoring check if sticky entries are present * Optimize sticky checks
This commit is contained in:
@@ -3953,7 +3953,7 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) {
|
|||||||
let newContent = '';
|
let newContent = '';
|
||||||
const textToScanTokens = await getTokenCountAsync(allActivatedText);
|
const textToScanTokens = await getTokenCountAsync(allActivatedText);
|
||||||
|
|
||||||
filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState);
|
filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState, timedEffects);
|
||||||
|
|
||||||
console.debug('[WI] --- PROBABILITY CHECKS ---');
|
console.debug('[WI] --- PROBABILITY CHECKS ---');
|
||||||
for (const entry of newEntries) {
|
for (const entry of newEntries) {
|
||||||
@@ -4143,8 +4143,9 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) {
|
|||||||
* @param {WorldInfoBuffer} buffer The buffer to use for scoring
|
* @param {WorldInfoBuffer} buffer The buffer to use for scoring
|
||||||
* @param {(entry: WIScanEntry) => void} removeEntry The function to remove an entry
|
* @param {(entry: WIScanEntry) => void} removeEntry The function to remove an entry
|
||||||
* @param {number} scanState The current scan state
|
* @param {number} scanState The current scan state
|
||||||
|
* @param {Map<string, boolean>} hasStickyMap The sticky entries map
|
||||||
*/
|
*/
|
||||||
function filterGroupsByScoring(groups, buffer, removeEntry, scanState) {
|
function filterGroupsByScoring(groups, buffer, removeEntry, scanState, hasStickyMap) {
|
||||||
for (const [key, group] of Object.entries(groups)) {
|
for (const [key, group] of Object.entries(groups)) {
|
||||||
// Group scoring is disabled both globally and for the group entries
|
// Group scoring is disabled both globally and for the group entries
|
||||||
if (!world_info_use_group_scoring && !group.some(x => x.useGroupScoring)) {
|
if (!world_info_use_group_scoring && !group.some(x => x.useGroupScoring)) {
|
||||||
@@ -4152,6 +4153,13 @@ function filterGroupsByScoring(groups, buffer, removeEntry, scanState) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the group has any sticky entries, the rest are already removed by the timed effects filter
|
||||||
|
const hasAnySticky = hasStickyMap.get(key);
|
||||||
|
if (hasAnySticky) {
|
||||||
|
console.debug(`[WI] Skipping group scoring check, group '${key}' has sticky entries`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const scores = group.map(entry => buffer.getScore(entry, scanState));
|
const scores = group.map(entry => buffer.getScore(entry, scanState));
|
||||||
const maxScore = Math.max(...scores);
|
const maxScore = Math.max(...scores);
|
||||||
console.debug(`[WI] Group '${key}' max score:`, maxScore);
|
console.debug(`[WI] Group '${key}' max score:`, maxScore);
|
||||||
@@ -4175,14 +4183,65 @@ function filterGroupsByScoring(groups, buffer, removeEntry, scanState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes entries on cooldown and forces sticky entries as winners.
|
||||||
|
* @param {Record<string, WIScanEntry[]>} groups The groups to filter
|
||||||
|
* @param {WorldInfoTimedEffects} timedEffects The timed effects to use
|
||||||
|
* @param {(entry: WIScanEntry) => void} removeEntry The function to remove an entry
|
||||||
|
* @returns {Map<string, boolean>} If any sticky entries were found
|
||||||
|
*/
|
||||||
|
function filterGroupsByTimedEffects(groups, timedEffects, removeEntry) {
|
||||||
|
/** @type {Map<string, boolean>} */
|
||||||
|
const hasStickyMap = new Map();
|
||||||
|
|
||||||
|
for (const [key, group] of Object.entries(groups)) {
|
||||||
|
hasStickyMap.set(key, false);
|
||||||
|
|
||||||
|
// If the group has any sticky entries, leave only the sticky entries
|
||||||
|
const stickyEntries = group.filter(x => timedEffects.isEffectActive('sticky', x));
|
||||||
|
if (stickyEntries.length) {
|
||||||
|
for (const entry of group) {
|
||||||
|
if (stickyEntries.includes(entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug(`[WI] Entry ${entry.uid}`, `removed as a non-sticky loser from inclusion group '${key}'`, entry);
|
||||||
|
removeEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasStickyMap.set(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It should not be possible for an entry on cooldown/delay to event get into the grouping phase but @Wolfsblvt told me to leave it here.
|
||||||
|
const cooldownEntries = group.filter(x => timedEffects.isEffectActive('cooldown', x));
|
||||||
|
if (cooldownEntries.length) {
|
||||||
|
console.debug(`[WI] Inclusion group '${key}' has entries on cooldown. They will be removed.`, cooldownEntries);
|
||||||
|
for (const entry of cooldownEntries) {
|
||||||
|
removeEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const delayEntries = group.filter(x => timedEffects.isEffectActive('delay', x));
|
||||||
|
if (delayEntries.length) {
|
||||||
|
console.debug(`[WI] Inclusion group '${key}' has entries with delay. They will be removed.`, delayEntries);
|
||||||
|
for (const entry of delayEntries) {
|
||||||
|
removeEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasStickyMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters entries by inclusion groups.
|
* Filters entries by inclusion groups.
|
||||||
* @param {object[]} newEntries Entries activated on current recursion level
|
* @param {object[]} newEntries Entries activated on current recursion level
|
||||||
* @param {Set<object>} allActivatedEntries Set of all activated entries
|
* @param {Set<object>} allActivatedEntries Set of all activated entries
|
||||||
* @param {WorldInfoBuffer} buffer The buffer to use for scanning
|
* @param {WorldInfoBuffer} buffer The buffer to use for scanning
|
||||||
* @param {number} scanState The current scan state
|
* @param {number} scanState The current scan state
|
||||||
|
* @param {WorldInfoTimedEffects} timedEffects The timed effects currently active
|
||||||
*/
|
*/
|
||||||
function filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState) {
|
function filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState, timedEffects) {
|
||||||
console.debug('[WI] --- INCLUSION GROUP CHECKS ---');
|
console.debug('[WI] --- INCLUSION GROUP CHECKS ---');
|
||||||
|
|
||||||
const grouped = newEntries.filter(x => x.group).reduce((acc, item) => {
|
const grouped = newEntries.filter(x => x.group).reduce((acc, item) => {
|
||||||
@@ -4212,11 +4271,19 @@ function filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filterGroupsByScoring(grouped, buffer, removeEntry, scanState);
|
const hasStickyMap = filterGroupsByTimedEffects(grouped, timedEffects, removeEntry);
|
||||||
|
filterGroupsByScoring(grouped, buffer, removeEntry, scanState, hasStickyMap);
|
||||||
|
|
||||||
for (const [key, group] of Object.entries(grouped)) {
|
for (const [key, group] of Object.entries(grouped)) {
|
||||||
console.debug(`[WI] Checking inclusion group '${key}' with ${group.length} entries`, group);
|
console.debug(`[WI] Checking inclusion group '${key}' with ${group.length} entries`, group);
|
||||||
|
|
||||||
|
// If the group has any sticky entries, the rest are already removed by the timed effects filter
|
||||||
|
const hasAnySticky = hasStickyMap.get(key);
|
||||||
|
if (hasAnySticky) {
|
||||||
|
console.debug(`[WI] Skipping inclusion group check, group '${key}' has sticky entries`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Array.from(allActivatedEntries).some(x => x.group === key)) {
|
if (Array.from(allActivatedEntries).some(x => x.group === key)) {
|
||||||
console.debug(`[WI] Skipping inclusion group check, group '${key}' was already activated`);
|
console.debug(`[WI] Skipping inclusion group check, group '${key}' was already activated`);
|
||||||
// We need to forcefully deactivate all other entries in the group
|
// We need to forcefully deactivate all other entries in the group
|
||||||
|
Reference in New Issue
Block a user