Implement WI matching on global data

d2ffefd24c869ff73cafab1ee76b0f5c8d371b5e

Crow <bismuthglass@protonmail.com>

2 files changed, +41 -13Ignore whitespace
public/script.js+2 -1
@@ -4143,7 +4143,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4143 // Make quiet prompt available for WIAN4143 // Make quiet prompt available for WIAN
4144 setExtensionPrompt('QUIET_PROMPT', quiet_prompt || '', extension_prompt_types.IN_PROMPT, 0, true);4144 setExtensionPrompt('QUIET_PROMPT', quiet_prompt || '', extension_prompt_types.IN_PROMPT, 0, true);
4145 const chatForWI = coreChat.map(x => world_info_include_names ? `${x.name}: ${x.mes}` : x.mes).reverse();4145 const chatForWI = coreChat.map(x => world_info_include_names ? `${x.name}: ${x.mes}` : x.mes).reverse();
4146 const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(chatForWI, this_max_context, dryRun);4146 // TODO: Build globalScanData
4147 const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(null, chatForWI, this_max_context, dryRun);
4147 setExtensionPrompt('QUIET_PROMPT', '', extension_prompt_types.IN_PROMPT, 0, true);4148 setExtensionPrompt('QUIET_PROMPT', '', extension_prompt_types.IN_PROMPT, 0, true);
41484149
4149 // Add message example WI4150 // Add message example WI
public/scripts/world-info.js+39 -12
@@ -156,6 +156,11 @@ class WorldInfoBuffer {
156 static externalActivations = new Map();156 static externalActivations = new Map();
157157
158 /**158 /**
159 * @type {WIGlobalScanData} Chat independent data to be scanned, such as persona and character descriptions
160 */
161 #globalScanDataBuffer = null;
162
163 /**
159 * @type {string[]} Array of messages sorted by ascending depth164 * @type {string[]} Array of messages sorted by ascending depth
160 */165 */
161 #depthBuffer = [];166 #depthBuffer = [];
@@ -182,10 +187,12 @@ class WorldInfoBuffer {
182187
183 /**188 /**
184 * Initialize the buffer with the given messages.189 * Initialize the buffer with the given messages.
190 * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned
185 * @param {string[]} messages Array of messages to add to the buffer191 * @param {string[]} messages Array of messages to add to the buffer
186 */192 */
187 constructor(messages) {193 constructor(globalScanData, messages) {
188 this.#initDepthBuffer(messages);194 this.#initDepthBuffer(messages);
195 this.#globalScanDataBuffer = globalScanData;
189 }196 }
190197
191 /**198 /**
@@ -242,6 +249,25 @@ class WorldInfoBuffer {
242 const JOINER = '\n' + MATCHER;249 const JOINER = '\n' + MATCHER;
243 let result = MATCHER + this.#depthBuffer.slice(this.#startDepth, depth).join(JOINER);250 let result = MATCHER + this.#depthBuffer.slice(this.#startDepth, depth).join(JOINER);
244251
252 if (entry.matchPersonaDescription) {
253 result += JOINER + this.#globalScanDataBuffer.personaDescription;
254 }
255 if (entry.matchCharacterDescription) {
256 result += JOINER + this.#globalScanDataBuffer.characterDescription;
257 }
258 if (entry.matchCharacterPersonality) {
259 result += JOINER + this.#globalScanDataBuffer.characterPersonality;
260 }
261 if (entry.matchCharacterNote) {
262 result += JOINER + this.#globalScanDataBuffer.characterNote;
263 }
264 if (entry.matchScenario) {
265 result += JOINER + this.#globalScanDataBuffer.scenario;
266 }
267 if (entry.matchCreatorNotes) {
268 result += JOINER + this.#globalScanDataBuffer.creatorNotes;
269 }
270
245 if (this.#injectBuffer.length > 0) {271 if (this.#injectBuffer.length > 0) {
246 result += JOINER + this.#injectBuffer.join(JOINER);272 result += JOINER + this.#injectBuffer.join(JOINER);
247 }273 }
@@ -770,6 +796,7 @@ export const worldInfoCache = new StructuredCloneMap({ cloneOnGet: true, cloneOn
770796
771/**797/**
772 * Gets the world info based on chat messages.798 * Gets the world info based on chat messages.
799 * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned
773 * @param {string[]} chat - The chat messages to scan, in reverse order.800 * @param {string[]} chat - The chat messages to scan, in reverse order.
774 * @param {number} maxContext - The maximum context size of the generation.801 * @param {number} maxContext - The maximum context size of the generation.
775 * @param {boolean} isDryRun - If true, the function will not emit any events.802 * @param {boolean} isDryRun - If true, the function will not emit any events.
@@ -783,10 +810,10 @@ export const worldInfoCache = new StructuredCloneMap({ cloneOnGet: true, cloneOn
783 * @property {Array} anAfter - Array of entries after Author's Note810 * @property {Array} anAfter - Array of entries after Author's Note
784 * @returns {Promise<WIPromptResult>} The world info string and depth.811 * @returns {Promise<WIPromptResult>} The world info string and depth.
785 */812 */
786export async function getWorldInfoPrompt(chat, maxContext, isDryRun) {813export async function getWorldInfoPrompt(globalScanData, chat, maxContext, isDryRun) {
787 let worldInfoString = '', worldInfoBefore = '', worldInfoAfter = '';814 let worldInfoString = '', worldInfoBefore = '', worldInfoAfter = '';
788815
789 const activatedWorldInfo = await checkWorldInfo(chat, maxContext, isDryRun);816 const activatedWorldInfo = await checkWorldInfo(globalScanData, chat, maxContext, isDryRun);
790 worldInfoBefore = activatedWorldInfo.worldInfoBefore;817 worldInfoBefore = activatedWorldInfo.worldInfoBefore;
791 worldInfoAfter = activatedWorldInfo.worldInfoAfter;818 worldInfoAfter = activatedWorldInfo.worldInfoAfter;
792 worldInfoString = worldInfoBefore + worldInfoAfter;819 worldInfoString = worldInfoBefore + worldInfoAfter;
@@ -3333,17 +3360,17 @@ export async function getWorldEntry(name, data, entry) {
33333360
3334 function handleOptionalSelect(name) {3361 function handleOptionalSelect(name) {
3335 const key = originalWIDataKeyMap[name];3362 const key = originalWIDataKeyMap[name];
3336 const selectElem = template.find(`select[name="${name}"]`);3363 const checkBoxElem = template.find(`input[type="checkbox"][name="${name}"]`);
3337 selectElem.data('uid', entry.uid);3364 checkBoxElem.data('uid', entry.uid);
3338 selectElem.on('input', async function () {3365 checkBoxElem.on('change', async function () {
3339 const uid = $(this).data('uid');3366 const uid = $(this).data('uid');
3340 const value = $(this).val();3367 const isChecked = $(this).is(':checked');
33413368
3342 data.entries[uid][name] = value === 'null' ? null : value === 'true';3369 data.entries[uid][name] = isChecked;
3343 setWIOriginalDataValue(data, uid, key, data.entries[uid][name]);3370 setWIOriginalDataValue(data, uid, key, data.entries[uid][name]);
3344 await saveWorldInfo(name, data);3371 await saveWorldInfo(name, data);
3345 });3372 });
3346 selectElem.val((entry[name] === null || entry[name] === undefined) ? 'null' : entry[name] ? 'true' : 'false').trigger('input');3373 checkBoxElem.prop('checked', !!entry[name]).trigger('change');
3347 }3374 }
33483375
3349 handleOptionalSelect("matchPersonaDescription");3376 handleOptionalSelect("matchPersonaDescription");
@@ -4020,7 +4047,7 @@ function parseDecorators(content) {
40204047
4021/**4048/**
4022 * Performs a scan on the chat and returns the world info activated.4049 * Performs a scan on the chat and returns the world info activated.
4023 * @param {string[]} chat The chat messages to scan, in reverse order.4050 * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned
4024 * @param {number} maxContext The maximum context size of the generation.4051 * @param {number} maxContext The maximum context size of the generation.
4025 * @param {boolean} isDryRun Whether to perform a dry run.4052 * @param {boolean} isDryRun Whether to perform a dry run.
4026 * @typedef {object} WIActivated4053 * @typedef {object} WIActivated
@@ -4033,9 +4060,9 @@ function parseDecorators(content) {
4033 * @property {Set<any>} allActivatedEntries All entries.4060 * @property {Set<any>} allActivatedEntries All entries.
4034 * @returns {Promise<WIActivated>} The world info activated.4061 * @returns {Promise<WIActivated>} The world info activated.
4035 */4062 */
4036export async function checkWorldInfo(chat, maxContext, isDryRun) {4063export async function checkWorldInfo(globalScanData, chat, maxContext, isDryRun) {
4037 const context = getContext();4064 const context = getContext();
4038 const buffer = new WorldInfoBuffer(chat);4065 const buffer = new WorldInfoBuffer(globalScanData, chat);
40394066
4040 console.debug(`[WI] --- START WI SCAN (on ${chat.length} messages)${isDryRun ? ' (DRY RUN)' : ''} ---`);4067 console.debug(`[WI] --- START WI SCAN (on ${chat.length} messages)${isDryRun ? ' (DRY RUN)' : ''} ---`);
40414068