From e5e275a827641db744e06d4e10d5c73c8e8050bf Mon Sep 17 00:00:00 2001 From: 50h100a Date: Fri, 7 Jul 2023 03:22:27 -0400 Subject: [PATCH 1/2] 'Smart Context' updates and fixes. Added alternative strategy. Logic fix to reliably load memories. Option to query using entire current chatlog. --- .../extensions/infinity-context/index.js | 356 ++++++++++++------ 1 file changed, 239 insertions(+), 117 deletions(-) diff --git a/public/scripts/extensions/infinity-context/index.js b/public/scripts/extensions/infinity-context/index.js index ecdf56830..f079c5827 100644 --- a/public/scripts/extensions/infinity-context/index.js +++ b/public/scripts/extensions/infinity-context/index.js @@ -1,4 +1,4 @@ -import { saveSettingsDebounced, getCurrentChatId, system_message_types, eventSource, event_types, getRequestHeaders, CHARACTERS_PER_TOKEN_RATIO, substituteParams, } from "../../../script.js"; +import { saveSettingsDebounced, getCurrentChatId, system_message_types, extension_prompt_types, eventSource, event_types, getRequestHeaders, CHARACTERS_PER_TOKEN_RATIO, substituteParams, max_context, } from "../../../script.js"; import { humanizedDateTime } from "../../RossAscends-mods.js"; import { getApiUrl, extension_settings, getContext, doExtrasFetch } from "../../extensions.js"; import { getFileText, onlyUnique, splitRecursive, IndexedDBStore } from "../../utils.js"; @@ -26,6 +26,9 @@ const defaultSettings = { chroma_depth_max: 500, chroma_depth_step: 1, chroma_default_msg: "In a past conversation: [{{memories}}]", + chroma_default_hhaa_wrapper: "Previous messages exchanged between {{user}} and {{char}}:\n{{memories}}", + chroma_default_hhaa_memory: "- {{name}}: {{message}}\n", + hhaa_token_limit: 512, split_length: 384, split_length_min: 64, @@ -44,6 +47,7 @@ const defaultSettings = { auto_adjust: true, freeze: false, + query_last_only: true, }; const postHeaders = { @@ -114,8 +118,14 @@ async function loadSettings() { $('#chromadb_keep_context_proportion').val(extension_settings.chromadb.keep_context_proportion).trigger('input'); $('#chromadb_custom_depth').val(extension_settings.chromadb.chroma_depth).trigger('input'); $('#chromadb_custom_msg').val(extension_settings.chromadb.recall_msg).trigger('input'); + + $('#chromadb_hhaa_wrapperfmt').val(extension_settings.chromadb.hhaa_wrapper_msg).trigger('input'); + $('#chromadb_hhaa_memoryfmt').val(extension_settings.chromadb.hhaa_memory_msg).trigger('input'); + $('#chromadb_hhaa_token_limit').val(extension_settings.chromadb.hhaa_token_limit).trigger('input'); + $('#chromadb_auto_adjust').prop('checked', extension_settings.chromadb.auto_adjust); $('#chromadb_freeze').prop('checked', extension_settings.chromadb.freeze); + $('#chromadb_query_last_only').val(extension_settings.chromadb.query_last_only).trigger('input'); enableDisableSliders(); onStrategyChange(); } @@ -123,16 +133,32 @@ async function loadSettings() { function onStrategyChange() { console.debug('changing chromadb strat'); extension_settings.chromadb.strategy = $('#chromadb_strategy').val(); + + $('#chromadb_custom_depth').hide(); + $('label[for="chromadb_custom_depth"]').hide(); + $('#chromadb_custom_msg').hide(); + $('label[for="chromadb_custom_msg"]').hide(); + + $('#chromadb_hhaa_wrapperfmt').hide(); + $('label[for="chromadb_hhaa_wrapperfmt"]').hide(); + $('#chromadb_hhaa_memoryfmt').hide(); + $('label[for="chromadb_hhaa_memoryfmt"]').hide(); + $('#chromadb_hhaa_token_limit').hide(); + $('label[for="chromadb_hhaa_token_limit"]').hide(); + if(extension_settings.chromadb.strategy === "custom"){ $('#chromadb_custom_depth').show(); $('label[for="chromadb_custom_depth"]').show(); $('#chromadb_custom_msg').show(); $('label[for="chromadb_custom_msg"]').show(); - } else { - $('#chromadb_custom_depth').hide(); - $('label[for="chromadb_custom_depth"]').hide(); - $('#chromadb_custom_msg').hide(); - $('label[for="chromadb_custom_msg"]').hide(); + } + else if(extension_settings.chromadb.strategy === "hh_aa"){ + $('#chromadb_hhaa_wrapperfmt').show(); + $('label[for="chromadb_hhaa_wrapperfmt"]').show(); + $('#chromadb_hhaa_memoryfmt').show(); + $('label[for="chromadb_hhaa_memoryfmt"]').show(); + $('#chromadb_hhaa_token_limit').show(); + $('label[for="chromadb_hhaa_token_limit"]').show(); } saveSettingsDebounced(); } @@ -174,6 +200,20 @@ function onChromaMsgInput() { saveSettingsDebounced(); } +function onChromaHHAAWrapper() { + extension_settings.chromadb.hhaa_wrapper_msg = $('#chromadb_hhaa_wrapperfmt').val(); + saveSettingsDebounced(); +} +function onChromaHHAAMemory() { + extension_settings.chromadb.hhaa_memory_msg = $('#chromadb_hhaa_memoryfmt').val(); + saveSettingsDebounced(); +} +function onChromaHHAATokens() { + extension_settings.chromadb.hhaa_token_limit = Number($('#chromadb_hhaa_token_limit').val()); + $('#chromadb_hhaa_token_limit_value').text(extension_settings.chromadb.hhaa_token_limit); + saveSettingsDebounced(); +} + function onSplitLengthInput() { extension_settings.chromadb.split_length = Number($('#chromadb_split_length').val()); $('#chromadb_split_length_value').text(extension_settings.chromadb.split_length); @@ -327,6 +367,15 @@ async function onExportClick() { } } +function tinyhash(text) { + let hash = 0; + for (let i = 0; i < text.length; ++i) { + hash = ((hash<<5) - hash) + text.charCodeAt(i); + hash = hash & hash; // Keeps it 32-bit allegedly. + } + return hash; +} + async function onSelectImportFile(e) { const file = e.target.files[0]; const currentChatId = getCurrentChatId(); @@ -344,6 +393,11 @@ async function onSelectImportFile(e) { const text = await getFileText(file); const imported = JSON.parse(text); + const id_salt = "-" + tinyhash(imported.chat_id).toString(36); + for (let entry of imported.content) { + entry.id = entry.id + id_salt; + } + imported.chat_id = currentChatId; const url = new URL(getApiUrl()); @@ -533,115 +587,161 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => { } const currentChatId = getCurrentChatId(); + if (!currentChatId) + return; + const selectedStrategy = extension_settings.chromadb.strategy; const recallStrategy = extension_settings.chromadb.recall_strategy; let recallMsg = extension_settings.chromadb.recall_msg || defaultSettings.chroma_default_msg; const chromaDepth = extension_settings.chromadb.chroma_depth; const chromaSortStrategy = extension_settings.chromadb.sort_strategy; - if (currentChatId) { - const messagesToStore = chat.slice(0, -extension_settings.chromadb.keep_context); + const chromaQueryLastOnly = extension_settings.chromadb.query_last_only; + const messagesToStore = chat.slice(0, -extension_settings.chromadb.keep_context); - if (messagesToStore.length > 0 || extension_settings.chromadb.freeze) { - await addMessages(currentChatId, messagesToStore); + if (messagesToStore.length > 0 && !extension_settings.chromadb.freeze) { + await addMessages(currentChatId, messagesToStore); + } + + const lastMessage = chat[chat.length - 1]; - const lastMessage = chat[chat.length - 1]; - - let queriedMessages; - console.debug(recallStrategy) - if (lastMessage) { - if (recallStrategy === 'multichat'){ - console.log("Utilizing multichat") - queriedMessages = await queryMultiMessages(currentChatId, lastMessage.mes); - } - else{ - queriedMessages = await queryMessages(currentChatId, lastMessage.mes); - } - - if(chromaSortStrategy === "date"){ - queriedMessages.sort((a, b) => a.date - b.date); - } - else{ - queriedMessages.sort((a, b) => b.distance - a.distance); - } - - - let newChat = []; - - if (selectedStrategy === 'ross') { - //adds chroma to the end of chat and allows Generate() to cull old messages naturally. - const context = getContext(); - const charname = context.name2; - newChat.push( - { - is_name: false, - is_user: false, - mes: `[Use these past chat exchanges to inform ${charname}'s next response:`, - name: "system", - send_date: 0, - } - ); - newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); - newChat.push( - { - is_name: false, - is_user: false, - mes: `]\n`, - name: "system", - send_date: 0, - } - ); - chat.splice(chat.length, 0, ...newChat); - } - if (selectedStrategy === 'custom') { - const context = getContext(); - recallMsg = substituteParams(recallMsg, context.name1, context.name2); - if (!text.includes("{{memories}}")) { - text += " {{memories}}"; - } - let recallStart = recallMsg.split('{{memories}}')[0] - let recallEnd = recallMsg.split('{{memories}}')[1] - - newChat.push( - { - is_name: false, - is_user: false, - mes: recallStart, - name: "system", - send_date: 0, - } - ); - newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); - newChat.push( - { - is_name: false, - is_user: false, - mes: recallEnd + `\n`, - name: "system", - send_date: 0, - } - ); - - //prototype chroma duplicate removal - let chatset = new Set(chat.map(obj => obj.mes)); - newChat = newChat.filter(obj => !chatset.has(obj.mes)); - - if(chromaDepth === -1){ - chat.splice(chat.length, 0, ...newChat); - } - else{ - chat.splice(chromaDepth, 0, ...newChat); - } - } - if (selectedStrategy === 'original') { - //removes .length # messages from the start of 'kept messages' - //replaces them with chromaDB results (with no separator) - newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); - chat.splice(0, messagesToStore.length, ...newChat); - - } - console.log('ChromaDB chat after injection', chat); + let queriedMessages; + console.debug(recallStrategy) + if (lastMessage) { + let queryBlob = ""; + if (chromaQueryLastOnly) { + queryBlob = lastMessage.mes; + } + else { + for (let msg of chat) { + queryBlob += `${msg.mes}\n` } } + console.log("ChromDB Query text:", queryBlob); + + if (recallStrategy === 'multichat'){ + console.log("Utilizing multichat") + queriedMessages = await queryMultiMessages(currentChatId, queryBlob); + } + else{ + queriedMessages = await queryMessages(currentChatId, queryBlob); + } + + if(chromaSortStrategy === "date"){ + queriedMessages.sort((a, b) => a.date - b.date); + } + else{ + queriedMessages.sort((a, b) => b.distance - a.distance); + } + console.log(queriedMessages); + + + let newChat = []; + + if (selectedStrategy === 'ross') { + //adds chroma to the end of chat and allows Generate() to cull old messages naturally. + const context = getContext(); + const charname = context.name2; + newChat.push( + { + is_name: false, + is_user: false, + mes: `[Use these past chat exchanges to inform ${charname}'s next response:`, + name: "system", + send_date: 0, + } + ); + newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); + newChat.push( + { + is_name: false, + is_user: false, + mes: `]\n`, + name: "system", + send_date: 0, + } + ); + chat.splice(chat.length, 0, ...newChat); + } + if (selectedStrategy === 'hh_aa') { + // Insert chroma history messages as a list at the AFTER_SCENARIO anchor point + const context = getContext(); + const chromaTokenLimit = extension_settings.chromadb.hhaa_token_limit; + + let wrapperMsg = extension_settings.chromadb.hhaa_wrapper_msg || defaultSettings.chroma_default_hhaa_wrapper; + wrapperMsg = substituteParams(wrapperMsg, context.name1, context.name2); + if (!wrapperMsg.includes("{{memories}}")) { + wrapperMsg += " {{memories}}"; + } + let memoryMsg = extension_settings.chromadb.hhaa_memory_msg || defaultSettings.chroma_default_hhaa_memory; + memoryMsg = substituteParams(memoryMsg, context.name1, context.name2); + if (!memoryMsg.includes("{{message}}")) { + memoryMsg += " {{message}}"; + } + + // Reversed because we want the most important messages at the bottom. + let recalledMemories = queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse).reverse(); + let tokenApprox = 0; + let allMemoryBlob = ""; + for (let msg of recalledMemories) { + let memoryBlob = memoryMsg.replace('{{name}}', msg.name).replace('{{message}}', msg.mes); + tokenApprox += (memoryBlob.length / CHARACTERS_PER_TOKEN_RATIO); + if (tokenApprox > chromaTokenLimit) { + break; + } + allMemoryBlob += memoryBlob; + } + + const promptBlob = wrapperMsg.replace('{{memories}}', allMemoryBlob); + context.setExtensionPrompt(MODULE_NAME, promptBlob, extension_prompt_types.AFTER_SCENARIO); + } + if (selectedStrategy === 'custom') { + const context = getContext(); + recallMsg = substituteParams(recallMsg, context.name1, context.name2); + if (!recallMsg.includes("{{memories}}")) { + recallMsg += " {{memories}}"; + } + let recallStart = recallMsg.split('{{memories}}')[0] + let recallEnd = recallMsg.split('{{memories}}')[1] + + newChat.push( + { + is_name: false, + is_user: false, + mes: recallStart, + name: "system", + send_date: 0, + } + ); + newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); + newChat.push( + { + is_name: false, + is_user: false, + mes: recallEnd + `\n`, + name: "system", + send_date: 0, + } + ); + + //prototype chroma duplicate removal + let chatset = new Set(chat.map(obj => obj.mes)); + newChat = newChat.filter(obj => !chatset.has(obj.mes)); + + if(chromaDepth === -1){ + chat.splice(chat.length, 0, ...newChat); + } + else{ + chat.splice(chromaDepth, 0, ...newChat); + } + } + if (selectedStrategy === 'original') { + //removes .length # messages from the start of 'kept messages' + //replaces them with chromaDB results (with no separator) + newChat.push(...queriedMessages.map(m => m.meta).filter(onlyUnique).map(JSON.parse)); + chat.splice(0, messagesToStore.length, ...newChat); + + } + console.log('ChromaDB chat after injection', chat); } } @@ -656,18 +756,19 @@ function onAutoAdjustInput() { enableDisableSliders(); saveSettingsDebounced(); } +function onFullLogQuery() { + extension_settings.chromadb.query_last_only = $('#chromadb_query_last_only').is(':checked'); + saveSettingsDebounced(); +} function enableDisableSliders() { - if (extension_settings.chromadb.auto_adjust) { - $('#chromadb_keep_context').prop('disabled', true).css('opacity', 0.5); - $('#chromadb_n_results').prop('disabled', true).css('opacity', 0.5); - $('#chromadb_keep_context_proportion').prop('disabled', false).css('opacity', 1); - } - else { - $('#chromadb_keep_context').prop('disabled', false).css('opacity', 1); - $('#chromadb_n_results').prop('disabled', false).css('opacity', 1); - $('#chromadb_keep_context_proportion').prop('disabled', true).css('opacity', 0.5); - } + const auto_adjust = extension_settings.chromadb.auto_adjust; + $('label[for="chromadb_keep_context"]').prop('hidden', auto_adjust); + $('#chromadb_keep_context').prop('hidden', auto_adjust) + $('label[for="chromadb_n_results"]').prop('hidden', auto_adjust); + $('#chromadb_n_results').prop('hidden', auto_adjust) + $('label[for="chromadb_keep_context_proportion"]').prop('hidden', !auto_adjust); + $('#chromadb_keep_context_proportion').prop('hidden', !auto_adjust) } function onKeepContextProportionInput() { @@ -691,12 +792,22 @@ jQuery(async () => { + + + + + + + + + Memory Recall Strategy - + + @@ -725,6 +837,10 @@ jQuery(async () => { Use % strategy +
+
+
-- Smart Context:
+
${smartContextStringTokens}
+
{{}} Bias:
${oaiBiasTokens}
@@ -3407,6 +3413,10 @@ function promptItemize(itemizedPrompts, requestedMesId) {
-- Author's Note:
${authorsNoteStringTokens}
+
+
-- Smart Context:
+
${smartContextStringTokens}
+
{{}} Bias:
${promptBiasTokens}