Working options.

This commit is contained in:
ebolam
2022-06-26 16:36:07 -04:00
parent 4c357abd78
commit b906742f61
9 changed files with 339 additions and 296 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -319,7 +319,19 @@ gensettingstf = [
"menu_path": "user",
"classname": "user",
"name": "debug"
}
},
{
"uitype": "dropdown",
"unit": "text",
"label": "Story Mode",
"id": "actionmode",
"default": 0,
"tooltip": "Choose the mode of KoboldAI",
"menu_path": "Story",
"classname": "story",
"name": "actionmode",
'children': [{'text': 'Story', 'value': 0}, {'text':'Adventure','value':1}, {'text':'Chat', 'value':2}]
}
]
gensettingsik =[{

View File

@@ -1,8 +1,11 @@
from flask_socketio import emit, join_room, leave_room, rooms
import os
import re
import os, re, time, threading
import socketio as socketio_client
socketio = None
main_thread_id = threading.get_ident()
rely_clients = {}
def clean_var_for_emit(value):
if isinstance(value, KoboldStoryRegister):
@@ -12,19 +15,43 @@ def clean_var_for_emit(value):
else:
return value
def process_variable_changes(classname, name, value, old_value):
#Special Case for KoboldStoryRegister
if isinstance(value, KoboldStoryRegister):
print("resetting")
socketio.emit("reset_story", {}, broadcast=True, room="UI_2")
for i in range(len(value.actions)):
socketio.emit("var_changed", {"classname": "actions", "name": "Selected Text", "old_value": None, "value": {"id": i, "text": value[i]}}, broadcast=True, room="UI_2")
socketio.emit("var_changed", {"classname": "actions", "name": "Options", "old_value": None, "value": {"id": i, "options": value.actions[i]['Options']}}, broadcast=True, room="UI_2")
else:
#print("{}: {} changed from {} to {}".format(classname, name, old_value, value))
#if name == "Selected Text":
# print({"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)})
socketio.emit("var_changed", {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, broadcast=True, room="UI_2")
def process_variable_changes(classname, name, value, old_value, debug_message=None):
if socketio is not None:
if debug_message is not None:
print("{} {}: {} changed from {} to {}".format(debug_message, classname, name, old_value, value))
if value != old_value:
#Special Case for KoboldStoryRegister
if isinstance(value, KoboldStoryRegister):
print("We got a story register")
print(value)
socketio.emit("reset_story", {}, broadcast=True, room="UI_2")
for i in range(len(value.actions)):
socketio.emit("var_changed", {"classname": "actions", "name": "Selected Text", "old_value": None, "value": {"id": i, "text": value[i]}}, include_self=True, broadcast=True, room="UI_2")
socketio.emit("var_changed", {"classname": "actions", "name": "Options", "old_value": None, "value": {"id": i, "options": value.actions[i]['Options']}}, include_self=True, broadcast=True, room="UI_2")
else:
#If we got a variable change from a thread other than what the app is run it, eventlet seems to block and no further messages are sent. Instead, we'll rely the message to the app and have the main thread send it
if main_thread_id != threading.get_ident():
if threading.get_ident() in rely_clients:
sio = rely_clients[threading.get_ident()]
else:
start_time = time.time()
print("getting client")
sio = socketio_client.Client()
@sio.event
def connect():
print("I'm connected!")
sio.connect('http://localhost:5000/?rely=true')
rely_clients[threading.get_ident()] = sio
print("got client, took {}".format(time.time()-start_time))
#release no longer used clients
for thread in rely_clients:
if thread not in [x.ident for x in threading.enumerate()]:
del rely_clients[thread]
sio.emit("relay", {"emit": "var_changed", "data": {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, "include_self":True, "broadcast":True, "room":"UI_2"})
else:
socketio.emit("var_changed", {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, include_self=True, broadcast=True, room="UI_2")
#eventlet.sleep()
#socketio.sleep(0)
class settings(object):
@@ -39,7 +66,6 @@ class settings(object):
class model_settings(settings):
local_only_variables = ['badwordsids', 'apikey', '_class_init']
settings_name = "model"
__class_initialized = False
def __init__(self):
self.model = "" # Model ID string chosen at startup
self.model_type = "" # Model Type (Automatically taken from the model config)
@@ -75,26 +101,20 @@ class model_settings(settings):
self.presets = [] # Holder for presets
self.selected_preset = ""
#Must be at end of __init__
self.__class_initialized = True
def __setattr__(self, name, value):
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if self.__class_initialized and name != '__class_initialized':
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
#Since I haven't migrated the old_ui to use the new actions class for options, let's sync the metadata and options here
if name == 'actions_metadata':
print(value)
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
class story_settings(settings):
#local_only_variables = ['generated_tkns']
local_only_variables = []
settings_name = "story"
__class_initialized = False
def __init__(self):
self.lastact = "" # The last action received from the user
self.submission = "" # Same as above, but after applying input formatting
@@ -138,21 +158,17 @@ class story_settings(settings):
self.dynamicscan = False
self.recentedit = False
#Must be at end of __init__
self.__class_initialized = True
def __setattr__(self, name, value):
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if self.__class_initialized and name != '__class_initialized':
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
class user_settings(settings):
local_only_variables = []
settings_name = "user"
__class_initialized = False
def __init__(self):
self.wirmvwhtsp = False # Whether to remove leading whitespace from WI entries
self.widepth = 3 # How many historical actions to scan for WI hits
@@ -172,22 +188,18 @@ class user_settings(settings):
self.nogenmod = False
self.debug = False # If set to true, will send debug information to the client for display
#Must be at end of __init__
self.__class_initialized = True
def __setattr__(self, name, value):
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if self.__class_initialized and name != '__class_initialized':
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
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']
settings_name = "system"
__class_initialized = False
def __init__(self):
self.noai = False # Runs the script without starting up the transformers pipeline
self.aibusy = False # Stops submissions while the AI is working
@@ -234,16 +246,13 @@ class system_settings(settings):
self.use_colab_tpu = os.environ.get("COLAB_TPU_ADDR", "") != "" or os.environ.get("TPU_NAME", "") != "" # Whether or not we're in a Colab TPU instance or Kaggle TPU instance and are going to use the TPU rather than the CPU
self.aria2_port = 6799 #Specify the port on which aria2's RPC interface will be open if aria2 is installed (defaults to 6799)
#Must be at end of __init__
self.__class_initialized = True
def __setattr__(self, name, value):
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if self.__class_initialized and name != '__class_initialized':
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
#Put variable change actions here
if name not in self.local_only_variables and name[0] != "_":
process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value)
class KoboldStoryRegister(object):
@@ -330,17 +339,10 @@ class KoboldStoryRegister(object):
self.action_count+=1
if self.action_count in self.actions:
self.actions[self.action_count]["Selected Text"] = text
print("looking for old option that matches")
for item in self.actions[self.action_count]["Options"]:
if item['text'] == text:
print("found it")
old_options = self.actions[self.action_count]["Options"]
del item
print("old: ")
print(old_options)
print()
print("New: ")
print(self.actions[self.action_count]["Options"])
process_variable_changes("actions", "Options", {"id": self.action_count, "options": self.actions[self.action_count]["Options"]}, {"id": self.action_count, "options": old_options})
else:
@@ -348,25 +350,23 @@ class KoboldStoryRegister(object):
process_variable_changes("actions", "Selected Text", {"id": self.action_count, "text": text}, None)
def append_options(self, option_list):
print("appending options for {}".format(self.action_count+1))
if self.action_count+1 in self.actions:
print("1")
old_options = self.actions[self.action_count+1]["Options"]
old_options = self.actions[self.action_count+1]["Options"].copy()
self.actions[self.action_count+1]['Options'].extend([{"text": x, "Pinned": False, "Previous Selection": False, "Edited": False} for x in option_list])
for item in option_list:
process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options})
else:
print("2")
old_options = None
self.actions[self.action_count+1] = {"Selected Text": "", "Options": [{"text": x, "Pinned": False, "Previous Selection": False, "Edited": False} for x in option_list]}
process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options})
process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options}, debug_message="wtf")
def clear_unused_options(self, pointer=None):
print("clearing options for {}".format(self.action_count+1))
new_options = []
old_options = None
if pointer is None:
pointer = self.action_count+1
if pointer in self.actions:
old_options = self.actions[pointer]["Options"]
old_options = self.actions[pointer]["Options"].copy()
self.actions[pointer]["Options"] = [x for x in self.actions[pointer]["Options"] if x["Pinned"] or x["Previous Selection"] or x["Edited"]]
new_options = self.actions[pointer]["Options"]
process_variable_changes("actions", "Options", {"id": pointer, "options": new_options}, {"id": pointer, "options": old_options})
@@ -382,20 +382,20 @@ class KoboldStoryRegister(object):
def set_pin(self, action_step, option_number):
if action_step in self.actions:
if option_number < len(self.actions[action_step]['Options']):
old_options = self.actions[action_step]["Options"]
old_options = self.actions[action_step]["Options"].copy()
self.actions[action_step]['Options'][option_number]['Pinned'] = True
process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options})
def unset_pin(self, action_step, option_number):
if action_step in self.actions:
old_options = self.actions[action_step]["Options"]
old_options = self.actions[action_step]["Options"].copy()
if option_number < len(self.actions[action_step]['Options']):
self.actions[action_step]['Options'][option_number]['Pinned'] = False
process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options})
def use_option(self, action_step, option_number):
if action_step in self.actions:
old_options = self.actions[action_step]["Options"]
old_options = self.actions[action_step]["Options"].copy()
old_text = self.actions[action_step]["Selected Text"]
if option_number < len(self.actions[action_step]['Options']):
self.actions[action_step]["Selected Text"] = self.actions[action_step]['Options'][option_number]['text']
@@ -405,7 +405,7 @@ class KoboldStoryRegister(object):
def delete_action(self, action_id):
if action_id in self.actions:
old_options = self.actions[action_id]["Options"]
old_options = self.actions[action_id]["Options"].copy()
old_text = self.actions[action_id]["Selected Text"]
self.actions[action_id]["Options"].append({"text": self.actions[action_id]["Selected Text"], "Pinned": False, "Previous Selection": True, "Edited": False})
self.actions[action_id]["Selected Text"] = ""
@@ -468,7 +468,7 @@ class KoboldStoryRegister(object):
return []
else:
if self.action_count+1 in self.actions:
return [[x, "pinned" if x['Pinned'] else 'normal'] for x in self.actions[self.action_count+1]["Options"] if x["Edited"] == False and x['Previous Selection'] == False]
return [[x['text'], "pinned" if x['Pinned'] else 'normal'] for x in self.actions[self.action_count+1]["Options"] if x["Edited"] == False and x['Previous Selection'] == False]
else:
return []
@@ -495,6 +495,12 @@ class KoboldStoryRegister(object):
return [x for x in self.actions[self.action_count+1]['Options'] if x['Pinned'] or x['Previous Selection']]
else:
return []
def __setattr__(self, name, value):
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if name == 'action_count':
process_variable_changes("actions", "Action Count", value, old_value)

View File

@@ -1359,7 +1359,6 @@ function setStartState() {
function parsegenseqs(seqs) {
seqselcontents.html("");
console.log(seqs);
var i;
for(i=0; i<seqs.length; i++) {
//setup selection data
@@ -2081,7 +2080,7 @@ $(document).ready(function(){
seqselcontents = $("#seqselcontents");
// Connect to SocketIO server
socket = io.connect(window.document.origin, {transports: ['polling', 'websocket'], closeOnBeforeunload: false});
socket = io.connect(window.document.origin, {transports: ['polling', 'websocket'], closeOnBeforeunload: false, query:{"ui": "1"}});
socket.on('from_server', function(msg) {
//console.log(msg);

View File

@@ -251,7 +251,7 @@
filter: brightness(85%);
}
.settings_menu select {
.settings_select {
color: black;
margin-left: auto;
margin-right: 25px;
@@ -341,9 +341,9 @@ body {
/* grid-template-areas: "menuicon gamescreen lefticon"
"menuicon actions lefticon"
"menuicon inputrow lefticon";*/
grid-template-areas: "menuicon gamescreen lefticon"
"menuicon inputrow lefticon";
grid-template-columns: 30px auto 20px;
grid-template-areas: "menuicon gamescreen options lefticon"
"menuicon inputrow inputrow lefticon";
grid-template-columns: 30px auto fit-content(30%) 20px;
/* grid-template-rows: auto 40px 100px;*/
grid-template-rows: auto 100px;
}
@@ -380,6 +380,11 @@ body {
color: var(--text_edit);
}
.sequence {
margin-top: 10px;
grid-area: options;
background-color: var(--gamescreen_background);
}
table.sequence {
width: 100%;

View File

@@ -3,7 +3,9 @@ socket = io.connect(window.location.origin, {transports: ['polling', 'websocket'
//Let's register our server communications
socket.on('connect', function(){connect();});
socket.on('disconnect', function(){disconnect();});
socket.on("disconnect", (reason, details) => {
console.log("Lost connection from: "+reason); // "transport error"
});
socket.on('reset_story', function(){reset_story();});
socket.on('var_changed', function(data){var_changed(data);});
//socket.onAny(function(event_name, data) {console.log({"event": event_name, "data": data});});
@@ -20,6 +22,7 @@ function disconnect() {
}
function reset_story() {
console.log("Resetting story");
var story_area = document.getElementById('Selected Text');
while (story_area.firstChild) {
story_area.removeChild(story_area.firstChild);
@@ -43,7 +46,7 @@ function fix_text(val) {
}
function create_options(data) {
console.log(data.value.options);
console.log(data);
if (document.getElementById("Select Options Chunk "+data.value.id)) {
var option_chunk = document.getElementById("Select Options Chunk "+data.value.id)
} else {
@@ -200,7 +203,7 @@ function var_changed(data) {
} else {
var elements_to_change = document.getElementsByClassName("var_sync_"+data.classname+"_"+data.name);
for (item of elements_to_change) {
if (item.tagName.toLowerCase() === 'input') {
if ((item.tagName.toLowerCase() === 'input') || (item.tagName.toLowerCase() === 'select')) {
item.value = fix_text(data.value);
} else {
item.textContent = fix_text(data.value);

File diff suppressed because one or more lines are too long

View File

@@ -37,8 +37,9 @@
<span id="prompt" class="var_sync_story_prompt rawtext"></span>
<span id="Selected Text" class="rawtext"></span>
</div>
<div id="selectoptions" class="sequence"></div>
</div>
<!------------ Sequences --------------------->
<div id="Select Options" class="sequence"></div>
<!------------ Input Area--------------------->
<div class="inputrow">
<textarea id="input_text" placeholder="Enter text here"></textarea>
@@ -54,9 +55,7 @@
<!------------ Right Flyout Menu--------------------->
<div id="rightSideMenu" class="rightSideMenu"> Status:<hr>
options:
<div id="Select Options"></div>
<br/>
</div>
</body>

View File

@@ -26,8 +26,8 @@
{% elif item["uitype"] == "toggle" %}
<input type=checkbox id="{{ item['classname'] }}_{{ item['name'] }}" class="setting_item_input var_sync_{{ item['classname'] }}_{{ item['name'] }}"
data-size="mini" data-onstyle="success" data-toggle="toggle" onchange='socket.emit("var_change", {"ID": this.id, "value": this.checked});'>
{% elif item['uuitype'] == "dropdown" %}
<select id="{{ item['classname'] }}_{{ item['name'] }}" class="setting_item_input var_sync_{{ item['classname'] }}_{{ item['name'] }}" onclick='socket.emit("var_change", {"ID": this.id, "value": this.value});'>
{% elif item['uitype'] == "dropdown" %}
<select id="{{ item['classname'] }}_{{ item['name'] }}" class="settings_select var_sync_{{ item['classname'] }}_{{ item['name'] }}" onclick='socket.emit("var_change", {"ID": this.id, "value": this.value});'>
{% for option in item['children'] %}
<option value="{{ option['value'] }}">{{ option["text"] }}</option>
{% endfor %}