diff --git a/.gitignore b/.gitignore index ff83d6e7..8a6b218c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ client.settings # Ignore stories file except for test_story stories/* -!stories/sample_story.json \ No newline at end of file +!stories/sample_story.json +/.project diff --git a/UPDATE YOUR COLAB NOTEBOOK.txt b/UPDATE YOUR COLAB NOTEBOOK.txt deleted file mode 100644 index 67a821f4..00000000 --- a/UPDATE YOUR COLAB NOTEBOOK.txt +++ /dev/null @@ -1,3 +0,0 @@ -If you use Google Colab to run your models, and you made a local copy of the Colab notebook in Google Drive instead of using the community notebook, you MUST make a new copy of the community notebook to use the new multiple-sequence generation feature. The link is below: - -https://colab.research.google.com/drive/1uGe9f4ruIQog3RLxfUsoThakvLpHjIkX?usp=sharing \ No newline at end of file diff --git a/aiserver.py b/aiserver.py index 8dcec2af..ba583480 100644 --- a/aiserver.py +++ b/aiserver.py @@ -56,13 +56,13 @@ class vars: model = "" # Model ID string chosen at startup noai = False # Runs the script without starting up the transformers pipeline aibusy = False # Stops submissions while the AI is working - max_length = 512 # Maximum number of tokens to submit per action + max_length = 1024 # Maximum number of tokens to submit per action ikmax = 3000 # Maximum number of characters to submit to InferKit - genamt = 60 # Amount of text for each action to generate + genamt = 80 # Amount of text for each action to generate ikgen = 200 # Number of characters for InferKit to generate - rep_pen = 1.0 # Default generator repetition_penalty - temp = 1.0 # Default generator temperature - top_p = 1.0 # Default generator top_p + rep_pen = 1.1 # Default generator repetition_penalty + temp = 0.5 # Default generator temperature + top_p = 0.9 # Default generator top_p numseqs = 1 # Number of sequences to ask the generator to create gamestarted = False # Whether the game has started (disables UI elements) prompt = "" # Prompt @@ -75,7 +75,7 @@ class vars: badwordsids = [] # Tokenized array of badwords deletewi = -1 # Temporary storage for index to delete wirmvwhtsp = False # Whether to remove leading whitespace from WI entries - widepth = 1 # How many historical actions to scan for WI hits + widepth = 3 # How many historical actions to scan for WI hits mode = "play" # Whether the interface is in play, memory, or edit mode editln = 0 # Which line was last selected in Edit Mode url = "https://api.inferkit.com/v1/models/standard/generate" # InferKit API URL @@ -434,6 +434,8 @@ def get_message(msg): importRequest() elif(msg['cmd'] == 'newgame'): newGameRequest() + elif(msg['cmd'] == 'rndgame'): + randomGameRequest(msg['data']) elif(msg['cmd'] == 'settemp'): vars.temp = float(msg['data']) emit('from_server', {'cmd': 'setlabeltemp', 'data': msg['data']}) @@ -1803,6 +1805,11 @@ def newGameRequest(): sendwi() setStartState() +def randomGameRequest(topic): + newGameRequest() + vars.memory = "You generate the following " + topic + " story concept :" + actionsubmit("") + vars.memory = "" #==================================================================# # Final startup commands to launch Flask app @@ -1813,5 +1820,5 @@ if __name__ == "__main__": # Start Flask/SocketIO (Blocking, so this must be last method!) print("{0}Server started!\rYou may now connect with a browser at http://127.0.0.1:5000/{1}".format(colors.GREEN, colors.END)) - #socketio.run(app, host='0.0.0.0', port=5000) - socketio.run(app) \ No newline at end of file + socketio.run(app, host='0.0.0.0', port=5000) + #socketio.run(app) diff --git a/gensettings.py b/gensettings.py index 8f6a67a0..eb914139 100644 --- a/gensettings.py +++ b/gensettings.py @@ -6,7 +6,7 @@ gensettingstf = [{ "min": 0.1, "max": 2.0, "step": 0.05, - "default": 1.0, + "default": 0.5, "tooltip": "Randomness of sampling. High values can increase creativity but may make text less sensible. Lower values will make text more predictable but can become repetitious." }, { @@ -17,7 +17,7 @@ gensettingstf = [{ "min": 0.1, "max": 1.0, "step": 0.05, - "default": 1.0, + "default": 0.9, "tooltip": "Used to discard unlikely text in the sampling process. Lower values will make text more predictable but can become repetitious." }, { @@ -28,7 +28,7 @@ gensettingstf = [{ "min": 1.0, "max": 2.0, "step": 0.05, - "default": 1.0, + "default": 1.1, "tooltip": "Used to penalize words that were already generated or belong to the context." }, { @@ -39,7 +39,7 @@ gensettingstf = [{ "min": 16, "max": 512, "step": 2, - "default": 60, + "default": 80, "tooltip": "Number of tokens the AI should generate. Higher numbers will take longer to generate." }, { @@ -50,7 +50,7 @@ gensettingstf = [{ "min": 512, "max": 2048, "step": 8, - "default": 512, + "default": 1024, "tooltip": "Max number of tokens of context to submit to the AI for sampling. Make sure this is higher than Amount to Generate. Higher values increase VRAM/RAM usage." }, { @@ -72,7 +72,7 @@ gensettingstf = [{ "min": 1, "max": 5, "step": 1, - "default": 1, + "default": 3, "tooltip": "Number of historic actions to scan for W Info keys." }, { @@ -95,7 +95,7 @@ gensettingsik =[{ "min": 0.1, "max": 2.0, "step": 0.05, - "default": 1.0, + "default": 0.5, "tooltip": "Randomness of sampling. High values can increase creativity but may make text less sensible. Lower values will make text more predictable but can become repetitious." }, { @@ -106,7 +106,7 @@ gensettingsik =[{ "min": 0.1, "max": 1.0, "step": 0.05, - "default": 1.0, + "default": 1.1, "tooltip": "Used to discard unlikely text in the sampling process. Lower values will make text more predictable but can become repetitious." }, { @@ -128,7 +128,7 @@ gensettingsik =[{ "min": 1, "max": 5, "step": 1, - "default": 1, + "default": 3, "tooltip": "Number of historic actions to scan for W Info keys." }, { diff --git a/readme.txt b/readme.txt index 5ea1e028..9ab782bb 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ This branch will eventually be used for a community edition of KoboldAI, uniting the different community made editions. -For now it is just a placeholder. +For now it is a WIP branch with Random Story Generation and better default settings. --- diff --git a/static/application - Copy.js b/static/application - Copy.js new file mode 100644 index 00000000..71c066d4 --- /dev/null +++ b/static/application - Copy.js @@ -0,0 +1,981 @@ +//=================================================================// +// VARIABLES +//=================================================================// + +// Socket IO Object +var socket; + +// UI references for jQuery +var connect_status; +var button_newgame; +var button_rndgame; +var button_save; +var button_saveas; +var button_savetofile; +var button_load; +var button_import; +var button_importwi; +var button_impaidg; +var button_settings; +var button_format; +var button_send; +var button_actedit; +var button_actmem; +var button_actback; +var button_actretry; +var button_delete; +var button_actwi; +var game_text; +var input_text; +var message_text; +var settings_menu; +var format_menu; +var wi_menu; +var anote_menu; +var anote_input; +var anote_labelcur; +var anote_slider; +var popup; +var popup_title; +var popup_content; +var popup_accept; +var popup_close; +var aidgpopup; +var aidgpromptnum; +var aidg_accept; +var aidg_close; +var saveaspopup; +var saveasinput; +var saveas_accept; +var saveas_close; +var saveasoverwrite; +var loadpopup; +var loadcontent; +var load_accept; +var load_close; +var nspopup; +var ns_accept; +var ns_close; +var rspopup; +var rs_accept; +var rs_close; +var seqselmenu; +var seqselcontents; + +// Key states +var shift_down = false; +var do_clear_ent = false; + +// Display vars +var allowtoggle = false; +var formatcount = 0; + +//=================================================================// +// METHODS +//=================================================================// + +function addSetting(ob) { + // Add setting block to Settings Menu + if(ob.uitype == "slider"){ + settings_menu.append("<div class=\"settingitem\">\ + <div class=\"settinglabel\">\ + <div class=\"justifyleft\">\ + "+ob.label+" <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>\ + <div class=\"justifyright\" id=\""+ob.id+"cur\">\ + "+ob.default+"\ + </div>\ + </div>\ + <div>\ + <input type=\"range\" class=\"form-range airange\" min=\""+ob.min+"\" max=\""+ob.max+"\" step=\""+ob.step+"\" id=\""+ob.id+"\">\ + </div>\ + <div class=\"settingminmax\">\ + <div class=\"justifyleft\">\ + "+ob.min+"\ + </div>\ + <div class=\"justifyright\">\ + "+ob.max+"\ + </div>\ + </div>\ + </div>"); + // Set references to HTML objects + var refin = $("#"+ob.id); + var reflb = $("#"+ob.id+"cur"); + window["setting_"+ob.id] = refin; // Is this still needed? + window["label_"+ob.id] = reflb; // Is this still needed? + // Add event function to input + refin.on("input", function () { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).val()}); + }); + } else if(ob.uitype == "toggle"){ + settings_menu.append("<div class=\"settingitem\">\ + <input type=\"checkbox\" data-toggle=\"toggle\" data-onstyle=\"success\" id=\""+ob.id+"\">\ + <span class=\"formatlabel\">"+ob.label+" </span>\ + <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>"); + // Tell Bootstrap-Toggle to render the new checkbox + $("input[type=checkbox]").bootstrapToggle(); + $("#"+ob.id).on("change", function () { + if(allowtoggle) { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).prop('checked')}); + } + }); + } +} + +function addFormat(ob) { + // Check if we need to make a new column for this button + if(formatcount == 0) { + format_menu.append("<div class=\"formatcolumn\"></div>"); + } + // Get reference to the last child column + var ref = $("#formatmenu > div").last(); + // Add format block to Format Menu + ref.append("<div class=\"formatrow\">\ + <input type=\"checkbox\" data-toggle=\"toggle\" data-onstyle=\"success\" id=\""+ob.id+"\">\ + <span class=\"formatlabel\">"+ob.label+" </span>\ + <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>"); + // Tell Bootstrap-Toggle to render the new checkbox + $("input[type=checkbox]").bootstrapToggle(); + // Add event to input + $("#"+ob.id).on("change", function () { + if(allowtoggle) { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).prop('checked')}); + } + }); + // Increment display variable + formatcount++; + if(formatcount == 2) { + formatcount = 0; + } +} + +function addImportLine(ob) { + popup_content.append("<div class=\"popuplistitem\" id=\"import"+ob.num+"\">\ + <div>"+ob.title+"</div>\ + <div>"+ob.acts+"</div>\ + <div>"+ob.descr+"</div>\ + </div>"); + $("#import"+ob.num).on("click", function () { + socket.send({'cmd': 'importselect', 'data': $(this).attr('id')}); + highlightImportLine($(this)); + }); +} + +function addWiLine(ob) { + if(ob.init) { + wi_menu.append("<div class=\"wilistitem\">\ + <div class=\"wiremove\">\ + <button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">X</button>\ + <button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\ + <button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">⮌</button>\ + </div>\ + <div class=\"wikey\">\ + <input class=\"form-control\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\ + </div>\ + <div class=\"wientry\">\ + <textarea class=\"form-control\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\">"+ob.content+"</textarea>\ + </div>\ + </div>"); + // Send key value to text input + $("#wikey"+ob.num).val(ob.key); + // Assign delete event to button + $("#btn_wi"+ob.num).on("click", function () { + showWiDeleteConfirm(ob.num); + }); + } else { + // Show WI line item with form fields hidden (uninitialized) + wi_menu.append("<div class=\"wilistitem\">\ + <div class=\"wiremove\">\ + <button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">+</button>\ + <button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\ + <button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">X</button>\ + </div>\ + <div class=\"wikey\">\ + <input class=\"form-control hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\ + </div>\ + <div class=\"wientry\">\ + <textarea class=\"form-control hidden\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\"></textarea>\ + </div>\ + </div>"); + // Assign function to expand WI item to button + $("#btn_wi"+ob.num).on("click", function () { + expandWiLine(ob.num); + }); + } + // Assign actions to other elements + $("#btn_wican"+ob.num).on("click", function () { + hideWiDeleteConfirm(ob.num); + }); + $("#btn_widel"+ob.num).on("click", function () { + socket.send({'cmd': 'widelete', 'data': ob.num}); + }); +} + +function expandWiLine(num) { + show([$("#wikey"+num), $("#wientry"+num)]); + $("#btn_wi"+num).html("X"); + $("#btn_wi"+num).off(); + // Tell server the WI entry was initialized + socket.send({'cmd': 'wiinit', 'data': num}); + $("#btn_wi"+num).on("click", function () { + showWiDeleteConfirm(num); + }); +} + +function showWiDeleteConfirm(num) { + hide([$("#btn_wi"+num)]); + show([$("#btn_widel"+num), $("#btn_wican"+num)]); +} + +function hideWiDeleteConfirm(num) { + show([$("#btn_wi"+num)]); + hide([$("#btn_widel"+num), $("#btn_wican"+num)]); +} + +function highlightImportLine(ref) { + $("#popupcontent > div").removeClass("popuplistselected"); + ref.addClass("popuplistselected"); + enableButtons([popup_accept]); +} + +function enableButtons(refs) { + for(i=0; i<refs.length; i++) { + refs[i].prop("disabled",false); + refs[i].removeClass("btn-secondary"); + refs[i].addClass("btn-primary"); + } +} + +function disableButtons(refs) { + for(i=0; i<refs.length; i++) { + refs[i].prop("disabled",true); + refs[i].removeClass("btn-primary"); + refs[i].addClass("btn-secondary"); + } +} + +function enableSendBtn() { + enableButtons([button_send]) + button_send.html("Submit"); +} + +function disableSendBtn() { + disableButtons([button_send]) + button_send.html(""); +} + +function showMessage(msg) { + message_text.removeClass(); + message_text.addClass("color_green"); + message_text.html(msg); +} + +function errMessage(msg) { + message_text.removeClass(); + message_text.addClass("color_red"); + message_text.html(msg); +} + +function hideMessage() { + message_text.html(""); + message_text.removeClass(); +} + +function showWaitAnimation() { + $("#inputrowright").append("<img id=\"waitanim\" src=\"static/thinking.gif\"/>"); +} + +function hideWaitAnimation() { + $('#waitanim').remove(); +} + +function hide(refs) { + for(i=0; i<refs.length; i++) { + refs[i].addClass("hidden"); + } +} + +function show(refs) { + for(i=0; i<refs.length; i++) { + refs[i].removeClass("hidden"); + } +} + +function popupShow(state) { + if(state) { + popup.removeClass("hidden"); + popup.addClass("flex"); + disableButtons([popup_accept]); + } else { + popup.removeClass("flex"); + popup.addClass("hidden"); + } +} + +function enterEditMode() { + // Add class to each story chunk + showMessage("Please select a story chunk to edit above."); + button_actedit.html("Cancel"); + game_text.children('chunk').addClass("chunkhov"); + game_text.on('click', '> *', function() { + editModeSelect($(this).attr("n")); + }); + disableSendBtn(); + hide([button_actback, button_actmem, button_actretry, button_actwi]); + show([button_delete]); +} + +function exitEditMode() { + // Remove class to each story chunk + hideMessage(); + button_actedit.html("Edit"); + game_text.children('chunk').removeClass("chunkhov"); + game_text.off('click', '> *'); + enableSendBtn(); + show([button_actback, button_actmem, button_actretry, button_actwi]); + hide([button_delete]); + input_text.val(""); +} + +function editModeSelect(n) { + socket.send({'cmd': 'editline', 'data': n}); +} + +function enterMemoryMode() { + showMessage("Edit the memory to be sent with each request to the AI."); + button_actmem.html("Cancel"); + hide([button_actback, button_actretry, button_actedit, button_delete, button_actwi]); + // Display Author's Note field + anote_menu.slideDown("fast"); +} + +function exitMemoryMode() { + hideMessage(); + button_actmem.html("Memory"); + show([button_actback, button_actretry, button_actedit, button_actwi]); + input_text.val(""); + // Hide Author's Note field + anote_menu.slideUp("fast"); +} + +function enterWiMode() { + showMessage("World Info will be added to memory only when the key appears in submitted text or the last action."); + button_actwi.html("Accept"); + hide([button_actedit, button_actback, button_actmem, button_actretry, game_text]); + show([wi_menu]); + disableSendBtn(); +} + +function exitWiMode() { + hideMessage(); + button_actwi.html("W Info"); + hide([wi_menu]); + show([button_actedit, button_actback, button_actmem, button_actretry, game_text]); + enableSendBtn(); +} + +function returnWiList(ar) { + var list = []; + var i; + for(i=0; i<ar.length; i++) { + var ob = {"key": "", "content": "", "num": ar[i]}; + ob.key = $("#wikey"+ar[i]).val(); + ob.content = $("#wientry"+ar[i]).val(); + list.push(ob); + } + socket.send({'cmd': 'sendwilist', 'data': list}); +} + +function dosubmit() { + var txt = input_text.val(); + socket.send({'cmd': 'submit', 'data': txt}); + input_text.val(""); + hideMessage(); + hidegenseqs(); +} + +function newTextHighlight(ref) { + ref.addClass("color_green"); + ref.addClass("colorfade"); + setTimeout(function () { + ref.removeClass("color_green"); + setTimeout(function () { + ref.removeClass("colorfade"); + }, 1000); + }, 10); +} + +function showAidgPopup() { + aidgpopup.removeClass("hidden"); + aidgpopup.addClass("flex"); + aidgpromptnum.focus(); +} + +function hideAidgPopup() { + aidgpopup.removeClass("flex"); + aidgpopup.addClass("hidden"); +} + +function sendAidgImportRequest() { + socket.send({'cmd': 'aidgimport', 'data': aidgpromptnum.val()}); + hideAidgPopup(); + aidgpromptnum.val(""); +} + +function showSaveAsPopup() { + disableButtons([saveas_accept]); + saveaspopup.removeClass("hidden"); + saveaspopup.addClass("flex"); + saveasinput.focus(); +} + +function hideSaveAsPopup() { + saveaspopup.removeClass("flex"); + saveaspopup.addClass("hidden"); + saveasinput.val(""); + hide([saveasoverwrite]); +} + +function sendSaveAsRequest() { + socket.send({'cmd': 'saveasrequest', 'data': saveasinput.val()}); +} + +function showLoadPopup() { + loadpopup.removeClass("hidden"); + loadpopup.addClass("flex"); +} + +function hideLoadPopup() { + loadpopup.removeClass("flex"); + loadpopup.addClass("hidden"); + loadcontent.html(""); +} + +function buildLoadList(ar) { + disableButtons([load_accept]); + loadcontent.html(""); + showLoadPopup(); + var i; + for(i=0; i<ar.length; i++) { + loadcontent.append("<div class=\"loadlistitem\" id=\"load"+i+"\" name=\""+ar[i].name+"\">\ + <div>"+ar[i].name+"</div>\ + <div>"+ar[i].actions+"</div>\ + </div>"); + $("#load"+i).on("click", function () { + enableButtons([load_accept]); + socket.send({'cmd': 'loadselect', 'data': $(this).attr("name")}); + highlightLoadLine($(this)); + }); + } +} + +function highlightLoadLine(ref) { + $("#loadlistcontent > div").removeClass("popuplistselected"); + ref.addClass("popuplistselected"); +} + +function showNewStoryPopup() { + nspopup.removeClass("hidden"); + nspopup.addClass("flex"); +} + +function hideNewStoryPopup() { + nspopup.removeClass("flex"); + nspopup.addClass("hidden"); +} + +function showRandomStoryPopup() { + rspopup.removeClass("hidden"); + rspopup.addClass("flex"); +} + +function hideRandomStoryPopup() { + rspopup.removeClass("flex"); + rspopup.addClass("hidden"); +} + +function setStartState() { + enableSendBtn(); + enableButtons([button_actmem, button_actwi]); + disableButtons([button_actedit, button_actback, button_actretry]); + hide([wi_menu, button_delete]); + show([game_text, button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + hideMessage(); + hideWaitAnimation(); + button_actedit.html("Edit"); + button_actmem.html("Memory"); + button_actwi.html("W Info"); + hideAidgPopup(); + hideSaveAsPopup(); + hideLoadPopup(); + hideNewStoryPopup(); + hidegenseqs(); +} + +function parsegenseqs(seqs) { + seqselcontents.html(""); + var i; + for(i=0; i<seqs.length; i++) { + seqselcontents.append("<div class=\"seqselitem\" id=\"seqsel"+i+"\" n=\""+i+"\">"+seqs[i].generated_text+"</div>"); + $("#seqsel"+i).on("click", function () { + socket.send({'cmd': 'seqsel', 'data': $(this).attr("n")}); + }); + } + $('#seqselmenu').slideDown("slow"); +} + +function hidegenseqs() { + $('#seqselmenu').slideUp("slow", function() { + seqselcontents.html(""); + }); +} + +//=================================================================// +// READY/RUNTIME +//=================================================================// + +$(document).ready(function(){ + + // Bind UI references + connect_status = $('#connectstatus'); + button_newgame = $('#btn_newgame'); + button_rndgame = $('#btn_rndgame'); + button_save = $('#btn_save'); + button_saveas = $('#btn_saveas'); + button_savetofile = $('#btn_savetofile'); + button_load = $('#btn_load'); + button_loadfrfile = $('#btn_loadfromfile'); + button_import = $("#btn_import"); + button_importwi = $("#btn_importwi"); + button_impaidg = $("#btn_impaidg"); + button_settings = $('#btn_settings'); + button_format = $('#btn_format'); + button_send = $('#btnsend'); + button_actedit = $('#btn_actedit'); + button_actmem = $('#btn_actmem'); + button_actback = $('#btn_actundo'); + button_actretry = $('#btn_actretry'); + button_delete = $('#btn_delete'); + button_actwi = $('#btn_actwi'); + game_text = $('#gametext'); + input_text = $('#input_text'); + message_text = $('#messagefield'); + settings_menu = $("#settingsmenu"); + format_menu = $('#formatmenu'); + anote_menu = $('#anoterowcontainer'); + wi_menu = $('#wimenu'); + anote_input = $('#anoteinput'); + anote_labelcur = $('#anotecur'); + anote_slider = $('#anotedepth'); + popup = $("#popupcontainer"); + popup_title = $("#popuptitletext"); + popup_content = $("#popupcontent"); + popup_accept = $("#btn_popupaccept"); + popup_close = $("#btn_popupclose"); + aidgpopup = $("#aidgpopupcontainer"); + aidgpromptnum = $("#aidgpromptnum"); + aidg_accept = $("#btn_aidgpopupaccept"); + aidg_close = $("#btn_aidgpopupclose"); + saveaspopup = $("#saveascontainer"); + saveasinput = $("#savename"); + saveas_accept = $("#btn_saveasaccept"); + saveas_close = $("#btn_saveasclose"); + saveasoverwrite = $("#saveasoverwrite"); + loadpopup = $("#loadcontainer"); + loadcontent = $("#loadlistcontent"); + load_accept = $("#btn_loadaccept"); + load_close = $("#btn_loadclose"); + nspopup = $("#newgamecontainer"); + ns_accept = $("#btn_nsaccept"); + ns_close = $("#btn_nsclose"); + rspopup = $("#rndgamecontainer"); + rs_accept = $("#btn_rsaccept"); + rs_close = $("#btn_rsclose"); + seqselmenu = $("#seqselmenu"); + seqselcontents = $("#seqselcontents"); + + // Connect to SocketIO server + loc = window.document.location; + socket = io.connect(loc.href); + + socket.on('from_server', function(msg) { + if(msg.cmd == "connected") { + // Connected to Server Actions + connect_status.html("<b>Connected to KoboldAI Process!</b>"); + connect_status.removeClass("color_orange"); + connect_status.addClass("color_green"); + // Reset Menus + settings_menu.html(""); + format_menu.html(""); + wi_menu.html(""); + } else if(msg.cmd == "updatescreen") { + // Send game content to Game Screen + game_text.html(msg.data); + // Scroll to bottom of text + setTimeout(function () { + $('#gamescreen').animate({scrollTop: $('#gamescreen').prop('scrollHeight')}, 1000); + }, 5); + } else if(msg.cmd == "setgamestate") { + // Enable or Disable buttons + if(msg.data == "ready") { + enableSendBtn(); + enableButtons([button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + hideWaitAnimation(); + } else if(msg.data == "wait") { + disableSendBtn(); + disableButtons([button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + showWaitAnimation(); + } else if(msg.data == "start") { + setStartState(); + } + } else if(msg.cmd == "editmode") { + // Enable or Disable edit mode + if(msg.data == "true") { + enterEditMode(); + } else { + exitEditMode(); + } + } else if(msg.cmd == "setinputtext") { + // Set input box text for edit mode + input_text.val(msg.data); + } else if(msg.cmd == "enablesubmit") { + // Enables the submit button + enableSendBtn(); + } else if(msg.cmd == "memmode") { + // Enable or Disable memory edit mode + if(msg.data == "true") { + enterMemoryMode(); + } else { + exitMemoryMode(); + } + } else if(msg.cmd == "errmsg") { + // Send error message + errMessage(msg.data); + } else if(msg.cmd == "texteffect") { + // Apply color highlight to line of text + newTextHighlight($("#n"+msg.data)) + } else if(msg.cmd == "updatetemp") { + // Send current temp value to input + $("#settemp").val(parseFloat(msg.data)); + $("#settempcur").html(msg.data); + } else if(msg.cmd == "updatetopp") { + // Send current top p value to input + $("#settopp").val(parseFloat(msg.data)); + $("#settoppcur").html(msg.data); + } else if(msg.cmd == "updatereppen") { + // Send current rep pen value to input + $("#setreppen").val(parseFloat(msg.data)); + $("#setreppencur").html(msg.data); + } else if(msg.cmd == "updateoutlen") { + // Send current output amt value to input + $("#setoutput").val(parseInt(msg.data)); + $("#setoutputcur").html(msg.data); + } else if(msg.cmd == "updatetknmax") { + // Send current max tokens value to input + $("#settknmax").val(parseInt(msg.data)); + $("#settknmaxcur").html(msg.data); + } else if(msg.cmd == "updateikgen") { + // Send current max tokens value to input + $("#setikgen").val(parseInt(msg.data)); + $("#setikgencur").html(msg.data); + } else if(msg.cmd == "setlabeltemp") { + // Update setting label with value from server + $("#settempcur").html(msg.data); + } else if(msg.cmd == "setlabeltopp") { + // Update setting label with value from server + $("#settoppcur").html(msg.data); + } else if(msg.cmd == "setlabelreppen") { + // Update setting label with value from server + $("#setreppencur").html(msg.data); + } else if(msg.cmd == "setlabeloutput") { + // Update setting label with value from server + $("#setoutputcur").html(msg.data); + } else if(msg.cmd == "setlabeltknmax") { + // Update setting label with value from server + $("#settknmaxcur").html(msg.data); + } else if(msg.cmd == "setlabelikgen") { + // Update setting label with value from server + $("#setikgencur").html(msg.data); + } else if(msg.cmd == "updateanotedepth") { + // Send current Author's Note depth value to input + anote_slider.val(parseInt(msg.data)); + anote_labelcur.html(msg.data); + } else if(msg.cmd == "setlabelanotedepth") { + // Update setting label with value from server + anote_labelcur.html(msg.data); + } else if(msg.cmd == "getanote") { + // Request contents of Author's Note field + var txt = anote_input.val(); + socket.send({'cmd': 'anote', 'data': txt}); + } else if(msg.cmd == "setanote") { + // Set contents of Author's Note field + anote_input.val(msg.data); + } else if(msg.cmd == "addsetting") { + // Add setting controls + addSetting(msg.data); + } else if(msg.cmd == "addformat") { + // Add setting controls + addFormat(msg.data); + } else if(msg.cmd == "updatefrmttriminc") { + // Update toggle state + $("#frmttriminc").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtrmblln") { + // Update toggle state + $("#frmtrmblln").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtrmspch") { + // Update toggle state + $("#frmtrmspch").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtadsnsp") { + // Update toggle state + $("#frmtadsnsp").prop('checked', msg.data).change(); + } else if(msg.cmd == "allowtoggle") { + // Allow toggle change states to propagate + allowtoggle = msg.data; + } else if(msg.cmd == "popupshow") { + // Show/Hide Popup + popupShow(msg.data); + } else if(msg.cmd == "addimportline") { + // Add import popup entry + addImportLine(msg.data); + } else if(msg.cmd == "clearpopup") { + // Clear previous contents of popup + popup_content.html(""); + } else if(msg.cmd == "wimode") { + // Enable or Disable WI edit mode + if(msg.data == "true") { + enterWiMode(); + } else { + exitWiMode(); + } + } else if(msg.cmd == "addwiitem") { + // Add WI entry to WI Menu + addWiLine(msg.data); + } else if(msg.cmd == "clearwi") { + // Clear previous contents of WI list + wi_menu.html(""); + } else if(msg.cmd == "requestwiitem") { + // Package WI contents and send back to server + returnWiList(msg.data); + } else if(msg.cmd == "saveas") { + // Show Save As prompt + showSaveAsPopup(); + } else if(msg.cmd == "hidesaveas") { + // Hide Save As prompt + hideSaveAsPopup(); + } else if(msg.cmd == "buildload") { + // Send array of save files to load UI + buildLoadList(msg.data); + } else if(msg.cmd == "askforoverwrite") { + // Show overwrite warning + show([saveasoverwrite]); + } else if(msg.cmd == "genseqs") { + // Parse generator sequences to UI + parsegenseqs(msg.data); + } else if(msg.cmd == "hidegenseqs") { + // Collapse genseqs menu + hidegenseqs(); + } else if(msg.cmd == "setlabelnumseq") { + // Update setting label with value from server + $("#setnumseqcur").html(msg.data); + } else if(msg.cmd == "updatenumseq") { + // Send current max tokens value to input + $("#setnumseq").val(parseInt(msg.data)); + $("#setnumseqcur").html(msg.data); + } else if(msg.cmd == "setlabelwidepth") { + // Update setting label with value from server + $("#setwidepthcur").html(msg.data); + } else if(msg.cmd == "updatewidepth") { + // Send current max tokens value to input + $("#setwidepth").val(parseInt(msg.data)); + $("#setwidepthcur").html(msg.data); + } else if(msg.cmd == "updateuseprompt") { + // Update toggle state + $("#setuseprompt").prop('checked', msg.data).change(); + } + }); + + socket.on('disconnect', function() { + connect_status.html("<b>Lost connection...</b>"); + connect_status.removeClass("color_green"); + connect_status.addClass("color_orange"); + }); + + // Bind actions to UI buttons + button_send.on("click", function(ev) { + dosubmit(); + }); + + button_actretry.on("click", function(ev) { + socket.send({'cmd': 'retry', 'data': ''}); + hidegenseqs(); + }); + + button_actback.on("click", function(ev) { + socket.send({'cmd': 'back', 'data': ''}); + hidegenseqs(); + }); + + button_actedit.on("click", function(ev) { + socket.send({'cmd': 'edit', 'data': ''}); + }); + + button_delete.on("click", function(ev) { + socket.send({'cmd': 'delete', 'data': ''}); + }); + + button_actmem.on("click", function(ev) { + socket.send({'cmd': 'memory', 'data': ''}); + }); + + button_savetofile.on("click", function(ev) { + socket.send({'cmd': 'savetofile', 'data': ''}); + }); + + button_loadfrfile.on("click", function(ev) { + socket.send({'cmd': 'loadfromfile', 'data': ''}); + }); + + button_import.on("click", function(ev) { + socket.send({'cmd': 'import', 'data': ''}); + }); + + button_importwi.on("click", function(ev) { + socket.send({'cmd': 'importwi', 'data': ''}); + }); + + button_settings.on("click", function(ev) { + $('#settingsmenu').slideToggle("slow"); + }); + + button_format.on("click", function(ev) { + $('#formatmenu').slideToggle("slow"); + }); + + popup_close.on("click", function(ev) { + socket.send({'cmd': 'importcancel', 'data': ''}); + }); + + popup_accept.on("click", function(ev) { + socket.send({'cmd': 'importaccept', 'data': ''}); + }); + + button_actwi.on("click", function(ev) { + socket.send({'cmd': 'wi', 'data': ''}); + }); + + button_impaidg.on("click", function(ev) { + showAidgPopup(); + }); + + aidg_close.on("click", function(ev) { + hideAidgPopup(); + }); + + aidg_accept.on("click", function(ev) { + sendAidgImportRequest(); + }); + + button_save.on("click", function(ev) { + socket.send({'cmd': 'saverequest', 'data': ''}); + }); + + button_saveas.on("click", function(ev) { + showSaveAsPopup(); + }); + + saveas_close.on("click", function(ev) { + hideSaveAsPopup(); + socket.send({'cmd': 'clearoverwrite', 'data': ''}); + }); + + saveas_accept.on("click", function(ev) { + sendSaveAsRequest(); + }); + + button_load.on("click", function(ev) { + socket.send({'cmd': 'loadlistrequest', 'data': ''}); + }); + + load_close.on("click", function(ev) { + hideLoadPopup(); + }); + + load_accept.on("click", function(ev) { + socket.send({'cmd': 'loadrequest', 'data': ''}); + hideLoadPopup(); + }); + + button_newgame.on("click", function(ev) { + showNewStoryPopup(); + }); + + ns_accept.on("click", function(ev) { + socket.send({'cmd': 'newgame', 'data': ''}); + hideNewStoryPopup(); + }); + + ns_close.on("click", function(ev) { + hideNewStoryPopup(); + }); + + button_rndgame.on("click", function(ev) { + showRandomStoryPopup(); + }); + + rs_accept.on("click", function(ev) { + socket.send({'cmd': 'rndgame', 'data': ''}); + hideRandomStoryPopup(); + }); + + rs_close.on("click", function(ev) { + hideRandomStoryPopup(); + }); + + anote_slider.on("input", function () { + socket.send({'cmd': 'anotedepth', 'data': $(this).val()}); + }); + + saveasinput.on("input", function () { + if(saveasinput.val() == "") { + disableButtons([saveas_accept]); + } else { + enableButtons([saveas_accept]); + } + hide([saveasoverwrite]); + }); + + // Bind Enter button to submit + input_text.keydown(function (ev) { + if (ev.which == 13 && !shift_down) { + do_clear_ent = true; + dosubmit(); + } else if(ev.which == 16) { + shift_down = true; + } + }); + + // Enter to submit, but not if holding shift + input_text.keyup(function (ev) { + if (ev.which == 13 && do_clear_ent) { + input_text.val(""); + do_clear_ent = false; + } else if(ev.which == 16) { + shift_down = false; + } + }); + + aidgpromptnum.keydown(function (ev) { + if (ev.which == 13) { + sendAidgImportRequest(); + } + }); + + saveasinput.keydown(function (ev) { + if (ev.which == 13 && saveasinput.val() != "") { + sendSaveAsRequest(); + } + }); +}); + diff --git a/static/application.js b/static/application.js index e5ebc806..5a4a0086 100644 --- a/static/application.js +++ b/static/application.js @@ -8,6 +8,7 @@ var socket; // UI references for jQuery var connect_status; var button_newgame; +var button_rndgame; var button_save; var button_saveas; var button_savetofile; @@ -45,6 +46,7 @@ var aidg_accept; var aidg_close; var saveaspopup; var saveasinput; +var topic; var saveas_accept; var saveas_close; var saveasoverwrite; @@ -55,6 +57,9 @@ var load_close; var nspopup; var ns_accept; var ns_close; +var rspopup; +var rs_accept; +var rs_close; var seqselmenu; var seqselcontents; @@ -482,6 +487,16 @@ function hideNewStoryPopup() { nspopup.addClass("hidden"); } +function showRandomStoryPopup() { + rspopup.removeClass("hidden"); + rspopup.addClass("flex"); +} + +function hideRandomStoryPopup() { + rspopup.removeClass("flex"); + rspopup.addClass("hidden"); +} + function setStartState() { enableSendBtn(); enableButtons([button_actmem, button_actwi]); @@ -527,6 +542,7 @@ $(document).ready(function(){ // Bind UI references connect_status = $('#connectstatus'); button_newgame = $('#btn_newgame'); + button_rndgame = $('#btn_rndgame'); button_save = $('#btn_save'); button_saveas = $('#btn_saveas'); button_savetofile = $('#btn_savetofile'); @@ -565,6 +581,7 @@ $(document).ready(function(){ aidg_close = $("#btn_aidgpopupclose"); saveaspopup = $("#saveascontainer"); saveasinput = $("#savename"); + topic = $("#topic"); saveas_accept = $("#btn_saveasaccept"); saveas_close = $("#btn_saveasclose"); saveasoverwrite = $("#saveasoverwrite"); @@ -575,6 +592,9 @@ $(document).ready(function(){ nspopup = $("#newgamecontainer"); ns_accept = $("#btn_nsaccept"); ns_close = $("#btn_nsclose"); + rspopup = $("#rndgamecontainer"); + rs_accept = $("#btn_rsaccept"); + rs_close = $("#btn_rsclose"); seqselmenu = $("#seqselmenu"); seqselcontents = $("#seqselcontents"); @@ -902,6 +922,19 @@ $(document).ready(function(){ hideNewStoryPopup(); }); + button_rndgame.on("click", function(ev) { + showRandomStoryPopup(); + }); + + rs_accept.on("click", function(ev) { + socket.send({'cmd': 'rndgame', 'data': topic.val()}); + hideRandomStoryPopup(); + }); + + rs_close.on("click", function(ev) { + hideRandomStoryPopup(); + }); + anote_slider.on("input", function () { socket.send({'cmd': 'anotedepth', 'data': $(this).val()}); }); diff --git a/static/application.js.bak b/static/application.js.bak new file mode 100644 index 00000000..71c066d4 --- /dev/null +++ b/static/application.js.bak @@ -0,0 +1,981 @@ +//=================================================================// +// VARIABLES +//=================================================================// + +// Socket IO Object +var socket; + +// UI references for jQuery +var connect_status; +var button_newgame; +var button_rndgame; +var button_save; +var button_saveas; +var button_savetofile; +var button_load; +var button_import; +var button_importwi; +var button_impaidg; +var button_settings; +var button_format; +var button_send; +var button_actedit; +var button_actmem; +var button_actback; +var button_actretry; +var button_delete; +var button_actwi; +var game_text; +var input_text; +var message_text; +var settings_menu; +var format_menu; +var wi_menu; +var anote_menu; +var anote_input; +var anote_labelcur; +var anote_slider; +var popup; +var popup_title; +var popup_content; +var popup_accept; +var popup_close; +var aidgpopup; +var aidgpromptnum; +var aidg_accept; +var aidg_close; +var saveaspopup; +var saveasinput; +var saveas_accept; +var saveas_close; +var saveasoverwrite; +var loadpopup; +var loadcontent; +var load_accept; +var load_close; +var nspopup; +var ns_accept; +var ns_close; +var rspopup; +var rs_accept; +var rs_close; +var seqselmenu; +var seqselcontents; + +// Key states +var shift_down = false; +var do_clear_ent = false; + +// Display vars +var allowtoggle = false; +var formatcount = 0; + +//=================================================================// +// METHODS +//=================================================================// + +function addSetting(ob) { + // Add setting block to Settings Menu + if(ob.uitype == "slider"){ + settings_menu.append("<div class=\"settingitem\">\ + <div class=\"settinglabel\">\ + <div class=\"justifyleft\">\ + "+ob.label+" <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>\ + <div class=\"justifyright\" id=\""+ob.id+"cur\">\ + "+ob.default+"\ + </div>\ + </div>\ + <div>\ + <input type=\"range\" class=\"form-range airange\" min=\""+ob.min+"\" max=\""+ob.max+"\" step=\""+ob.step+"\" id=\""+ob.id+"\">\ + </div>\ + <div class=\"settingminmax\">\ + <div class=\"justifyleft\">\ + "+ob.min+"\ + </div>\ + <div class=\"justifyright\">\ + "+ob.max+"\ + </div>\ + </div>\ + </div>"); + // Set references to HTML objects + var refin = $("#"+ob.id); + var reflb = $("#"+ob.id+"cur"); + window["setting_"+ob.id] = refin; // Is this still needed? + window["label_"+ob.id] = reflb; // Is this still needed? + // Add event function to input + refin.on("input", function () { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).val()}); + }); + } else if(ob.uitype == "toggle"){ + settings_menu.append("<div class=\"settingitem\">\ + <input type=\"checkbox\" data-toggle=\"toggle\" data-onstyle=\"success\" id=\""+ob.id+"\">\ + <span class=\"formatlabel\">"+ob.label+" </span>\ + <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>"); + // Tell Bootstrap-Toggle to render the new checkbox + $("input[type=checkbox]").bootstrapToggle(); + $("#"+ob.id).on("change", function () { + if(allowtoggle) { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).prop('checked')}); + } + }); + } +} + +function addFormat(ob) { + // Check if we need to make a new column for this button + if(formatcount == 0) { + format_menu.append("<div class=\"formatcolumn\"></div>"); + } + // Get reference to the last child column + var ref = $("#formatmenu > div").last(); + // Add format block to Format Menu + ref.append("<div class=\"formatrow\">\ + <input type=\"checkbox\" data-toggle=\"toggle\" data-onstyle=\"success\" id=\""+ob.id+"\">\ + <span class=\"formatlabel\">"+ob.label+" </span>\ + <span class=\"helpicon\">?<span class=\"helptext\">"+ob.tooltip+"</span></span>\ + </div>"); + // Tell Bootstrap-Toggle to render the new checkbox + $("input[type=checkbox]").bootstrapToggle(); + // Add event to input + $("#"+ob.id).on("change", function () { + if(allowtoggle) { + socket.send({'cmd': $(this).attr('id'), 'data': $(this).prop('checked')}); + } + }); + // Increment display variable + formatcount++; + if(formatcount == 2) { + formatcount = 0; + } +} + +function addImportLine(ob) { + popup_content.append("<div class=\"popuplistitem\" id=\"import"+ob.num+"\">\ + <div>"+ob.title+"</div>\ + <div>"+ob.acts+"</div>\ + <div>"+ob.descr+"</div>\ + </div>"); + $("#import"+ob.num).on("click", function () { + socket.send({'cmd': 'importselect', 'data': $(this).attr('id')}); + highlightImportLine($(this)); + }); +} + +function addWiLine(ob) { + if(ob.init) { + wi_menu.append("<div class=\"wilistitem\">\ + <div class=\"wiremove\">\ + <button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">X</button>\ + <button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\ + <button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">⮌</button>\ + </div>\ + <div class=\"wikey\">\ + <input class=\"form-control\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\ + </div>\ + <div class=\"wientry\">\ + <textarea class=\"form-control\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\">"+ob.content+"</textarea>\ + </div>\ + </div>"); + // Send key value to text input + $("#wikey"+ob.num).val(ob.key); + // Assign delete event to button + $("#btn_wi"+ob.num).on("click", function () { + showWiDeleteConfirm(ob.num); + }); + } else { + // Show WI line item with form fields hidden (uninitialized) + wi_menu.append("<div class=\"wilistitem\">\ + <div class=\"wiremove\">\ + <button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">+</button>\ + <button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\ + <button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">X</button>\ + </div>\ + <div class=\"wikey\">\ + <input class=\"form-control hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\ + </div>\ + <div class=\"wientry\">\ + <textarea class=\"form-control hidden\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\"></textarea>\ + </div>\ + </div>"); + // Assign function to expand WI item to button + $("#btn_wi"+ob.num).on("click", function () { + expandWiLine(ob.num); + }); + } + // Assign actions to other elements + $("#btn_wican"+ob.num).on("click", function () { + hideWiDeleteConfirm(ob.num); + }); + $("#btn_widel"+ob.num).on("click", function () { + socket.send({'cmd': 'widelete', 'data': ob.num}); + }); +} + +function expandWiLine(num) { + show([$("#wikey"+num), $("#wientry"+num)]); + $("#btn_wi"+num).html("X"); + $("#btn_wi"+num).off(); + // Tell server the WI entry was initialized + socket.send({'cmd': 'wiinit', 'data': num}); + $("#btn_wi"+num).on("click", function () { + showWiDeleteConfirm(num); + }); +} + +function showWiDeleteConfirm(num) { + hide([$("#btn_wi"+num)]); + show([$("#btn_widel"+num), $("#btn_wican"+num)]); +} + +function hideWiDeleteConfirm(num) { + show([$("#btn_wi"+num)]); + hide([$("#btn_widel"+num), $("#btn_wican"+num)]); +} + +function highlightImportLine(ref) { + $("#popupcontent > div").removeClass("popuplistselected"); + ref.addClass("popuplistselected"); + enableButtons([popup_accept]); +} + +function enableButtons(refs) { + for(i=0; i<refs.length; i++) { + refs[i].prop("disabled",false); + refs[i].removeClass("btn-secondary"); + refs[i].addClass("btn-primary"); + } +} + +function disableButtons(refs) { + for(i=0; i<refs.length; i++) { + refs[i].prop("disabled",true); + refs[i].removeClass("btn-primary"); + refs[i].addClass("btn-secondary"); + } +} + +function enableSendBtn() { + enableButtons([button_send]) + button_send.html("Submit"); +} + +function disableSendBtn() { + disableButtons([button_send]) + button_send.html(""); +} + +function showMessage(msg) { + message_text.removeClass(); + message_text.addClass("color_green"); + message_text.html(msg); +} + +function errMessage(msg) { + message_text.removeClass(); + message_text.addClass("color_red"); + message_text.html(msg); +} + +function hideMessage() { + message_text.html(""); + message_text.removeClass(); +} + +function showWaitAnimation() { + $("#inputrowright").append("<img id=\"waitanim\" src=\"static/thinking.gif\"/>"); +} + +function hideWaitAnimation() { + $('#waitanim').remove(); +} + +function hide(refs) { + for(i=0; i<refs.length; i++) { + refs[i].addClass("hidden"); + } +} + +function show(refs) { + for(i=0; i<refs.length; i++) { + refs[i].removeClass("hidden"); + } +} + +function popupShow(state) { + if(state) { + popup.removeClass("hidden"); + popup.addClass("flex"); + disableButtons([popup_accept]); + } else { + popup.removeClass("flex"); + popup.addClass("hidden"); + } +} + +function enterEditMode() { + // Add class to each story chunk + showMessage("Please select a story chunk to edit above."); + button_actedit.html("Cancel"); + game_text.children('chunk').addClass("chunkhov"); + game_text.on('click', '> *', function() { + editModeSelect($(this).attr("n")); + }); + disableSendBtn(); + hide([button_actback, button_actmem, button_actretry, button_actwi]); + show([button_delete]); +} + +function exitEditMode() { + // Remove class to each story chunk + hideMessage(); + button_actedit.html("Edit"); + game_text.children('chunk').removeClass("chunkhov"); + game_text.off('click', '> *'); + enableSendBtn(); + show([button_actback, button_actmem, button_actretry, button_actwi]); + hide([button_delete]); + input_text.val(""); +} + +function editModeSelect(n) { + socket.send({'cmd': 'editline', 'data': n}); +} + +function enterMemoryMode() { + showMessage("Edit the memory to be sent with each request to the AI."); + button_actmem.html("Cancel"); + hide([button_actback, button_actretry, button_actedit, button_delete, button_actwi]); + // Display Author's Note field + anote_menu.slideDown("fast"); +} + +function exitMemoryMode() { + hideMessage(); + button_actmem.html("Memory"); + show([button_actback, button_actretry, button_actedit, button_actwi]); + input_text.val(""); + // Hide Author's Note field + anote_menu.slideUp("fast"); +} + +function enterWiMode() { + showMessage("World Info will be added to memory only when the key appears in submitted text or the last action."); + button_actwi.html("Accept"); + hide([button_actedit, button_actback, button_actmem, button_actretry, game_text]); + show([wi_menu]); + disableSendBtn(); +} + +function exitWiMode() { + hideMessage(); + button_actwi.html("W Info"); + hide([wi_menu]); + show([button_actedit, button_actback, button_actmem, button_actretry, game_text]); + enableSendBtn(); +} + +function returnWiList(ar) { + var list = []; + var i; + for(i=0; i<ar.length; i++) { + var ob = {"key": "", "content": "", "num": ar[i]}; + ob.key = $("#wikey"+ar[i]).val(); + ob.content = $("#wientry"+ar[i]).val(); + list.push(ob); + } + socket.send({'cmd': 'sendwilist', 'data': list}); +} + +function dosubmit() { + var txt = input_text.val(); + socket.send({'cmd': 'submit', 'data': txt}); + input_text.val(""); + hideMessage(); + hidegenseqs(); +} + +function newTextHighlight(ref) { + ref.addClass("color_green"); + ref.addClass("colorfade"); + setTimeout(function () { + ref.removeClass("color_green"); + setTimeout(function () { + ref.removeClass("colorfade"); + }, 1000); + }, 10); +} + +function showAidgPopup() { + aidgpopup.removeClass("hidden"); + aidgpopup.addClass("flex"); + aidgpromptnum.focus(); +} + +function hideAidgPopup() { + aidgpopup.removeClass("flex"); + aidgpopup.addClass("hidden"); +} + +function sendAidgImportRequest() { + socket.send({'cmd': 'aidgimport', 'data': aidgpromptnum.val()}); + hideAidgPopup(); + aidgpromptnum.val(""); +} + +function showSaveAsPopup() { + disableButtons([saveas_accept]); + saveaspopup.removeClass("hidden"); + saveaspopup.addClass("flex"); + saveasinput.focus(); +} + +function hideSaveAsPopup() { + saveaspopup.removeClass("flex"); + saveaspopup.addClass("hidden"); + saveasinput.val(""); + hide([saveasoverwrite]); +} + +function sendSaveAsRequest() { + socket.send({'cmd': 'saveasrequest', 'data': saveasinput.val()}); +} + +function showLoadPopup() { + loadpopup.removeClass("hidden"); + loadpopup.addClass("flex"); +} + +function hideLoadPopup() { + loadpopup.removeClass("flex"); + loadpopup.addClass("hidden"); + loadcontent.html(""); +} + +function buildLoadList(ar) { + disableButtons([load_accept]); + loadcontent.html(""); + showLoadPopup(); + var i; + for(i=0; i<ar.length; i++) { + loadcontent.append("<div class=\"loadlistitem\" id=\"load"+i+"\" name=\""+ar[i].name+"\">\ + <div>"+ar[i].name+"</div>\ + <div>"+ar[i].actions+"</div>\ + </div>"); + $("#load"+i).on("click", function () { + enableButtons([load_accept]); + socket.send({'cmd': 'loadselect', 'data': $(this).attr("name")}); + highlightLoadLine($(this)); + }); + } +} + +function highlightLoadLine(ref) { + $("#loadlistcontent > div").removeClass("popuplistselected"); + ref.addClass("popuplistselected"); +} + +function showNewStoryPopup() { + nspopup.removeClass("hidden"); + nspopup.addClass("flex"); +} + +function hideNewStoryPopup() { + nspopup.removeClass("flex"); + nspopup.addClass("hidden"); +} + +function showRandomStoryPopup() { + rspopup.removeClass("hidden"); + rspopup.addClass("flex"); +} + +function hideRandomStoryPopup() { + rspopup.removeClass("flex"); + rspopup.addClass("hidden"); +} + +function setStartState() { + enableSendBtn(); + enableButtons([button_actmem, button_actwi]); + disableButtons([button_actedit, button_actback, button_actretry]); + hide([wi_menu, button_delete]); + show([game_text, button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + hideMessage(); + hideWaitAnimation(); + button_actedit.html("Edit"); + button_actmem.html("Memory"); + button_actwi.html("W Info"); + hideAidgPopup(); + hideSaveAsPopup(); + hideLoadPopup(); + hideNewStoryPopup(); + hidegenseqs(); +} + +function parsegenseqs(seqs) { + seqselcontents.html(""); + var i; + for(i=0; i<seqs.length; i++) { + seqselcontents.append("<div class=\"seqselitem\" id=\"seqsel"+i+"\" n=\""+i+"\">"+seqs[i].generated_text+"</div>"); + $("#seqsel"+i).on("click", function () { + socket.send({'cmd': 'seqsel', 'data': $(this).attr("n")}); + }); + } + $('#seqselmenu').slideDown("slow"); +} + +function hidegenseqs() { + $('#seqselmenu').slideUp("slow", function() { + seqselcontents.html(""); + }); +} + +//=================================================================// +// READY/RUNTIME +//=================================================================// + +$(document).ready(function(){ + + // Bind UI references + connect_status = $('#connectstatus'); + button_newgame = $('#btn_newgame'); + button_rndgame = $('#btn_rndgame'); + button_save = $('#btn_save'); + button_saveas = $('#btn_saveas'); + button_savetofile = $('#btn_savetofile'); + button_load = $('#btn_load'); + button_loadfrfile = $('#btn_loadfromfile'); + button_import = $("#btn_import"); + button_importwi = $("#btn_importwi"); + button_impaidg = $("#btn_impaidg"); + button_settings = $('#btn_settings'); + button_format = $('#btn_format'); + button_send = $('#btnsend'); + button_actedit = $('#btn_actedit'); + button_actmem = $('#btn_actmem'); + button_actback = $('#btn_actundo'); + button_actretry = $('#btn_actretry'); + button_delete = $('#btn_delete'); + button_actwi = $('#btn_actwi'); + game_text = $('#gametext'); + input_text = $('#input_text'); + message_text = $('#messagefield'); + settings_menu = $("#settingsmenu"); + format_menu = $('#formatmenu'); + anote_menu = $('#anoterowcontainer'); + wi_menu = $('#wimenu'); + anote_input = $('#anoteinput'); + anote_labelcur = $('#anotecur'); + anote_slider = $('#anotedepth'); + popup = $("#popupcontainer"); + popup_title = $("#popuptitletext"); + popup_content = $("#popupcontent"); + popup_accept = $("#btn_popupaccept"); + popup_close = $("#btn_popupclose"); + aidgpopup = $("#aidgpopupcontainer"); + aidgpromptnum = $("#aidgpromptnum"); + aidg_accept = $("#btn_aidgpopupaccept"); + aidg_close = $("#btn_aidgpopupclose"); + saveaspopup = $("#saveascontainer"); + saveasinput = $("#savename"); + saveas_accept = $("#btn_saveasaccept"); + saveas_close = $("#btn_saveasclose"); + saveasoverwrite = $("#saveasoverwrite"); + loadpopup = $("#loadcontainer"); + loadcontent = $("#loadlistcontent"); + load_accept = $("#btn_loadaccept"); + load_close = $("#btn_loadclose"); + nspopup = $("#newgamecontainer"); + ns_accept = $("#btn_nsaccept"); + ns_close = $("#btn_nsclose"); + rspopup = $("#rndgamecontainer"); + rs_accept = $("#btn_rsaccept"); + rs_close = $("#btn_rsclose"); + seqselmenu = $("#seqselmenu"); + seqselcontents = $("#seqselcontents"); + + // Connect to SocketIO server + loc = window.document.location; + socket = io.connect(loc.href); + + socket.on('from_server', function(msg) { + if(msg.cmd == "connected") { + // Connected to Server Actions + connect_status.html("<b>Connected to KoboldAI Process!</b>"); + connect_status.removeClass("color_orange"); + connect_status.addClass("color_green"); + // Reset Menus + settings_menu.html(""); + format_menu.html(""); + wi_menu.html(""); + } else if(msg.cmd == "updatescreen") { + // Send game content to Game Screen + game_text.html(msg.data); + // Scroll to bottom of text + setTimeout(function () { + $('#gamescreen').animate({scrollTop: $('#gamescreen').prop('scrollHeight')}, 1000); + }, 5); + } else if(msg.cmd == "setgamestate") { + // Enable or Disable buttons + if(msg.data == "ready") { + enableSendBtn(); + enableButtons([button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + hideWaitAnimation(); + } else if(msg.data == "wait") { + disableSendBtn(); + disableButtons([button_actedit, button_actmem, button_actwi, button_actback, button_actretry]); + showWaitAnimation(); + } else if(msg.data == "start") { + setStartState(); + } + } else if(msg.cmd == "editmode") { + // Enable or Disable edit mode + if(msg.data == "true") { + enterEditMode(); + } else { + exitEditMode(); + } + } else if(msg.cmd == "setinputtext") { + // Set input box text for edit mode + input_text.val(msg.data); + } else if(msg.cmd == "enablesubmit") { + // Enables the submit button + enableSendBtn(); + } else if(msg.cmd == "memmode") { + // Enable or Disable memory edit mode + if(msg.data == "true") { + enterMemoryMode(); + } else { + exitMemoryMode(); + } + } else if(msg.cmd == "errmsg") { + // Send error message + errMessage(msg.data); + } else if(msg.cmd == "texteffect") { + // Apply color highlight to line of text + newTextHighlight($("#n"+msg.data)) + } else if(msg.cmd == "updatetemp") { + // Send current temp value to input + $("#settemp").val(parseFloat(msg.data)); + $("#settempcur").html(msg.data); + } else if(msg.cmd == "updatetopp") { + // Send current top p value to input + $("#settopp").val(parseFloat(msg.data)); + $("#settoppcur").html(msg.data); + } else if(msg.cmd == "updatereppen") { + // Send current rep pen value to input + $("#setreppen").val(parseFloat(msg.data)); + $("#setreppencur").html(msg.data); + } else if(msg.cmd == "updateoutlen") { + // Send current output amt value to input + $("#setoutput").val(parseInt(msg.data)); + $("#setoutputcur").html(msg.data); + } else if(msg.cmd == "updatetknmax") { + // Send current max tokens value to input + $("#settknmax").val(parseInt(msg.data)); + $("#settknmaxcur").html(msg.data); + } else if(msg.cmd == "updateikgen") { + // Send current max tokens value to input + $("#setikgen").val(parseInt(msg.data)); + $("#setikgencur").html(msg.data); + } else if(msg.cmd == "setlabeltemp") { + // Update setting label with value from server + $("#settempcur").html(msg.data); + } else if(msg.cmd == "setlabeltopp") { + // Update setting label with value from server + $("#settoppcur").html(msg.data); + } else if(msg.cmd == "setlabelreppen") { + // Update setting label with value from server + $("#setreppencur").html(msg.data); + } else if(msg.cmd == "setlabeloutput") { + // Update setting label with value from server + $("#setoutputcur").html(msg.data); + } else if(msg.cmd == "setlabeltknmax") { + // Update setting label with value from server + $("#settknmaxcur").html(msg.data); + } else if(msg.cmd == "setlabelikgen") { + // Update setting label with value from server + $("#setikgencur").html(msg.data); + } else if(msg.cmd == "updateanotedepth") { + // Send current Author's Note depth value to input + anote_slider.val(parseInt(msg.data)); + anote_labelcur.html(msg.data); + } else if(msg.cmd == "setlabelanotedepth") { + // Update setting label with value from server + anote_labelcur.html(msg.data); + } else if(msg.cmd == "getanote") { + // Request contents of Author's Note field + var txt = anote_input.val(); + socket.send({'cmd': 'anote', 'data': txt}); + } else if(msg.cmd == "setanote") { + // Set contents of Author's Note field + anote_input.val(msg.data); + } else if(msg.cmd == "addsetting") { + // Add setting controls + addSetting(msg.data); + } else if(msg.cmd == "addformat") { + // Add setting controls + addFormat(msg.data); + } else if(msg.cmd == "updatefrmttriminc") { + // Update toggle state + $("#frmttriminc").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtrmblln") { + // Update toggle state + $("#frmtrmblln").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtrmspch") { + // Update toggle state + $("#frmtrmspch").prop('checked', msg.data).change(); + } else if(msg.cmd == "updatefrmtadsnsp") { + // Update toggle state + $("#frmtadsnsp").prop('checked', msg.data).change(); + } else if(msg.cmd == "allowtoggle") { + // Allow toggle change states to propagate + allowtoggle = msg.data; + } else if(msg.cmd == "popupshow") { + // Show/Hide Popup + popupShow(msg.data); + } else if(msg.cmd == "addimportline") { + // Add import popup entry + addImportLine(msg.data); + } else if(msg.cmd == "clearpopup") { + // Clear previous contents of popup + popup_content.html(""); + } else if(msg.cmd == "wimode") { + // Enable or Disable WI edit mode + if(msg.data == "true") { + enterWiMode(); + } else { + exitWiMode(); + } + } else if(msg.cmd == "addwiitem") { + // Add WI entry to WI Menu + addWiLine(msg.data); + } else if(msg.cmd == "clearwi") { + // Clear previous contents of WI list + wi_menu.html(""); + } else if(msg.cmd == "requestwiitem") { + // Package WI contents and send back to server + returnWiList(msg.data); + } else if(msg.cmd == "saveas") { + // Show Save As prompt + showSaveAsPopup(); + } else if(msg.cmd == "hidesaveas") { + // Hide Save As prompt + hideSaveAsPopup(); + } else if(msg.cmd == "buildload") { + // Send array of save files to load UI + buildLoadList(msg.data); + } else if(msg.cmd == "askforoverwrite") { + // Show overwrite warning + show([saveasoverwrite]); + } else if(msg.cmd == "genseqs") { + // Parse generator sequences to UI + parsegenseqs(msg.data); + } else if(msg.cmd == "hidegenseqs") { + // Collapse genseqs menu + hidegenseqs(); + } else if(msg.cmd == "setlabelnumseq") { + // Update setting label with value from server + $("#setnumseqcur").html(msg.data); + } else if(msg.cmd == "updatenumseq") { + // Send current max tokens value to input + $("#setnumseq").val(parseInt(msg.data)); + $("#setnumseqcur").html(msg.data); + } else if(msg.cmd == "setlabelwidepth") { + // Update setting label with value from server + $("#setwidepthcur").html(msg.data); + } else if(msg.cmd == "updatewidepth") { + // Send current max tokens value to input + $("#setwidepth").val(parseInt(msg.data)); + $("#setwidepthcur").html(msg.data); + } else if(msg.cmd == "updateuseprompt") { + // Update toggle state + $("#setuseprompt").prop('checked', msg.data).change(); + } + }); + + socket.on('disconnect', function() { + connect_status.html("<b>Lost connection...</b>"); + connect_status.removeClass("color_green"); + connect_status.addClass("color_orange"); + }); + + // Bind actions to UI buttons + button_send.on("click", function(ev) { + dosubmit(); + }); + + button_actretry.on("click", function(ev) { + socket.send({'cmd': 'retry', 'data': ''}); + hidegenseqs(); + }); + + button_actback.on("click", function(ev) { + socket.send({'cmd': 'back', 'data': ''}); + hidegenseqs(); + }); + + button_actedit.on("click", function(ev) { + socket.send({'cmd': 'edit', 'data': ''}); + }); + + button_delete.on("click", function(ev) { + socket.send({'cmd': 'delete', 'data': ''}); + }); + + button_actmem.on("click", function(ev) { + socket.send({'cmd': 'memory', 'data': ''}); + }); + + button_savetofile.on("click", function(ev) { + socket.send({'cmd': 'savetofile', 'data': ''}); + }); + + button_loadfrfile.on("click", function(ev) { + socket.send({'cmd': 'loadfromfile', 'data': ''}); + }); + + button_import.on("click", function(ev) { + socket.send({'cmd': 'import', 'data': ''}); + }); + + button_importwi.on("click", function(ev) { + socket.send({'cmd': 'importwi', 'data': ''}); + }); + + button_settings.on("click", function(ev) { + $('#settingsmenu').slideToggle("slow"); + }); + + button_format.on("click", function(ev) { + $('#formatmenu').slideToggle("slow"); + }); + + popup_close.on("click", function(ev) { + socket.send({'cmd': 'importcancel', 'data': ''}); + }); + + popup_accept.on("click", function(ev) { + socket.send({'cmd': 'importaccept', 'data': ''}); + }); + + button_actwi.on("click", function(ev) { + socket.send({'cmd': 'wi', 'data': ''}); + }); + + button_impaidg.on("click", function(ev) { + showAidgPopup(); + }); + + aidg_close.on("click", function(ev) { + hideAidgPopup(); + }); + + aidg_accept.on("click", function(ev) { + sendAidgImportRequest(); + }); + + button_save.on("click", function(ev) { + socket.send({'cmd': 'saverequest', 'data': ''}); + }); + + button_saveas.on("click", function(ev) { + showSaveAsPopup(); + }); + + saveas_close.on("click", function(ev) { + hideSaveAsPopup(); + socket.send({'cmd': 'clearoverwrite', 'data': ''}); + }); + + saveas_accept.on("click", function(ev) { + sendSaveAsRequest(); + }); + + button_load.on("click", function(ev) { + socket.send({'cmd': 'loadlistrequest', 'data': ''}); + }); + + load_close.on("click", function(ev) { + hideLoadPopup(); + }); + + load_accept.on("click", function(ev) { + socket.send({'cmd': 'loadrequest', 'data': ''}); + hideLoadPopup(); + }); + + button_newgame.on("click", function(ev) { + showNewStoryPopup(); + }); + + ns_accept.on("click", function(ev) { + socket.send({'cmd': 'newgame', 'data': ''}); + hideNewStoryPopup(); + }); + + ns_close.on("click", function(ev) { + hideNewStoryPopup(); + }); + + button_rndgame.on("click", function(ev) { + showRandomStoryPopup(); + }); + + rs_accept.on("click", function(ev) { + socket.send({'cmd': 'rndgame', 'data': ''}); + hideRandomStoryPopup(); + }); + + rs_close.on("click", function(ev) { + hideRandomStoryPopup(); + }); + + anote_slider.on("input", function () { + socket.send({'cmd': 'anotedepth', 'data': $(this).val()}); + }); + + saveasinput.on("input", function () { + if(saveasinput.val() == "") { + disableButtons([saveas_accept]); + } else { + enableButtons([saveas_accept]); + } + hide([saveasoverwrite]); + }); + + // Bind Enter button to submit + input_text.keydown(function (ev) { + if (ev.which == 13 && !shift_down) { + do_clear_ent = true; + dosubmit(); + } else if(ev.which == 16) { + shift_down = true; + } + }); + + // Enter to submit, but not if holding shift + input_text.keyup(function (ev) { + if (ev.which == 13 && do_clear_ent) { + input_text.val(""); + do_clear_ent = false; + } else if(ev.which == 16) { + shift_down = false; + } + }); + + aidgpromptnum.keydown(function (ev) { + if (ev.which == 13) { + sendAidgImportRequest(); + } + }); + + saveasinput.keydown(function (ev) { + if (ev.which == 13 && saveasinput.val() != "") { + sendSaveAsRequest(); + } + }); +}); + diff --git a/static/custom.css b/static/custom.css index 0fa720ca..f27bce24 100644 --- a/static/custom.css +++ b/static/custom.css @@ -271,6 +271,12 @@ chunk { margin-top: 200px; } +#rspopup { + width: 800px; + background-color: #262626; + margin-top: 200px; +} + /*================= Classes =================*/ .aidgpopupcontent { diff --git a/templates/index.html b/templates/index.html index 6efac6c5..a334f905 100644 --- a/templates/index.html +++ b/templates/index.html @@ -27,8 +27,12 @@ </button> <div class="collapse navbar-collapse" id="navbarNavDropdown"> <ul class="nav navbar-nav"> - <li class="nav-item"> - <a class="nav-link" href="#" id="btn_newgame">New Story</a> + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">New Game</a> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#" id="btn_newgame">Blank Story</a> + <a class="dropdown-item" href="#" id="btn_rndgame">Random Story</a> + </div> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Save</a> @@ -222,5 +226,28 @@ </div> </div> </div> + <div class="popupcontainer hidden" id="rndgamecontainer"> + <div id="rspopup"> + <div class="popuptitlebar"> + <div class="popuptitletext">Really Start A Random Story?</div> + </div> + <div class="aidgpopuplistheader"> + <br> + Story quality and topic depends on the model and your settings/suggestion (Around 0.5 temp is recommended).<br> + This feature works best with finetuned models like GPT-Neo-AID or GPT-Neo-Horni but is limited to what the AI knows.<br> + If you get random spam then your model is not capable of using this feature and if you get unrelated stories it does not understand the topic.<br> + Generated results are unfiltered and can be offensive or unsuitable for children.<br><br> + Unsaved data will be lost.<br><br> + Below you can input a genre suggestion for the AI to loosely base the story on (For example Horror or Cowboy).<br> + </div> + <div class="aidgpopupcontent"> + <input class="form-control" type="text" placeholder="Story Genre Suggestion (Leave blank for fully random)" id="topic"> + </div> + <div class="popupfooter"> + <button type="button" class="btn btn-primary" id="btn_rsaccept">Accept</button> + <button type="button" class="btn btn-primary" id="btn_rsclose">Cancel</button> + </div> + </div> + </div> </body> -</html> \ No newline at end of file +</html>