diff --git a/public/script.js b/public/script.js index f901090dd..84c02c9e8 100644 --- a/public/script.js +++ b/public/script.js @@ -2645,6 +2645,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, allAnchors: allAnchors, summarizeString: (extension_prompts['1_memory']?.value || ''), authorsNoteString: (extension_prompts['2_floating_prompt']?.value || ''), + smartContextString: (extension_prompts['chromadb']?.value || ''), worldInfoString: worldInfoString, storyString: storyString, worldInfoAfter: worldInfoAfter, @@ -3139,6 +3140,7 @@ function promptItemize(itemizedPrompts, requestedMesId) { var allAnchorsTokens = getTokenCount(itemizedPrompts[thisPromptSet].allAnchors); var summarizeStringTokens = getTokenCount(itemizedPrompts[thisPromptSet].summarizeString); var authorsNoteStringTokens = getTokenCount(itemizedPrompts[thisPromptSet].authorsNoteString); + var smartContextStringTokens = getTokenCount(itemizedPrompts[thisPromptSet].smartContextString); var afterScenarioAnchorTokens = getTokenCount(itemizedPrompts[thisPromptSet].afterScenarioAnchor); var zeroDepthAnchorTokens = getTokenCount(itemizedPrompts[thisPromptSet].afterScenarioAnchor); var worldInfoStringTokens = getTokenCount(itemizedPrompts[thisPromptSet].worldInfoString); @@ -3313,6 +3315,10 @@ function promptItemize(itemizedPrompts, requestedMesId) {
-- Author's Note:
${authorsNoteStringTokens}
+
+
-- Smart Context:
+
${smartContextStringTokens}
+
{{}} Bias:
${oaiBiasTokens}
@@ -3400,6 +3406,10 @@ function promptItemize(itemizedPrompts, requestedMesId) {
-- Author's Note:
${authorsNoteStringTokens}
+
+
-- Smart Context:
+
${smartContextStringTokens}
+
{{}} Bias:
${promptBiasTokens}
diff --git a/public/scripts/extensions/infinity-context/index.js b/public/scripts/extensions/infinity-context/index.js index ec0cc279b..f00f266dc 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(); } @@ -128,11 +138,14 @@ function onStrategyChange() { $('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 +187,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); @@ -337,6 +364,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(); @@ -354,6 +390,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()); @@ -549,122 +590,167 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => { } const currentChatId = getCurrentChatId(); + if (!currentChatId) + return; + + //log the current settings + console.debug("CHROMADB: Current settings: %o", extension_settings.chromadb); + 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; + const chromaQueryLastOnly = extension_settings.chromadb.query_last_only; + const messagesToStore = chat.slice(0, -extension_settings.chromadb.keep_context); - //log the current settings - console.debug("CHROMADB: Current settings: %o", extension_settings.chromadb); - - - if (currentChatId) { - const messagesToStore = chat.slice(0, -extension_settings.chromadb.keep_context); + if (messagesToStore.length > 0 && !extension_settings.chromadb.freeze) { //log the messages to store console.debug("CHROMADB: Messages to store: %o", messagesToStore); + //log the messages to store length vs keep context + console.debug("CHROMADB: Messages to store length vs keep context: %o vs %o", messagesToStore.length, extension_settings.chromadb.keep_context); + await addMessages(currentChatId, messagesToStore); + } + + const lastMessage = chat[chat.length - 1]; - if (messagesToStore.length > 0 || extension_settings.chromadb.freeze) { - //log the messages to store length vs keep context - console.debug("CHROMADB: Messages to store length vs keep context: %o vs %o", messagesToStore.length, extension_settings.chromadb.keep_context); - await addMessages(currentChatId, messagesToStore); - - const lastMessage = chat[chat.length - 1]; - - let queriedMessages; - console.debug(recallStrategy) - if (lastMessage) { - if (recallStrategy === '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); - - } + 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); + + } } } @@ -679,18 +765,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() { @@ -714,12 +801,22 @@ jQuery(async () => { + + + + + + + + + Memory Recall Strategy - + + @@ -752,6 +850,10 @@ jQuery(async () => { Chunk on Newlines +