From 6784676e210bbbec22dd96b687e9912eabbe9c32 Mon Sep 17 00:00:00 2001 From: prima Date: Fri, 26 Jul 2024 21:18:06 +0100 Subject: [PATCH 1/4] feature: Addition of memory snippets (LTM) --- index.html | 828 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 807 insertions(+), 21 deletions(-) diff --git a/index.html b/index.html index b121c9c..b355ea4 100644 --- a/index.html +++ b/index.html @@ -4166,6 +4166,9 @@ dry_allowed_length: 2, dry_sequence_breakers: ["\n", ":", "\"", "*"], sampler_order: [6, 0, 1, 3, 4, 2, 5], + memsnippet_enabled: false, // Memory snippets off by default + memsnippet_numOfSnippets: 3, // Number of snippets to include defaults to 3 + memsnippet_minSignificance: 0.01, // Must have the bare minimum of significance to be included }; var defaultsettings = JSON.parse(JSON.stringify(localsettings)); @@ -10286,6 +10289,9 @@ logitbiasdict = {}; wi_searchdepth = 0; wi_insertlocation = 0; + localsettings.memsnippet_enabled = false; + localsettings.memsnippet_numOfSnippets = 3; + localsettings.memsnippet_minSignificance = 0.01; current_anotetemplate = "[Author's note: <|>]"; regexreplace_data = []; placeholder_tags_data = []; @@ -11036,6 +11042,27 @@ } } + function getMaxAllowedCharacters(content, amountToTrimForContext) + { + //this is a hack since we dont have a proper tokenizer, but we can estimate 1 token per 3 characters + let chars_per_token = 3.0; + + //we try to detect attempts at coding which tokenize poorly. This usually happens when the average word length is high. + let avgwordlen = (1.0 + content.length) / (1.0 + countWords(content)); + if (avgwordlen >= 7.8) { + chars_per_token = 2.7; + } + if (current_memory == null || current_memory.trim() == "") { + //if there is no memory, then we can be a lot of lenient with the character counts since the backend will truncate excess anyway + chars_per_token = 4.8; + } + if (is_using_kcpp_with_added_memory()) //easily handle overflow + { + chars_per_token = 6; + } + return Math.max(1, Math.floor(amountToTrimForContext * chars_per_token) - 12); + } + function submit_generation() { warn_on_quit = true; @@ -11208,24 +11235,7 @@ let truncated_context = concat_gametext(true, "","","",false,true); //no need to truncate if memory is empty truncated_context = truncated_context.replace(/\xA0/g,' '); //replace non breaking space nbsp - //this is a hack since we dont have a proper tokenizer, but we can estimate 1 token per 3 characters - let chars_per_token = 3.0; - //we try to detect attempts at coding which tokenize poorly. This usually happens when the average word length is high. - let avgwordlen = (1.0+truncated_context.length)/(1.0+countWords(truncated_context)); - if(avgwordlen>=7.8) - { - chars_per_token = 2.7; - } - if (current_memory == null || current_memory.trim() == "") - { - //if there is no memory, then we can be a lot of lenient with the character counts since the backend will truncate excess anyway - chars_per_token = 4.8; - } - if(is_using_kcpp_with_added_memory()) //easily handle overflow - { - chars_per_token = 6; - } - let max_allowed_characters = Math.max(1, Math.floor((maxctxlen-maxgenamt) * chars_per_token) - 12); + let max_allowed_characters = getMaxAllowedCharacters(truncated_context, (maxctxlen - maxgenamt)) //for adventure mode, inject hidden context, even more if there's nothing in memory if (localsettings.opmode == 2 && localsettings.adventure_context_mod) @@ -11515,6 +11525,24 @@ truncated_anote = ""; } + // [LTM][START] + if (localsettings.memsnippet_enabled) + { + // Finds the relevant memory fragments, formats them in a similar way to an authors note and inserts them before WI + let ltmSnippets = SimilarityUtils.getMemForLastResponse(localsettings.memsnippet_numOfSnippets, localsettings.memsnippet_minSignificance, (maxctxlen - maxgenamt)) + if (ltmSnippets.length === 0) + { + console.log("No memory fragments found either as history is too short or no relevant content found") + } + else + { + console.log("Memory fragments", ltmSnippets) + let ltmContent = ltmSnippets.map(snippet => snippet.snippet).join("|") + wistr = `\n\n[Chat history: ${ltmContent}]\n\n` + wistr + } + } + // [LTM][END] + if(wi_insertlocation>0) { truncated_anote = wistr + truncated_anote; @@ -14495,7 +14523,7 @@ if(m_opps[i] && m_opps[i].trim()!="") { let m_opp = m_opps[i] + ": "; - fulltxt = replaceAll(fulltxt, m_opp, `` + escapeHtml(m_opp) + ``); + fulltxt = replaceAll(fulltxt, m_opp, `` + escapeHtml(m_opp) + ``); } } } @@ -15559,9 +15587,12 @@ document.getElementById("memory_tab").classList.remove("active"); document.getElementById("wi_tab").classList.remove("active"); document.getElementById("token_tab").classList.remove("active"); + document.getElementById("memsnippet_tab").classList.remove("active"); document.getElementById("memory_tab_container").classList.add("hidden"); document.getElementById("wi_tab_container").classList.add("hidden"); document.getElementById("token_tab_container").classList.add("hidden"); + document.getElementById("memsnippet_tab_container").classList.add("hidden"); + switch (newtab) { case 0: document.getElementById("memory_tab").classList.add("active"); @@ -15572,6 +15603,10 @@ document.getElementById("wi_tab_container").classList.remove("hidden"); break; case 2: + document.getElementById("memsnippet_tab").classList.add("active"); + document.getElementById("memsnippet_tab_container").classList.remove("hidden"); + break; + case 3: document.getElementById("token_tab").classList.add("active"); document.getElementById("token_tab_container").classList.remove("hidden"); break; @@ -15608,6 +15643,8 @@ start_editing_wi(); update_wi(); + load_memsnippet(); + populate_placeholder_tags(); populate_regex_replacers(); @@ -15912,6 +15949,26 @@ document.getElementById("wi_insertlocation").value = wi_insertlocation; } + function load_memsnippet() { + document.getElementById("memsnippet_enabled").checked = localsettings.memsnippet_enabled; + document.getElementById("memsnippet_numOfSnippets").value = localsettings.memsnippet_numOfSnippets; + document.getElementById("memsnippet_minSignificance").value = localsettings.memsnippet_minSignificance; + } + + function save_memsnippet() { + localsettings.memsnippet_enabled = (document.getElementById("memsnippet_enabled").checked ? true : false); + localsettings.memsnippet_numOfSnippets = document.getElementById("memsnippet_numOfSnippets").value; + localsettings.memsnippet_minSignificance = document.getElementById("memsnippet_minSignificance").value; + } + + function validateMemInput(input) + { + let notValid = !input?.validity?.valid; + document.getElementById("memoryOkButton").disabled = notValid; + document.getElementById("memoryOkButton").title = notValid ? `${input.title}: ${input.validationMessage}` : ""; + input.reportValidity(); + } + var backLongPressTimer = null; function btn_back_longpress_start() { @@ -18039,7 +18096,8 @@
@@ -18122,6 +18180,25 @@
+ +
+
+
Enable memory snippets
+ +
+ +
+
Amount of memory snippets to include ?Controls + how many snippets of text from the memory are included based on the automatic search
+ +
+
+
Minimum significance required for inclusion ?Controls + the minimum threshold for snippets to be included based on the automatic search, ranging from 0 (any significance) to 1, which is a high degree of significance
+ +
+
+
Extra Stopping Sequences ?Triggers the text generator to stop generating early if this sequence appears, in addition to default stop sequences. If you want multiple sequences, separate them with the following delimiter: ||$||
@@ -18197,7 +18274,7 @@
- +
@@ -18654,4 +18731,713 @@ } + + + + + + + + + + + + + + + + + + + + From 75d0b6ad9c4fff4fe00216dc04ccded1b11c2579 Mon Sep 17 00:00:00 2001 From: prima Date: Fri, 26 Jul 2024 21:22:03 +0100 Subject: [PATCH 2/4] refactor: Cleanup of formatting after merge / removal of old code (LTM) --- index.html | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/index.html b/index.html index b355ea4..546e25a 100644 --- a/index.html +++ b/index.html @@ -14523,7 +14523,7 @@ if(m_opps[i] && m_opps[i].trim()!="") { let m_opp = m_opps[i] + ": "; - fulltxt = replaceAll(fulltxt, m_opp, `` + escapeHtml(m_opp) + ``); + fulltxt = replaceAll(fulltxt, m_opp, `` + escapeHtml(m_opp) + ``); } } } @@ -19417,27 +19417,6 @@ } - - - From 2cce5b02df81bcd64e4aab65b394ef695f041b4b Mon Sep 17 00:00:00 2001 From: Eso <65901558+esolithe@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:59:05 +0100 Subject: [PATCH 3/4] feat: Improvements to snippet selection accuracy by incorportating minisearch and modifying search to use multiple differently prioritised segments --- index.html | 535 +++++++++++++++++------------------------------------ 1 file changed, 169 insertions(+), 366 deletions(-) diff --git a/index.html b/index.html index 0a5abb2..1cb9cf5 100644 --- a/index.html +++ b/index.html @@ -18931,73 +18931,25 @@ - - - - - + + + - - - - -