@@ -12,7 +12,7 @@ Current version indicated by LITEVER below.
1212-->
1313
1414<script>
15- const LITEVER = 197 ;
15+ const LITEVER = 198 ;
1616 const urlParams = new URLSearchParams(window.location.search);
1717 var localflag = true;
1818 const STORAGE_PREFIX = (localflag?"e_":"")+"kaihordewebui_";
@@ -3203,6 +3203,22 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
32033203 }
32043204 }
32053205
3206+ function removeAndReplacePlaceholders(text) {
3207+ // Replace {{user}} and other placeholders
3208+ text = replace_placeholders(text);
3209+
3210+ // Remove any instruct tags as needed to ensure a more accurate search
3211+ text = replaceAll(text, get_instruct_starttag(false), "");
3212+ text = replaceAll(text, get_instruct_endtag(false), "");
3213+ text = replaceAll(text, get_instruct_systag(false), "");
3214+ text = replaceAll(text, get_instruct_starttag(false).trim(), "");
3215+ text = replaceAll(text, get_instruct_endtag(false).trim(), "");
3216+ text = replaceAll(text, get_instruct_systag(false).trim(), "");
3217+ text = text.replace(/\{\{\[INPUT\]\}\}/g, "").replace(/\{\{\[OUTPUT\]\}\}/g, "");
3218+
3219+ return text;
3220+ }
3221+
32063222 function readTavernPngFromBlob(blob, onDone)
32073223 {
32083224 var fileReader = new FileReader();
@@ -4177,6 +4193,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
41774193 const koboldcpp_transcribe_endpoint = "/api/extra/transcribe";
41784194 const koboldcpp_tokenize_endpoint = "/api/extra/tokencount";
41794195 const koboldcpp_perf_endpoint = "/api/extra/perf";
4196+ const koboldcpp_websearch_endpoint = "/api/extra/websearch"
41804197
41814198 const oai_models_endpoint = "/models";
41824199 const oai_submit_endpoint = "/completions";
@@ -4278,6 +4295,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
42784295 var documentdb_searchrange = 300;
42794296 var documentdb_chunksize = 800;
42804297 var documentdb_data = "";
4298+ var websearch_enabled = false;
42814299 var generateimagesinterval = 750; //if generated images is enabled, it will trigger after every 700 new characters in context.
42824300 var nextgeneratedimagemilestone = generateimagesinterval; //used to keep track of when to generate the next image
42834301 var image_db = {}; //stores a dictionary of pending images
@@ -4319,6 +4337,9 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
43194337 var koboldcpp_version_obj = {};
43204338 var koboldcpp_has_vision = false;
43214339 var koboldcpp_has_multiplayer = false;
4340+ var koboldcpp_has_websearch = false;
4341+ var lastSearchQuery = "";
4342+ var lastSearchResults = [];
43224343 var multiplayer_active = false;
43234344 var multiplayer_pinged = false;
43244345 var multiplayer_override_name = "";
@@ -5927,6 +5948,10 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
59275948 {
59285949 return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.78") >= 0 && koboldcpp_has_multiplayer);
59295950 }
5951+ function is_using_kcpp_with_websearch()
5952+ {
5953+ return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.80") >= 0 && koboldcpp_has_websearch);
5954+ }
59305955
59315956
59325957 //0 is none, 1 is poll-streaming, 2 is sse-streaming
@@ -6416,6 +6441,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
64166441 new_save_storyobj.documentdb_searchrange = documentdb_searchrange;
64176442 new_save_storyobj.documentdb_chunksize = documentdb_chunksize;
64186443 new_save_storyobj.documentdb_data = documentdb_data;
6444+ new_save_storyobj.websearch_enabled = websearch_enabled;
64196445
64206446 if (export_settings) {
64216447 new_save_storyobj.savedsettings = JSON.parse(JSON.stringify(localsettings));
@@ -6723,6 +6749,10 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
67236749 {
67246750 documentdb_data = storyobj.documentdb_data;
67256751 }
6752+ if(storyobj.websearch_enabled)
6753+ {
6754+ websearch_enabled = storyobj.websearch_enabled;
6755+ }
67266756 } else {
67276757 //v2 load
67286758 if(storyobj.prompt != "")
@@ -9492,6 +9522,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
94929522 koboldcpp_has_vision = (data.vision?true:false);
94939523 koboldcpp_has_whisper = (data.transcribe?true:false);
94949524 koboldcpp_has_multiplayer = (data.multiplayer?true:false);
9525+ koboldcpp_has_websearch = (data.websearch?true:false);
94959526 let has_password = (data.protected?true:false);
94969527 let has_txt2img = (data.txt2img?true:false);
94979528 let no_txt_model = (mdlname=="inactive");
@@ -11381,6 +11412,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1138111412 documentdb_searchrange = cleannum(documentdb_searchrange,0,1024);
1138211413 documentdb_chunksize = parseInt(documentdb_chunksize);
1138311414 documentdb_chunksize = cleannum(documentdb_chunksize,32,2048);
11415+ websearch_enabled = document.getElementById("websearch_enabled").checked?true:false;
1138411416 }
1138511417
1138611418 function set_personal_notes()
@@ -11638,6 +11670,7 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1163811670 documentdb_searchrange = 300;
1163911671 documentdb_chunksize = 800;
1164011672 documentdb_data = "";
11673+ websearch_enabled = false;
1164111674 }
1164211675 warn_on_quit = false;
1164311676 show_corpo_leftpanel(false);
@@ -12674,10 +12707,19 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1267412707 return Math.max(1, Math.floor(((maxctxlen - maxgenamt)) * chars_per_token) - 12);
1267512708 }
1267612709
12677- function submit_generation()
12710+ function submit_generation() //wrap websearch into this
12711+ {
12712+ let senttext = document.getElementById("input_text").value;
12713+ document.getElementById("input_text").value = "";
12714+ PerformWebsearch(senttext,(res)=>{
12715+ submit_generation_post_search(senttext);
12716+ });
12717+ }
12718+
12719+ function submit_generation_post_search(senttext)
1267812720 {
1267912721 warn_on_quit = true;
12680- let newgen = document.getElementById("input_text").value ;
12722+ let newgen = senttext ;
1268112723 let img_gen_trigger_prompt = "";
1268212724 let doNotGenerate = false;
1268312725 retry_in_progress = false;
@@ -12813,7 +12855,6 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1281312855 retry_prev_text = [];
1281412856 retry_preserve_last = true; //initially set to true
1281512857 redo_prev_text = [];
12816- document.getElementById("input_text").value = "";
1281712858 pending_response_id = "-1";
1281812859
1281912860 let mtl = document.getElementById("maintxtloader");
@@ -13158,14 +13199,25 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1315813199 }
1315913200 }
1316013201
13161- // TextDocuDB Long term memory minisearch
13202+ //use newest websearch results
13203+ if (websearch_enabled && is_using_kcpp_with_websearch() && lastSearchResults && lastSearchResults.length>0)
13204+ {
13205+ for(let i=0;i<lastSearchResults.length;++i)
13206+ {
13207+ let sresult = lastSearchResults[i];
13208+ let snippet = `\n[Search Snippet: ${sresult.title}\nSource: ${sresult.url}\nExcerpt: ${((sresult.content && sresult.content!="")?sresult.content:sresult.desc)}]`;
13209+ wistr = snippet + wistr;
13210+ }
13211+ }
13212+
13213+ // TextDB Long term memory minisearch
1316213214 if (documentdb_enabled)
1316313215 {
1316413216 // Finds the relevant memory fragments, formats them in a similar way to an authors note and inserts them before WI
1316513217 const ltmSearchQuery = !!rawNewText ? rawNewText : gametext_arr.length > 0 ? gametext_arr.slice(-1)[0] : undefined;
1316613218 if(ltmSearchQuery)
1316713219 {
13168- let gameText = concat_gametext().replace(/\xA0/g, ' ').trim();
13220+ let gameText = concat_gametext(true ).replace(/\xA0/g, ' ').trim();
1316913221 let maxAllowedCharacters = getMaxAllowedCharacters(gameText, maxctxlen, maxgenamt);
1317013222 if (documentdb_data!="" || gameText.length > maxAllowedCharacters)
1317113223 {
@@ -17732,10 +17784,12 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1773217784 memory_tab = newtab;
1773317785 document.getElementById("memory_tab").classList.remove("active");
1773417786 document.getElementById("wi_tab").classList.remove("active");
17787+ document.getElementById("websearch_tab").classList.remove("active");
1773517788 document.getElementById("token_tab").classList.remove("active");
1773617789 document.getElementById("documentdb_tab").classList.remove("active");
1773717790 document.getElementById("memory_tab_container").classList.add("hidden");
1773817791 document.getElementById("wi_tab_container").classList.add("hidden");
17792+ document.getElementById("websearch_tab_container").classList.add("hidden");
1773917793 document.getElementById("token_tab_container").classList.add("hidden");
1774017794 document.getElementById("documentdb_tab_container").classList.add("hidden");
1774117795
@@ -17753,6 +17807,10 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1775317807 document.getElementById("documentdb_tab_container").classList.remove("hidden");
1775417808 break;
1775517809 case 3:
17810+ document.getElementById("websearch_tab").classList.add("active");
17811+ document.getElementById("websearch_tab_container").classList.remove("hidden");
17812+ break;
17813+ case 4:
1775617814 document.getElementById("token_tab").classList.add("active");
1775717815 document.getElementById("token_tab_container").classList.remove("hidden");
1775817816 break;
@@ -17795,6 +17853,15 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1779517853 document.getElementById("documentdb_searchrange").value = documentdb_searchrange;
1779617854 document.getElementById("documentdb_chunksize").value = documentdb_chunksize;
1779717855 document.getElementById("documentdb_data").value = documentdb_data;
17856+ document.getElementById("websearch_enabled").checked = websearch_enabled;
17857+ if(is_using_kcpp_with_websearch())
17858+ {
17859+ document.getElementById("websearchunsupporteddiv").classList.add("hidden");
17860+ }
17861+ else
17862+ {
17863+ document.getElementById("websearchunsupporteddiv").classList.remove("hidden");
17864+ }
1779817865
1779917866 populate_placeholder_tags();
1780017867 populate_regex_replacers();
@@ -18966,7 +19033,68 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1896619033 document.getElementById('aesthetic_text_preview').innerHTML = render_aesthetic_ui(preview,true);
1896719034 }
1896819035
18969- //LTM TextDocuDB Memsnipper searching
19036+ function PerformWebsearch(webSearchQuery, onDone)
19037+ {
19038+ //websearch
19039+ if (websearch_enabled && is_using_kcpp_with_websearch())
19040+ {
19041+ webSearchQuery = webSearchQuery.trim();
19042+ if(webSearchQuery=="")
19043+ {
19044+ webSearchQuery = (gametext_arr.length > 0 ? gametext_arr.slice(-1)[0] : "");
19045+ }
19046+ webSearchQuery = removeAndReplacePlaceholders(webSearchQuery);
19047+ webSearchQuery = webSearchQuery.trim();
19048+ webSearchQuery = webSearchQuery.replace(/(?:\r\n|\r|\n)/g, '. ');
19049+ if(webSearchQuery==lastSearchQuery || webSearchQuery=="")
19050+ {
19051+ onDone(); //use cached results
19052+ }
19053+ else
19054+ {
19055+ if(pending_response_id=="")
19056+ {
19057+ pending_response_id = "-1";
19058+ render_gametext(false);
19059+ }
19060+ let murl = `${custom_kobold_endpoint}${koboldcpp_websearch_endpoint}`;
19061+ murl = apply_proxy_url(murl);
19062+ fetch(murl, {
19063+ method: 'POST',
19064+ headers: get_kobold_header(),
19065+ body: JSON.stringify({q: webSearchQuery}),
19066+ })
19067+ .then(x => x.json())
19068+ .then(values => {
19069+ lastSearchQuery = webSearchQuery;
19070+ lastSearchResults = values;
19071+ if(pending_response_id=="-1")
19072+ {
19073+ pending_response_id = "";
19074+ }
19075+ onDone();
19076+ })
19077+ .catch(error => {
19078+ console.log("WebSearch Error: " + error);
19079+ lastSearchResults = [];
19080+ lastSearchQuery = "";
19081+ if(pending_response_id=="-1")
19082+ {
19083+ pending_response_id = "";
19084+ }
19085+ onDone();
19086+ });
19087+ }
19088+ }
19089+ else
19090+ {
19091+ lastSearchResults = [];
19092+ lastSearchQuery = "";
19093+ onDone();
19094+ }
19095+ }
19096+
19097+ //LTM TextDB Memsnipper searching
1897019098 //searches dbText for searchStr and recentTextStr, returns up to 3 results
1897119099 function DatabaseMinisearch(dbText, searchStr, recentTextStr)
1897219100 { //predefined minisearch constants
@@ -19048,6 +19176,12 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
1904819176 let paragraphs = [];
1904919177 let allText = cleanupSpecialTags(dbText);
1905019178 allText = replaceAll(allText,recentTextStr,"");
19179+
19180+ // Ensure placeholders are replaced to allow searching for user / character
19181+ allText = removeAndReplacePlaceholders(allText)
19182+ searchStr = removeAndReplacePlaceholders(searchStr)
19183+ recentTextStr = removeAndReplacePlaceholders(recentTextStr)
19184+
1905119185 let i = 0, startLoc = 0;
1905219186 while (startLoc < allText.length && i < Number.MAX_SAFE_INTEGER) {
1905319187 let actualChunkStart = Math.max(0, startLoc - chunkSizeOverlap);
@@ -20699,8 +20833,9 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
2069920833 <div><ul class="nav nav-tabs settingsnav">
2070020834 <li id="memory_tab" class="active"><a class="" href="#" onclick="display_memory_tab(0)">Memory</a></li>
2070120835 <li id="wi_tab"><a class="" href="#" onclick="display_memory_tab(1)">World Info</a></li>
20702- <li id="documentdb_tab"><a class="" href="#" onclick="display_memory_tab(2)">TextDocuDB</a></li>
20703- <li id="token_tab"><a class="" href="#" onclick="display_memory_tab(3)">Tokens</a></li>
20836+ <li id="documentdb_tab"><a class="" href="#" onclick="display_memory_tab(2)">TextDB</a></li>
20837+ <li id="websearch_tab"><a class="" href="#" onclick="display_memory_tab(3)">WebSearch</a></li>
20838+ <li id="token_tab"><a class="" href="#" onclick="display_memory_tab(4)">Tokens</a></li>
2070420839 </ul></div>
2070520840
2070620841 <div class="memtabcontainer" id="memory_tab_container">
@@ -20785,10 +20920,10 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
2078520920 </div>
2078620921
2078720922 <div class="memtabcontainer" id="documentdb_tab_container">
20788- <div class="settinglabel" style="padding: 4px;">Automatically search and include relevant snippets from uploaded documents or history.</div>
20923+ <div class="settinglabel" style="padding: 4px;">Automatically search and include relevant snippets from a text document or history.</div>
2078920924 <div class="settinglabel" style="padding: 4px;">
20790- <div class="justifyleft settingsmall" title="Enable TextDocuDB ">Enable TextDocuDB </div>
20791- <input title="Enable TextDocuDB " type="checkbox" id="documentdb_enabled" style="margin:0px 0 0;">
20925+ <div class="justifyleft settingsmall" title="Enable TextDB ">Enable TextDB </div>
20926+ <input title="Enable TextDB " type="checkbox" id="documentdb_enabled" style="margin:0px 0 0;">
2079220927 </div>
2079320928
2079420929 <div class="settinglabel" style="padding: 4px;">
@@ -20821,11 +20956,20 @@ pre code,td,th{padding:0}pre code,table{background-color:transparent}.table,inpu
2082120956 min="0" step="1" pattern="\d+" placeholder="" value="" id="documentdb_chunksize">
2082220957 </div>
2082320958 <div class="settinglabel">
20824- <div class="justifyleft"><br>TextDocuDB Storage<span class="helpicon">?<span
20825- class="helptext">Paste as much raw text data here as you like. E.g. background information, reference documents, etc. This text will populate the database that will be chunked and searched by TextDocuDB.</span></span></div>
20959+ <div class="justifyleft"><br>TextDB Storage<span class="helpicon">?<span
20960+ class="helptext">Paste as much raw text data here as you like. E.g. background information, reference documents, etc. This text will populate the database that will be chunked and searched by TextDB.</span></span></div>
20961+ </div>
20962+ <textarea title="Edit TextDB" class="form-control" id="documentdb_data" style="height: 120px;"
20963+ placeholder="Paste as much text data here as you like. This text will populate the database that will be searched by TextDB."></textarea>
20964+ </div>
20965+
20966+ <div class="memtabcontainer" id="websearch_tab_container">
20967+ <div class="settinglabel" style="padding: 4px;">Search the Web for relavant information when using instruct mode<br>(Requires WebSearch enabled KoboldCpp)</div>
20968+ <div id="websearchunsupporteddiv" class="color_red hidden" style="font-weight:bold;padding:3px;font-size:12px">WebSearch Not Supported</div>
20969+ <div class="settinglabel" style="padding: 4px;">
20970+ <div class="justifyleft settingsmall" title="Enable WebSearch">Enable WebSearch </div>
20971+ <input title="Enable WebSearch" type="checkbox" id="websearch_enabled" style="margin:0px 0 0;">
2082620972 </div>
20827- <textarea title="Edit TextDocuDB" class="form-control" id="documentdb_data" style="height: 120px;"
20828- placeholder="Paste as much text data here as you like. This text will populate the database that will be searched by TextDocuDB."></textarea>
2082920973 </div>
2083020974
2083120975 <div class="memtabcontainer" id="token_tab_container">
0 commit comments