Remove double-loop nesting of WI key processing

This commit is contained in:
Wolfsblvt
2024-07-06 01:53:26 +02:00
parent b5f77a2164
commit 0b9431cd9a

View File

@@ -3693,76 +3693,85 @@ async function checkWorldInfo(chat, maxContext, isDryRun) {
continue; continue;
} }
// If selectiveLogic isn't found, assume it's AND, only do this once per entry
const selectiveLogic = entry.selectiveLogic ?? 0;
// Cache the text to scan before the loop, it won't change its content // Cache the text to scan before the loop, it won't change its content
const textToScan = buffer.get(entry, scanState); const textToScan = buffer.get(entry, scanState);
primary: for (let key of entry.key) { // PRIMARY KEYWORDS
let primaryKeyMatch = entry.key.find(key => {
const substituted = substituteParams(key); const substituted = substituteParams(key);
return substituted && buffer.matchKeys(textToScan, substituted.trim(), entry);
});
if (substituted && buffer.matchKeys(textToScan, substituted.trim(), entry)) { if (!primaryKeyMatch) {
log('has match on primary keyword', substituted); // Don't write logs for simple no-matches
continue;
}
//selective logic begins const hasSecondaryKeywords = (
if ( entry.selective && //all entries are selective now
entry.selective && //all entries are selective now Array.isArray(entry.keysecondary) && //always true
Array.isArray(entry.keysecondary) && //always true entry.keysecondary.length //ignore empties
entry.keysecondary.length //ignore empties );
) {
log('has secondary keywords. Checking logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic));
let hasAnyMatch = false;
let hasAllMatch = true;
secondary: for (let keysecondary of entry.keysecondary) {
const secondarySubstituted = substituteParams(keysecondary);
const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry);
if (hasSecondaryMatch) { if (!hasSecondaryKeywords) {
hasAnyMatch = true; // Handle cases where secondary is empty
} log('activated by primary key match', primaryKeyMatch);
activatedNow.add(entry);
continue;
}
if (!hasSecondaryMatch) {
hasAllMatch = false;
}
// Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya) // SECONDARY KEYWORDS
// If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass const selectiveLogic = entry.selectiveLogic ?? 0; // If selectiveLogic isn't found, assume it's AND, only do this once per entry
if ((selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) || (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch)) { log('Entry with primary key match', primaryKeyMatch, 'has secondary keywords. Checking with logic logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic));
if (selectiveLogic === world_info_logic.AND_ANY) {
log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted);
} else {
log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted);
}
activatedNow.add(entry);
break secondary;
}
}
// Handle NOT ANY logic /** @type {() => boolean} */
if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) { function matchSecondaryKeys() {
log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary); let hasAnyMatch = false;
activatedNow.add(entry); let hasAllMatch = true;
break primary; for (let keysecondary of entry.keysecondary) {
} const secondarySubstituted = substituteParams(keysecondary);
const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry);
// Handle AND ALL logic if (hasSecondaryMatch) hasAnyMatch = true;
if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) { if (!hasSecondaryMatch) hasAllMatch = false;
log('activated. (AND ALL) All secondary keywords found', entry.keysecondary);
activatedNow.add(entry);
break primary;
}
log('skipped. Secondary keywords not satisfied', entry.keysecondary); // Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya)
break primary; // If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass
} else { if (selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) {
// Handle cases where secondary is empty log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted);
log('activated by primary keyword', substituted); return true;
activatedNow.add(entry); }
break primary; if (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch) {
log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted);
return true;
} }
} }
// Handle NOT ANY logic
if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) {
log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary);
return true;
}
// Handle AND ALL logic
if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) {
log('activated. (AND ALL) All secondary keywords found', entry.keysecondary);
return true;
}
return false;
} }
const matched = matchSecondaryKeys();
if (!matched) {
log('skipped. Secondary keywords not satisfied', entry.keysecondary);
continue;
}
// Success logging was already done inside the function, so just add the entry
activatedNow.add(entry);
continue;
} }
console.debug(`[WI] Search done. Found ${activatedNow.size} possible entries.`); console.debug(`[WI] Search done. Found ${activatedNow.size} possible entries.`);