diff --git a/aiserver.py b/aiserver.py index 99ce3979..6962a378 100644 --- a/aiserver.py +++ b/aiserver.py @@ -1474,7 +1474,7 @@ def general_startup(override_args=None): parser.add_argument("--cacheonly", action='store_true', help="Does not save the model to the models folder when it has been downloaded in the cache") parser.add_argument("--customsettings", help="Preloads arguements from json file. You only need to provide the location of the json file. Use customsettings.json template file. It can be renamed if you wish so that you can store multiple configurations. Leave any settings you want as default as null. Any values you wish to set need to be in double quotation marks") parser.add_argument("--no_ui", action='store_true', default=False, help="Disables the GUI and Socket.IO server while leaving the API server running.") - parser.add_argument("--summarizer_model", action='store', default="philschmid/bart-large-cnn-samsum", help="Huggingface model to use for summarization. Defaults to sshleifer/distilbart-cnn-12-6") + parser.add_argument("--summarizer_model", action='store', default="pszemraj/led-large-book-summary", help="Huggingface model to use for summarization. Defaults to pszemraj/led-large-book-summary") parser.add_argument("--max_summary_length", action='store', default=75, help="Maximum size for summary to send to image generation") parser.add_argument("--multi_story", action='store_true', default=False, help="Allow multi-story mode (experimental)") parser.add_argument("--peft", type=str, help="Specify the path or HuggingFace ID of a Peft to load it. Not supported on TPU. (Experimental)") @@ -7650,16 +7650,19 @@ def get_items_locations_from_text(text): #==================================================================# def summarize(text, max_length=100, min_length=30, unload=True): from transformers import pipeline as summary_pipeline + from transformers import AutoConfig start_time = time.time() if koboldai_vars.summarizer is None: if os.path.exists("functional_models/{}".format(args.summarizer_model.replace('/', '_'))): koboldai_vars.summary_tokenizer = AutoTokenizer.from_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") koboldai_vars.summarizer = AutoModelForSeq2SeqLM.from_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") + koboldai_vars.summary_model_config = AutoConfig.from_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") else: koboldai_vars.summary_tokenizer = AutoTokenizer.from_pretrained(args.summarizer_model, cache_dir="cache") koboldai_vars.summarizer = AutoModelForSeq2SeqLM.from_pretrained(args.summarizer_model, cache_dir="cache") koboldai_vars.summary_tokenizer.save_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), max_shard_size="500MiB") koboldai_vars.summarizer.save_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), max_shard_size="500MiB") + koboldai_vars.summary_model_config = AutoConfig.from_pretrained(args.summarizer_model, cache_dir="cache") #Try GPU accel if koboldai_vars.hascuda and torch.cuda.get_device_properties(0).total_memory - torch.cuda.memory_reserved(0) >= 1645778560: @@ -7673,9 +7676,27 @@ def summarize(text, max_length=100, min_length=30, unload=True): #Actual sumarization start_time = time.time() #make sure text is less than 1024 tokens, otherwise we'll crash - if len(koboldai_vars.summary_tokenizer.encode(text)) > 1000: - text = koboldai_vars.summary_tokenizer.decode(koboldai_vars.summary_tokenizer.encode(text)[:1000]) - output = tpool.execute(summarizer, text, max_length=max_length, min_length=min_length, do_sample=False)[0]['summary_text'] + max_tokens = koboldai_vars.summary_model_config.max_encoder_position_embeddings if hasattr(koboldai_vars.summary_model_config, 'max_encoder_position_embeddings') else 1024 + logger.info("Using max summary tokens of {}".format(max_tokens)) + if len(koboldai_vars.summary_tokenizer.encode(text)) > max_tokens: + text_list = koboldai_vars.actions.sentence_re.findall(text) + i=0 + while i <= len(text_list)-2: + if len(koboldai_vars.summary_tokenizer.encode(text_list[i] + text_list[i+1])) < max_tokens: + text_list[i] = text_list[i] + text_list[i+1] + del text_list[i+1] + else: + i+=1 + + + else: + text_list = [text] + + output = [] + logger.info("Summarizing with {} chunks of length {}".format(len(text_list), [len(koboldai_vars.summary_tokenizer.encode(x)) for x in text_list])) + for text in text_list: + output.append(tpool.execute(summarizer, text, max_length=max_length, min_length=min_length, do_sample=False)[0]['summary_text']) + output = " ".join(output) logger.debug("Time to summarize: {}".format(time.time()-start_time)) #move model back to CPU to save precious vram torch.cuda.empty_cache() @@ -7695,40 +7716,33 @@ def summarize(text, max_length=100, min_length=30, unload=True): @socketio.on("refresh_auto_memory") @logger.catch def UI_2_refresh_auto_memory(data): + max_output_length=500 + from transformers import AutoConfig koboldai_vars.auto_memory = "Generating..." if koboldai_vars.summary_tokenizer is None: - if os.path.exists("models/{}".format(args.summarizer_model.replace('/', '_'))): - koboldai_vars.summary_tokenizer = AutoTokenizer.from_pretrained("models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") + if os.path.exists("functional_models/{}".format(args.summarizer_model.replace('/', '_'))): + koboldai_vars.summary_tokenizer = AutoTokenizer.from_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") + koboldai_vars.summary_model_config = AutoConfig.from_pretrained("functional_models/{}".format(args.summarizer_model.replace('/', '_')), cache_dir="cache") else: koboldai_vars.summary_tokenizer = AutoTokenizer.from_pretrained(args.summarizer_model, cache_dir="cache") - #first, let's get all of our game text and split it into sentences - sentences = [x[0] for x in koboldai_vars.actions.to_sentences()] - sentences_lengths = [len(koboldai_vars.summary_tokenizer.encode(x)) for x in sentences] + koboldai_vars.summary_model_config = AutoConfig.from_pretrained(args.summarizer_model, cache_dir="cache") + max_tokens = koboldai_vars.summary_model_config.max_encoder_position_embeddings if hasattr(koboldai_vars.summary_model_config, 'max_encoder_position_embeddings') else 1024 + + #first, let's get all of our game text + sentences = "".join([x[0] for x in koboldai_vars.actions.to_sentences()]) pass_number = 1 - while len(koboldai_vars.summary_tokenizer.encode("".join(sentences))) > 1000: - #Now let's split them into 1000 token chunks - summary_chunks = [""] - summary_chunk_lengths = [0] - for i in range(len(sentences)): - if summary_chunk_lengths[-1] + sentences_lengths[i] <= 1000: - summary_chunks[-1] += sentences[i] - summary_chunk_lengths[-1] += sentences_lengths[i] - else: - summary_chunks.append(sentences[i]) - summary_chunk_lengths.append(sentences_lengths[i]) - new_sentences = [] - i=0 - for summary_chunk in summary_chunks: - logger.debug("summarizing chunk {}".format(i)) - new_sentences.extend(re.split("(?<=[.!?])\s+", summarize(summary_chunk, unload=False))) - i+=1 + while len(koboldai_vars.summary_tokenizer.encode(sentences)) > max_tokens: + new_sentences = summarize(sentences, unload=False, max_length=max_output_length) logger.debug("Pass {}:\nSummarized to {} sentencees from {}".format(pass_number, len(new_sentences), len(sentences))) sentences = new_sentences - koboldai_vars.auto_memory += "Pass {}:\n{}\n\n".format(pass_number, "\n".join(sentences)) + koboldai_vars.auto_memory += "Pass {}:\n{}\n\n".format(pass_number, sentences) pass_number+=1 logger.debug("OK, doing final summarization") - output = summarize(" ".join(sentences)) + if len(koboldai_vars.summary_tokenizer.encode(sentences)) > max_output_length: + output = summarize(sentences, max_length=max_output_length) + else: + output = sentences koboldai_vars.auto_memory += "\n\n Final Result:\n" + output diff --git a/environments/huggingface.yml b/environments/huggingface.yml index 74229dbd..deead8e7 100644 --- a/environments/huggingface.yml +++ b/environments/huggingface.yml @@ -33,6 +33,7 @@ dependencies: - flask-cloudflared==0.0.10 - flask-ngrok - flask-cors + - Werkzeug==2.3.7 - lupa==1.10 - transformers[sentencepiece]==4.34.0 - huggingface_hub==0.16.4 diff --git a/environments/ipex.yml b/environments/ipex.yml index 944b8fa2..c9794e48 100644 --- a/environments/ipex.yml +++ b/environments/ipex.yml @@ -33,6 +33,7 @@ dependencies: - flask-cloudflared==0.0.10 - flask-ngrok - flask-cors + - Werkzeug==2.3.7 - lupa==1.10 - transformers[sentencepiece]==4.34.0 - huggingface_hub==0.16.4 diff --git a/environments/rocm.yml b/environments/rocm.yml index 83f9a48e..2a6043ea 100644 --- a/environments/rocm.yml +++ b/environments/rocm.yml @@ -29,6 +29,7 @@ dependencies: - flask-cloudflared==0.0.10 - flask-ngrok - flask-cors + - Werkzeug==2.3.7 - lupa==1.10 - transformers[sentencepiece]==4.34.0 - huggingface_hub==0.16.4 diff --git a/koboldai_settings.py b/koboldai_settings.py index 159031ea..afd7efc8 100644 --- a/koboldai_settings.py +++ b/koboldai_settings.py @@ -1247,9 +1247,9 @@ class undefined_settings(settings): class system_settings(settings): local_only_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'lua_koboldcore', 'regex_sl', 'acregex_ai', 'acregex_ui', 'comregex_ai', 'comregex_ui', - 'sp', '_horde_pid', 'inference_config', 'image_pipeline', + 'sp', '_horde_pid', 'inference_config', 'image_pipeline', 'summary_model_config', 'summarizer', 'summary_tokenizer', 'tts_model', 'rng_states', 'comregex_ai', 'comregex_ui', 'colab_arg'] - no_save_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', + no_save_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'summary_model_config', 'lua_koboldcore', 'sp', 'sp_length', '_horde_pid', 'horde_share', 'aibusy', 'serverstarted', 'inference_config', 'image_pipeline', 'summarizer', 'on_colab' 'summary_tokenizer', 'use_colab_tpu', 'noai', 'disable_set_aibusy', 'cloudflare_link', 'tts_model', @@ -1334,6 +1334,7 @@ class system_settings(settings): self.image_pipeline = None self.summarizer = None self.summary_tokenizer = None + self.summary_model_config = {} self.keep_img_gen_in_memory = False self.cookies = {} #cookies for colab since colab's URL changes, cookies are lost self.experimental_features = False diff --git a/requirements.txt b/requirements.txt index 2d17c5a5..8d6ac290 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ optimum[onnxruntime]==1.13.2 safetensors==0.3.3 Flask==2.3.3 Flask-SocketIO==5.3.2 +Werkzeug==2.3.7 python-socketio==5.7.2 requests torch == 2.0.* diff --git a/requirements_mtj.txt b/requirements_mtj.txt index a4466752..1e30b1cb 100644 --- a/requirements_mtj.txt +++ b/requirements_mtj.txt @@ -16,6 +16,7 @@ python-socketio==5.7.2 flask-cloudflared==0.0.10 flask-ngrok flask-cors +Werkzeug==2.3.7 eventlet==0.33.3 dnspython==2.2.1 lupa==1.10 diff --git a/static/klite.html b/static/klite.html index 9a4bca92..7e33d6fc 100644 --- a/static/klite.html +++ b/static/klite.html @@ -1,15 +1,13 @@ - @@ -2241,10 +2296,22 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } return str.replace(new RegExp(escapeRegExp(find), (caseInsensitive?'gi':'g')), replace); - - } + function rgbToHex(rgbColor) { + rgbColor = rgbColor.split("(")[1]; + rgbColor = rgbColor.split(")")[0]; + const components = rgbColor.split(','); + const red = parseInt(components[0]); + const green = parseInt(components[1]); + const blue = parseInt(components[2]); + const redHex = red.toString(16).padStart(2, '0'); + const greenHex = green.toString(16).padStart(2, '0'); + const blueHex = blue.toString(16).padStart(2, '0'); + return `#${redHex}${greenHex}${blueHex}`; + } + + function GetUniqueColor(idx) { switch(idx) @@ -2839,6 +2906,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob const default_oai_base = "https://api.openai.com"; const default_claude_base = "https://api.anthropic.com"; + const default_palm_base = "https://generativelanguage.googleapis.com/v1beta2/models/text-bison-001:generateText?key="; //support for quick news updates const news_endpoint = "https://news.concedo.workers.dev" @@ -2866,8 +2934,10 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob var pending_response_horde = text_hordes[0]; //the url to poll for pending response from a v2 submit var poll_in_progress = false; //are we currently waiting for a text generation var poll_ticks_passed = 0; //how much time passed after polling + var horde_poll_nearly_completed = false; //if true, increase polling rate var prev_hl_chunk = null; //will store the last highlighted element var pending_context_preinjection = ""; //this will be injected before the AI's next RESPONSE + var last_reply_was_empty = false; //set to true if last reply is empty var current_memory = ""; //stored memory var current_anote = ""; //stored author note var current_anotetemplate = "[Author\'s note: <|>]"; @@ -2887,6 +2957,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob var custom_oai_key = ""; //if set, uses the OpenAI API to generate var custom_oai_model = ""; var custom_scale_key = ""; + var custom_palm_key = ""; var custom_scale_ID = ""; var custom_claude_endpoint = default_claude_base; var custom_claude_key = ""; @@ -2905,6 +2976,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob var kobold_endpoint_version = ""; //used to track problematic versions to avoid sending extra fields var koboldcpp_version = ""; //detect if we are using koboldcpp var last_request_str = "No Requests Available"; //full context of last submitted request + var lastcheckgenkey = ""; //for checking polled-streaming unique id when generating in kcpp var localsettings = { my_api_key: "0000000000", //put here so it can be saved and loaded in persistent mode @@ -2914,11 +2986,12 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob saved_claude_key: "", //do not ever share this in save files! saved_claude_addr: "", //do not ever share this in save files! saved_oai_jailbreak: "", //customized oai system prompt + saved_palm_key: "", autoscroll: true, //automatically scroll to bottom on render trimsentences: true, //trim to last punctuation trimwhitespace: false, //trim trailing whitespace - unban_tokens: false, //allow the EOS token when using locally + eos_ban_mode: 0, //allow the EOS token when using locally 0=auto,1=unban,2=ban opmode: 1, //what mode are we in? 1=story, 2=adventure, 3=chat, 4=instruct adventure_is_action: false, //in adventure mode, determine story or action adventure_context_mod: true, //extra injection for adventure mode @@ -2927,12 +3000,13 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob instruct_starttag: "\\n### Instruction:\\n", instruct_endtag: "\\n### Response:\\n", instruct_has_markdown: false, - raw_instruct_tags: false, + placeholder_tags: true, persist_session: true, speech_synth: 0, //0 is disabled beep_on: false, image_styles: "", grammar:"", + tokenstreaming: (localflag?true:false), generate_images: (localflag?"":"stable_diffusion"), //"" is disabled and "*" is all, anything else is the model name pulled from stable horde img_autogen: false, img_allownsfw: true, @@ -3072,12 +3146,6 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } } - const tokenstreaming = urlParams.get('streaming'); - if(tokenstreaming) - { - document.getElementById("tokenstreaming").checked = true; - } - const fromfile = ( window.location.protocol == 'file:' ); if(!dbgmode && !fromfile){ if(!window.console) window.console = {}; @@ -3112,6 +3180,12 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob console.log("Discarded invalid local save: " + e); } + const tokenstreaming = urlParams.get('streaming'); + if(tokenstreaming) + { + localsettings.tokenstreaming = true; + } + //toggle genimg btn if (localsettings.generate_images) { document.getElementById("btn_genimg").classList.remove("hidden"); @@ -3431,7 +3505,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob function is_using_custom_ep() { - return (custom_oai_key!=""||custom_kobold_endpoint!=""||custom_scale_key!=""||custom_claude_key!=""); + return (custom_oai_key!=""||custom_kobold_endpoint!=""||custom_scale_key!=""||custom_claude_key!=""||custom_palm_key!=""); } function is_using_kcpp_with_streaming() @@ -3450,7 +3524,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob //0 is none, 1 is pseudostreaming, 2 is true streaming function determine_streaming_type() { - let streamtype = (document.getElementById("tokenstreaming").checked ? 1 : 0); + let streamtype = (localsettings.tokenstreaming ? 1 : 0); let pstreamamount = urlParams.get('streamamount'); if(streamtype==1 && is_using_kcpp_with_streaming() && (pstreamamount == null || pstreamamount <= 0)) { @@ -3464,6 +3538,27 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob return streamtype; } + function determine_if_ban_eos(input_was_empty) { + if (localsettings.eos_ban_mode == 0) { + if (localsettings.opmode == 1) { + return true; //story mode always ban + } + else if (localsettings.opmode == 3 && !localsettings.allow_continue_chat) { + return false; //chat mode always unban unless cont allowed + } + else if (!input_was_empty) //if user input is not empty, ALWAYS unban EOS. + { + return false; + } + else { + return last_reply_was_empty; + } + } + else { + return (localsettings.eos_ban_mode == 2 ? true : false); + } + } + function is_using_web_lite() { return (window.location.hostname.includes("koboldai.net") || window.location.hostname.includes("kaihordewebui.github.io")); @@ -3644,6 +3739,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob let tmp_oai2 = localsettings.saved_oai_addr; let tmp_claude1 = localsettings.saved_claude_key; let tmp_claude2 = localsettings.saved_claude_addr; + let tmp_palm1 = localsettings.saved_palm_key; import_props_into_object(localsettings, story.savedsettings); localsettings.my_api_key = tmpapikey1; localsettings.home_cluster = tmphc; @@ -3651,6 +3747,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob localsettings.saved_oai_addr = tmp_oai2; localsettings.saved_claude_key = tmp_claude1; localsettings.saved_claude_addr = tmp_claude2; + localsettings.saved_palm_key = tmp_palm1; } if (story.savedaestheticsettings && story.savedaestheticsettings != "") { @@ -3959,6 +4056,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob let tmp_oai2 = localsettings.saved_oai_addr; let tmp_claude1 = localsettings.saved_claude_key; let tmp_claude2 = localsettings.saved_claude_addr; + let tmp_palm1 = localsettings.saved_palm_key; import_props_into_object(localsettings, loaded_storyobj.savedsettings); localsettings.my_api_key = tmpapikey1; localsettings.home_cluster = tmphc; @@ -3966,6 +4064,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob localsettings.saved_oai_addr = tmp_oai2; localsettings.saved_claude_key = tmp_claude1; localsettings.saved_claude_addr = tmp_claude2; + localsettings.saved_palm_key = tmp_palm1; //backwards compat support for newlines if(localsettings.instruct_has_newlines==true || (loaded_storyobj.savedsettings != null && loaded_storyobj.savedsettings.instruct_has_newlines==null&&loaded_storyobj.savedsettings.instruct_has_markdown==null)) @@ -4030,6 +4129,25 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob render_gametext(); } + function load_agnai_wi(obj,chatopponent,myname) + { + console.log("Append Agnai WI"); + current_wi = []; + for (let key in obj.entries) { + var itm = obj.entries[key]; + var karr = itm.keywords; + let nwi = { + "key": karr.join(","), + "keysecondary": "", + "content": itm.entry, + "comment": "", + "folder": null, + "selective": false, + "constant": false + }; + current_wi.push(nwi); + } + } function load_tavern_wi(obj,chatopponent,myname) { console.log("Append Tavern WI"); @@ -4048,7 +4166,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } let nwi = { "key": karr.join(","), - "keysecondary": (ksarr.length > 0 ? ksarr.join(",") : ""), + "keysecondary": ((ksarr && ksarr.length) > 0 ? ksarr.join(",") : ""), "content": itm.content, "comment": itm.comment, "folder": null, @@ -4083,11 +4201,16 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob examplemsg = "\n"+examplemsg; } let combinedmem = memory + scenario + examplemsg; + let agnaidatafieldsempty = scenario + examplemsg + (obj.personality?obj.personality:"") + greeting; //check if it's a world info only card, if so, do not restart game if(combinedmem.trim()=="" && greeting=="" && obj.entries) { load_tavern_wi(obj,chatopponent,myname); } + else if(agnaidatafieldsempty.trim()=="" && obj.entries && obj.kind=="memory") + { + load_agnai_wi(obj,chatopponent,myname); + } else { restart_new_game(); @@ -4102,6 +4225,10 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob { load_tavern_wi(obj.character_book,chatopponent,myname); } + else if(obj.entries && obj.entries.length>0) + { + load_agnai_wi(obj,chatopponent,myname); + } } render_gametext(); } @@ -4288,13 +4415,26 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob //load contexts gametext_arr = []; if (temp_scenario.prompt != "") { - gametext_arr.push(temp_scenario.prompt); + let prompttxt = temp_scenario.prompt; + if(!localsettings.placeholder_tags) //do a one-time replace instead + { + prompttxt = replace_placeholders_direct(prompttxt); + } + gametext_arr.push(prompttxt); } if (temp_scenario.authorsnote != "") { current_anote = temp_scenario.authorsnote; + if(!localsettings.placeholder_tags) + { + current_anote = replace_placeholders_direct(current_anote); + } } if (temp_scenario.memory != "") { current_memory = temp_scenario.memory; + if(!localsettings.placeholder_tags) + { + current_memory = replace_placeholders_direct(current_memory); + } } if (temp_scenario.worldinfo && temp_scenario.worldinfo.length > 0) { current_wi = []; @@ -4360,8 +4500,6 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob if (temp_scenario.instruct_endtag) { localsettings.instruct_endtag = temp_scenario.instruct_endtag; } } - - render_gametext(); } function togglescenarioallownsfw() @@ -4419,7 +4557,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob { scenarioautopickai = true; //no selected model, pick a good one } - if (scenarioautopickai && !localflag) + if (scenarioautopickai && !localflag && !is_using_custom_ep()) { fetch_models((mdls) => { @@ -4429,7 +4567,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } else { - let nsfwmodels = ["erebus","shinen","horni","litv2","lit-6b"]; + let nsfwmodels = ["erebus","shinen","horni","litv2","lit-6b","spicyboros","mlewd"]; selected_models = []; for (var i = 0; i < mdls.length; ++i) { for (var j = 0; j < temp_scenario.prefmodel1.length; ++j) { @@ -4627,6 +4765,15 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } } } + + function format_uptime(seconds) + { + const days = Math.floor(seconds / (3600 * 24)); + const hours = Math.floor((seconds % (3600 * 24)) / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + return days+"d "+hours+"h "+minutes+"m"; + } + function show_workers() { document.getElementById("workercontainer").classList.remove("hidden"); @@ -4653,7 +4800,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob allmdls += escapeHtml(elem.models[n].substring(0, 32)); } - str += "" + workerNameHtml + "" + allmdls + "" + elem.max_length + " / " + elem.max_context_length + "
(" + tokenspersec + " T/s)" + elem.uptime + "
(" + elem.requests_fulfilled + " jobs)" + elem.kudos_rewards.toFixed(0) + ""+clustertag+""; + str += "" + workerNameHtml + "" + allmdls + "" + elem.max_length + " / " + elem.max_context_length + "
(" + tokenspersec + " T/s)" + format_uptime(elem.uptime) + "
(" + elem.requests_fulfilled + " jobs)" + elem.kudos_rewards.toFixed(0) + ""+clustertag+""; } document.getElementById("workertable").innerHTML = str; document.getElementById("worktitlecount").innerText = "Worker List - Total " + worker_data_showonly.length; @@ -4681,7 +4828,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob let brokenstyle = (elem.maintenance_mode ? "style=\"color:#ee4444;\"" : ""); let workerNameHtml = escapeHtml(elem.name.substring(0, 32)); let eleminfo = ((elem.info && elem.info!="")?elem.info:""); - str += "" + workerNameHtml + "" + elem.uptime + "
(" + elem.requests_fulfilled + " jobs)" + elem.kudos_rewards.toFixed(0) + ""+(elem.online?"Online":"Offline")+""; + str += "" + workerNameHtml + "" + format_uptime(elem.uptime) + "
(" + elem.requests_fulfilled + " jobs)" + elem.kudos_rewards.toFixed(0) + ""+(elem.online?"Online":"Offline")+""; } document.getElementById("myownworkertable").innerHTML = str; @@ -4881,6 +5028,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob document.getElementById("koboldcustom").classList.add("hidden"); document.getElementById("scalecustom").classList.add("hidden"); document.getElementById("claudecustom").classList.add("hidden"); + document.getElementById("palmcustom").classList.add("hidden"); if(epchoice==0) { document.getElementById("koboldcustom").classList.remove("hidden"); @@ -4917,6 +5065,14 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } } } + else if(epchoice==4) + { + document.getElementById("palmcustom").classList.remove("hidden"); + if(custom_palm_key=="" && localsettings.saved_palm_key!="") + { + document.getElementById("custom_palm_key").value = localsettings.saved_palm_key; + } + } } @@ -4926,6 +5082,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob custom_oai_key = ""; custom_scale_key = ""; custom_claude_key = ""; + custom_palm_key = ""; let epchoice = document.getElementById("customapidropdown").value; if(epchoice==0) //connect to kobold endpoint @@ -5076,6 +5233,10 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob selected_models = []; selected_workers = []; custom_kobold_endpoint = ""; + if(localflag) + { + document.getElementById("connectstatus").innerHTML = "Offline Mode"; + } render_gametext(); } else { uses_cors_proxy = true; //fallback to cors proxy, this will remain for rest of session @@ -5098,8 +5259,11 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob { desired_oai_ep = desired_oai_ep.slice(0, -1); } - if(desired_oai_ep!="" && desired_oai_ep.length > 4 && !desired_oai_ep.slice(-4).toLowerCase().includes("/v")) { - desired_oai_ep = desired_oai_ep + "/v1"; + if (document.getElementById("oaiaddversion").checked) + { + if(desired_oai_ep!="" && desired_oai_ep.length > 4 && !desired_oai_ep.slice(-4).toLowerCase().includes("/v")) { + desired_oai_ep = desired_oai_ep + "/v1"; + } } if(desired_oai_key!="" && desired_oai_ep!="") { @@ -5242,8 +5406,11 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob { desired_claude_ep = desired_claude_ep.slice(0, -1); } - if(desired_claude_ep!="" && desired_claude_ep.length > 4 && !desired_claude_ep.slice(-4).toLowerCase().includes("/v")) { - desired_claude_ep = desired_claude_ep + "/v1"; + if (document.getElementById("claudeaddversion").checked) + { + if (desired_claude_ep != "" && desired_claude_ep.length > 4 && !desired_claude_ep.slice(-4).toLowerCase().includes("/v")) { + desired_claude_ep = desired_claude_ep + "/v1"; + } } if(desired_claude_key!="" && desired_claude_ep!="") { @@ -5283,6 +5450,37 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } } + else if(epchoice==4) //palm endpoint + { + let desired_palm_key = document.getElementById("custom_palm_key").value.trim(); + + if(desired_palm_key!="") + { + hide_popups(); + + //good to go + custom_palm_key = desired_palm_key; + localsettings.saved_palm_key = custom_palm_key; + + selected_models = [{ "performance": 100.0, "queued": 0.0, "eta": 0, "name": "text-bison-001", "count": 1 }]; + selected_workers = []; + if (perfdata == null) { + //generate some fake perf data if horde is offline and using custom endpoint + perfdata = { + "queued_requests": 0, + "queued_tokens": 0, + "past_minute_tokens": 0, + "worker_count": 0 + }; + document.body.classList.add("connected"); + document.getElementById("connectstatus").classList.remove("color_orange"); + document.getElementById("connectstatus").classList.add("color_green"); + } + document.getElementById("connectstatus").innerHTML = "Connected to PaLM Endpoint"; + render_gametext(); + } + } + } function display_custom_endpoint() @@ -5440,6 +5638,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob custom_oai_key = ""; custom_scale_key = ""; custom_claude_key = ""; + custom_palm_key = ""; //remove the Custom Endpoint if it's multi selected together with others. const findex = selected_idx_arr.indexOf("9999"); if (findex > -1) { @@ -5695,11 +5894,12 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob document.getElementById("invert_colors").checked = localsettings.invert_colors; document.getElementById("trimsentences").checked = localsettings.trimsentences; document.getElementById("trimwhitespace").checked = localsettings.trimwhitespace; - document.getElementById("unban_tokens").checked = localsettings.unban_tokens; + document.getElementById("eos_ban_mode").value = localsettings.eos_ban_mode; document.getElementById("persist_session").checked = localsettings.persist_session; document.getElementById("opmode").value = localsettings.opmode; document.getElementById("chatname").value = localsettings.chatname; - document.getElementById("chatopponent").value = localsettings.chatopponent; + document.getElementById("chatopponent").value = replaceAll(localsettings.chatopponent,"||$||","\n"); + handle_bot_name_onchange(); document.getElementById("instruct_starttag").value = localsettings.instruct_starttag; document.getElementById("instruct_endtag").value = localsettings.instruct_endtag; document.getElementById("top_k").value = localsettings.top_k; @@ -5721,6 +5921,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob } document.getElementById("setgrammar").disabled = !is_using_kcpp_with_grammar(); + document.getElementById("grammar_retain_state").disabled = document.getElementById("setgrammar").disabled; if(custom_kobold_endpoint!="") { @@ -5737,7 +5938,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob document.getElementById("idle_duration").value = localsettings.idle_duration; document.getElementById("adventure_context_mod").checked = localsettings.adventure_context_mod; document.getElementById("instruct_has_markdown").checked = localsettings.instruct_has_markdown; - document.getElementById("raw_instruct_tags").checked = localsettings.raw_instruct_tags; + document.getElementById("placeholder_tags").checked = localsettings.placeholder_tags; document.getElementById("auto_ctxlen").checked = localsettings.auto_ctxlen; document.getElementById("auto_genamt").checked = localsettings.auto_genamt; if(localflag) @@ -5786,6 +5987,7 @@ Kobold Lite is under the AGPL v3.0 License for the purposes of koboldcpp and Kob sdmodelshtml += "