From a5d00d356b9e78e256eca8dde3730eb0fbb879af Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Mon, 1 Apr 2024 02:11:52 +0300
Subject: [PATCH] Auto-calculate summary words
---
public/scripts/extensions/memory/index.js | 36 +++++++++++++++++++
.../scripts/extensions/memory/settings.html | 11 ++++--
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/public/scripts/extensions/memory/index.js b/public/scripts/extensions/memory/index.js
index 00c6de443..093e7f47b 100644
--- a/public/scripts/extensions/memory/index.js
+++ b/public/scripts/extensions/memory/index.js
@@ -122,6 +122,41 @@ function loadSettings() {
switchSourceControls(extension_settings.memory.source);
}
+async function onPromptForceWordsAutoClick() {
+ const context = getContext();
+ const maxPromptLength = getMaxContextSize(extension_settings.memory.overrideResponseLength);
+ const chat = context.chat;
+ const allMessages = chat.filter(m => !m.is_system && m.mes).map(m => m.mes);
+ const messagesWordCount = allMessages.map(m => extractAllWords(m)).flat().length;
+ const averageMessageWordCount = messagesWordCount / allMessages.length;
+ const tokensPerWord = getTokenCount(allMessages.join('\n')) / messagesWordCount;
+ const wordsPerToken = 1 / tokensPerWord;
+ const maxPromptLengthWords = Math.round(maxPromptLength * wordsPerToken);
+ // How many words should pass so that messages will start be dropped out of context;
+ const wordsPerPrompt = Math.floor(maxPromptLength / tokensPerWord);
+ // How many words will be needed to fit the allowance buffer
+ const summaryPromptWords = extractAllWords(extension_settings.memory.prompt).length;
+ const promptAllowanceWords = maxPromptLengthWords - extension_settings.memory.promptWords - summaryPromptWords;
+ const maxMessagesPerSummary = extension_settings.memory.maxMessagesPerRequest || 0;
+ const additionalWords = maxMessagesPerSummary > 0 ? Math.floor(averageMessageWordCount * maxMessagesPerSummary) : Math.max(0, promptAllowanceWords);
+ const targetSummaryWords = Math.round((wordsPerPrompt / 2) + additionalWords);
+
+ console.table({
+ maxPromptLength,
+ maxPromptLengthWords,
+ promptAllowanceWords,
+ targetSummaryWords,
+ wordsPerPrompt,
+ wordsPerToken,
+ tokensPerWord,
+ messagesWordCount,
+ });
+
+ const ROUNDING = 100;
+ extension_settings.memory.promptForceWords = Math.max(1, Math.floor(targetSummaryWords / ROUNDING) * ROUNDING);
+ $('#memory_prompt_words_force').val(extension_settings.memory.promptForceWords).trigger('input');
+}
+
async function onPromptIntervalAutoClick() {
const context = getContext();
const maxPromptLength = getMaxContextSize(extension_settings.memory.overrideResponseLength);
@@ -800,6 +835,7 @@ function setupListeners() {
$('#memory_prompt_builder_raw_non_blocking').off('click').on('input', onMemoryPromptBuilderInput);
$('#memory_prompt_restore').off('click').on('click', onMemoryPromptRestoreClick);
$('#memory_prompt_interval_auto').off('click').on('click', onPromptIntervalAutoClick);
+ $('#memory_prompt_words_auto').off('click').on('click', onPromptForceWordsAutoClick);
$('#memory_override_response_length').off('click').on('input', onOverrideResponseLengthInput);
$('#memory_max_messages_per_request').off('click').on('input', onMaxMessagesPerRequestInput);
$('#summarySettingsBlockToggle').off('click').on('click', function () {
diff --git a/public/scripts/extensions/memory/settings.html b/public/scripts/extensions/memory/settings.html
index c6f05fd2d..ed3b31ad7 100644
--- a/public/scripts/extensions/memory/settings.html
+++ b/public/scripts/extensions/memory/settings.html
@@ -91,9 +91,14 @@
-