diff --git a/aiserver.py b/aiserver.py
index ba583480..cb282e5b 100644
--- a/aiserver.py
+++ b/aiserver.py
@@ -6,6 +6,7 @@
# External packages
from os import path, getcwd
+import re
import tkinter as tk
from tkinter import messagebox
import json
@@ -96,6 +97,10 @@ class vars:
saveow = False # Whether or not overwrite confirm has been displayed
genseqs = [] # Temporary storage for generated sequences
useprompt = True # Whether to send the full prompt with every submit action
+ acregex_ai = re.compile(r'\n* *>(.|\n)*') # Pattern for matching adventure actions from the AI so we can remove them
+ acregex_ui = re.compile(r'^ *(>.*)$', re.MULTILINE) # Pattern for matching actions in the HTML-escaped story so we can apply colouring, etc (make sure to encase part to format in parentheses)
+ actionmode = 1
+ adventure = False
#==================================================================#
# Function to get model selection at startup
@@ -399,7 +404,7 @@ def get_message(msg):
# Submit action
if(msg['cmd'] == 'submit'):
if(vars.mode == "play"):
- actionsubmit(msg['data'])
+ actionsubmit(msg['data'], actionmode=msg['actionmode'])
elif(vars.mode == "edit"):
editsubmit(msg['data'])
elif(vars.mode == "memory"):
@@ -531,6 +536,10 @@ def get_message(msg):
elif(msg['cmd'] == 'setuseprompt'):
vars.useprompt = msg['data']
settingschanged()
+ elif(msg['cmd'] == 'setadventure'):
+ vars.adventure = msg['data']
+ settingschanged()
+ refresh_story()
elif(msg['cmd'] == 'importwi'):
wiimportrequest()
@@ -543,7 +552,7 @@ def setStartState():
txt = txt + "Please load a game or enter a prompt below to begin!"
else:
txt = txt + "Please load or import a story to read. There is no AI in this mode."
- emit('from_server', {'cmd': 'updatescreen', 'data': txt})
+ emit('from_server', {'cmd': 'updatescreen', 'gamestarted': vars.gamestarted, 'data': txt})
emit('from_server', {'cmd': 'setgamestate', 'data': 'start'})
#==================================================================#
@@ -583,6 +592,7 @@ def savesettings():
js["numseqs"] = vars.numseqs
js["widepth"] = vars.widepth
js["useprompt"] = vars.useprompt
+ js["adventure"] = vars.adventure
# Write it
file = open("client.settings", "w")
@@ -625,6 +635,8 @@ def loadsettings():
vars.widepth = js["widepth"]
if("useprompt" in js):
vars.useprompt = js["useprompt"]
+ if("adventure" in js):
+ vars.adventure = js["adventure"]
file.close()
@@ -639,11 +651,19 @@ def settingschanged():
#==================================================================#
# Take input text from SocketIO and decide what to do with it
#==================================================================#
-def actionsubmit(data):
+def actionsubmit(data, actionmode=0):
# Ignore new submissions if the AI is currently busy
if(vars.aibusy):
return
set_aibusy(1)
+
+ vars.actionmode = actionmode
+
+ # "Action" mode
+ if(actionmode == 1):
+ data = data.strip().lstrip('>')
+ data = re.sub(r'\n+', ' ', data)
+ data = f"\n\n> {data}\n"
# If we're not continuing, store a copy of the raw input
if(data != ""):
@@ -656,7 +676,7 @@ def actionsubmit(data):
vars.prompt = data
if(not vars.noai):
# Clear the startup text from game screen
- emit('from_server', {'cmd': 'updatescreen', 'data': 'Please wait, generating story...'})
+ emit('from_server', {'cmd': 'updatescreen', 'gamestarted': vars.gamestarted, 'data': 'Please wait, generating story...'})
calcsubmit(data) # Run the first action through the generator
else:
refresh_story()
@@ -665,7 +685,8 @@ def actionsubmit(data):
# Dont append submission if it's a blank/continue action
if(data != ""):
# Apply input formatting & scripts before sending to tokenizer
- data = applyinputformatting(data)
+ if(vars.actionmode == 0):
+ data = applyinputformatting(data)
# Store the result in the Action log
vars.actions.append(data)
@@ -1076,6 +1097,10 @@ def applyinputformatting(txt):
def applyoutputformatting(txt):
# Use standard quotes and apostrophes
txt = utils.fixquotes(txt)
+
+ # Adventure mode clipping of all characters after '>'
+ if(vars.adventure):
+ txt = vars.acregex_ai.sub('', txt)
# Trim incomplete sentences
if(vars.formatoptns["frmttriminc"]):
@@ -1085,7 +1110,7 @@ def applyoutputformatting(txt):
txt = utils.replaceblanklines(txt)
# Remove special characters
if(vars.formatoptns["frmtrmspch"]):
- txt = utils.removespecialchars(txt)
+ txt = utils.removespecialchars(txt, vars)
return txt
@@ -1095,8 +1120,10 @@ def applyoutputformatting(txt):
def refresh_story():
text_parts = ['', html.escape(vars.prompt), '']
for idx, item in enumerate(vars.actions, start=1):
- text_parts.extend(('', html.escape(item), ''))
- emit('from_server', {'cmd': 'updatescreen', 'data': formatforhtml(''.join(text_parts))})
+ if vars.adventure: # Add special formatting to adventure actions
+ item = vars.acregex_ui.sub('\\1', html.escape(item))
+ text_parts.extend(('', item, ''))
+ emit('from_server', {'cmd': 'updatescreen', 'gamestarted': vars.gamestarted, 'data': formatforhtml(''.join(text_parts))})
#==================================================================#
# Sends the current generator settings to the Game Menu
@@ -1120,6 +1147,7 @@ def refresh_settings():
emit('from_server', {'cmd': 'updateanotedepth', 'data': vars.andepth})
emit('from_server', {'cmd': 'updatewidepth', 'data': vars.widepth})
emit('from_server', {'cmd': 'updateuseprompt', 'data': vars.useprompt})
+ emit('from_server', {'cmd': 'updateadventure', 'data': vars.adventure})
emit('from_server', {'cmd': 'updatefrmttriminc', 'data': vars.formatoptns["frmttriminc"]})
emit('from_server', {'cmd': 'updatefrmtrmblln', 'data': vars.formatoptns["frmtrmblln"]})
@@ -1820,5 +1848,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)
+ #socketio.run(app, host='0.0.0.0', port=5000)
+ socketio.run(app)
diff --git a/gensettings.py b/gensettings.py
index eb914139..da3aaa76 100644
--- a/gensettings.py
+++ b/gensettings.py
@@ -85,6 +85,17 @@ gensettingstf = [{
"step": 1,
"default": 1,
"tooltip": "Whether the prompt should be sent in the context of every action."
+ },
+ {
+ "uitype": "toggle",
+ "unit": "bool",
+ "label": "Adventure Mode",
+ "id": "setadventure",
+ "min": 0,
+ "max": 1,
+ "step": 1,
+ "default": 0,
+ "tooltip": "Turn this on if you are playing a Choose your Adventure model."
}]
gensettingsik =[{
@@ -141,6 +152,17 @@ gensettingsik =[{
"step": 1,
"default": 1,
"tooltip": "Whether the prompt should be sent in the context of every action."
+ },
+ {
+ "uitype": "toggle",
+ "unit": "bool",
+ "label": "Adventure Mode",
+ "id": "setadventure",
+ "min": 0,
+ "max": 1,
+ "step": 1,
+ "default": 0,
+ "tooltip": "Turn this on if you are playing a Choose your Adventure model."
}]
formatcontrols = [{
diff --git a/readme.txt b/readme.txt
index 9ab782bb..7b4d93c4 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,6 +1,13 @@
This branch will eventually be used for a community edition of KoboldAI, uniting the different community made editions.
-For now it is a WIP branch with Random Story Generation and better default settings.
+For now it is a WIP branch as I integrate the community features.
+Once done i will be replacing this with a better page describing KoboldAI.
---
Looking for ColabKobold? Check the different branches on my account.
+
+---
+Contains work from :
+- All the original KoboldAI creators
+- Henky!! (Random Story Generator / Setting Optimizations)
+- VE_FORBRYDERNE (Adventure Mode)
\ No newline at end of file
diff --git a/static/application - Copy.js b/static/application - Copy.js
deleted file mode 100644
index 71c066d4..00000000
--- a/static/application - Copy.js
+++ /dev/null
@@ -1,981 +0,0 @@
-//=================================================================//
-// 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("
\
-
\
-
\
- "+ob.label+" ?"+ob.tooltip+"\
-
\
-
\
- "+ob.default+"\
-
\
-
\
-
\
- \
-
\
-
\
-
\
- "+ob.min+"\
-
\
-
\
- "+ob.max+"\
-
\
-
\
-
");
- // 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("
\
- \
- "+ob.label+" \
- ?"+ob.tooltip+"\
-
");
- // 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("");
- }
- // Get reference to the last child column
- var ref = $("#formatmenu > div").last();
- // Add format block to Format Menu
- ref.append("
");
- // 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("
\
-
\
- \
- \
- \
-
\
-
\
- \
-
\
-
\
- \
-
\
-
");
- // 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");
-}
-
-function hideWaitAnimation() {
- $('#waitanim').remove();
-}
-
-function hide(refs) {
- for(i=0; i *', 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\
-
");
- // 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("
\
- \
- "+ob.label+" \
- ?"+ob.tooltip+"\
-
");
- // 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("");
- }
- // Get reference to the last child column
- var ref = $("#formatmenu > div").last();
- // Add format block to Format Menu
- ref.append("
");
- // 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("
\
-
\
- \
- \
- \
-
\
-
\
- \
-
\
-
\
- \
-
\
-
");
- // 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");
-}
-
-function hideWaitAnimation() {
- $('#waitanim').remove();
-}
-
-function hide(refs) {
- for(i=0; i *', 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\
-