mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-03 04:37:40 +01: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:
parent
758c90be00
commit
75c6bee350
@ -3953,7 +3953,7 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) {
|
||||
let newContent = '';
|
||||
const textToScanTokens = await getTokenCountAsync(allActivatedText);
|
||||
|
||||
filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState);
|
||||
filterByInclusionGroups(newEntries, allActivatedEntries, buffer, scanState, timedEffects);
|
||||
|
||||
console.debug('[WI] --- PROBABILITY CHECKS ---');
|
||||
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 {(entry: WIScanEntry) => void} removeEntry The function to remove an entry
|
||||
* @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)) {
|
||||
// Group scoring is disabled both globally and for the group entries
|
||||
if (!world_info_use_group_scoring && !group.some(x => x.useGroupScoring)) {
|
||||
@ -4152,6 +4153,13 @@ function filterGroupsByScoring(groups, buffer, removeEntry, scanState) {
|
||||
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 maxScore = Math.max(...scores);
|
||||
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.
|
||||
* @param {object[]} newEntries Entries activated on current recursion level
|
||||
* @param {Set<object>} allActivatedEntries Set of all activated entries
|
||||
* @param {WorldInfoBuffer} buffer The buffer to use for scanning
|
||||
* @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 ---');
|
||||
|
||||
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)) {
|
||||
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)) {
|
||||
console.debug(`[WI] Skipping inclusion group check, group '${key}' was already activated`);
|
||||
// We need to forcefully deactivate all other entries in the group
|
||||
|
Loading…
x
Reference in New Issue
Block a user