back, redo, retry functional

This commit is contained in:
ebolam
2022-06-26 21:06:06 -04:00
parent b906742f61
commit 057f3dd92d
6 changed files with 232 additions and 107 deletions

View File

@@ -3407,6 +3407,9 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
for i in range(model_settings.numseqs):
genout.append({"generated_text": system_settings.lua_koboldbridge.outputs[i+1]})
assert type(genout[-1]["generated_text"]) is str
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"], flash=False)
refresh_story()
@@ -3466,6 +3469,9 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
for i in range(model_settings.numseqs):
genout.append({"generated_text": system_settings.lua_koboldbridge.outputs[i+1]})
assert type(genout[-1]["generated_text"]) is str
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"])
if(not system_settings.abort and system_settings.lua_koboldbridge.restart_sequence is not None):
@@ -3893,6 +3899,9 @@ def generate(txt, minimum, maximum, found_entries=None):
else:
genout = [{"generated_text": utils.decodenewlines(tokenizer.decode(tokens[-already_generated:]))} for tokens in genout]
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"])
else:
@@ -3947,11 +3956,7 @@ def genselect(genout):
print("{0}[Result {1}]\n{2}{3}".format(colors.CYAN, i, result["generated_text"], colors.END))
i += 1
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options_no_edits()]
# Store sequences in memory until selection is made
story_settings.genseqs = genout
@@ -4046,7 +4051,11 @@ def sendtocolab(txt, min, max):
genout.append(system_settings.lua_koboldbridge.outputs[i+1])
assert type(genout[-1]) is str
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0])
else:
# Convert torch output format to transformers
@@ -4195,13 +4204,16 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None):
else:
genout = [{"generated_text": utils.decodenewlines(tokenizer.decode(txt))} for txt in genout]
if(len(genout) == 1):
genresult(genout[0]["generated_text"])
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if(len(story_settings.actions.get_current_options()) == 1):
genresult(story_settings.actions.get_current_options()[0])
else:
if(system_settings.lua_koboldbridge.restart_sequence is not None and system_settings.lua_koboldbridge.restart_sequence > 0):
genresult(genout[system_settings.lua_koboldbridge.restart_sequence-1]["generated_text"])
else:
genselect(genout)
genselect([{"generated_text": x} for x in story_settings.actions.get_current_options()])
set_aibusy(0)
@@ -4943,7 +4955,9 @@ def oairequest(txt, min, max):
{"generated_text": utils.decodenewlines(txt)}
for txt in outputs]
story_settings.actions.clear_unused_options()
story_settings.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in story_settings.actions.get_current_options()]
if (len(genout) == 1):
genresult(genout[0]["generated_text"])
else:
@@ -5794,7 +5808,7 @@ def new_ui_index():
@socketio.on('Set Selected Text')
def UI_2_Set_Selected_Text(data):
print("Updating Selected Text: {}".format(data))
story_settings.actions.use_option(int(data['chunk']), int(data['option']))
story_settings.actions.use_option(int(data['option']), action_step=int(data['chunk']))
#==================================================================#
# Event triggered when user clicks the submit button
@@ -5820,6 +5834,7 @@ def UI_2_Pinning(data):
#==================================================================#
@socketio.on('back')
def UI_2_back(data):
print("back")
ignore = story_settings.actions.pop()
#==================================================================#
@@ -5827,8 +5842,19 @@ def UI_2_back(data):
#==================================================================#
@socketio.on('redo')
def UI_2_redo(data):
pass
if len(story_settings.actions.get_current_options()) == 1:
story_settings.actions.use_option(0)
#==================================================================#
# Event triggered when user clicks the redo button
#==================================================================#
@socketio.on('retry')
def UI_2_retry(data):
story_settings.actions.clear_unused_options()
system_settings.lua_koboldbridge.feedback = None
story_settings.recentrng = story_settings.recentrngm = None
actionsubmit("", actionmode=story_settings.actionmode)
#==================================================================#
# Event triggered to rely a message
#==================================================================#

View File

@@ -22,9 +22,8 @@ def process_variable_changes(classname, name, value, old_value, debug_message=No
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")
socketio.emit("var_changed", {"classname": "actions", "name": "Action Count", "old_value": None, "value":value.action_count}, 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")
@@ -34,24 +33,19 @@ def process_variable_changes(classname, name, value, old_value, debug_message=No
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!")
pass
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"})
sio.emit("relay", ["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"}])
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):
@@ -350,17 +344,15 @@ 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:
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])
else:
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}, debug_message="wtf")
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})
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:
@@ -393,13 +385,19 @@ class KoboldStoryRegister(object):
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):
def use_option(self, option_number, action_step=None):
if action_step is None:
action_step = self.action_count+1
if action_step in self.actions:
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']
del self.actions[action_step]['Options'][option_number]
#If this is the current spot in the story, advance
if action_step-1 == self.action_count:
self.action_count+=1
socketio.emit("var_changed", {"classname": "actions", "name": "Action Count", "old_value": None, "value":self.action_count}, broadcast=True, room="UI_2")
process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options})
process_variable_changes("actions", "Selected Text", {"id": action_step, "text": self.actions[action_step]["Selected Text"]}, {"id": action_step, "Selected Text": old_text})

View File

@@ -11,4 +11,5 @@ markdown
bleach==4.1.0
sentencepiece
protobuf
accelerate
accelerate
python-socketio[client]

View File

@@ -427,14 +427,19 @@ td.sequence:hover {
.inputrow {
grid-area: inputrow;
display: grid;
grid-template-areas: "textarea submit submit submit"
grid-template-areas: "textarea statusbar statusbar statusbar"
"textarea submit submit submit"
"textarea back redo retry";
grid-template-columns: auto 30px 30px 30px;
grid-template-rows: auto 40px;
grid-template-rows: 0px auto 40px;
gap: 1px;
}
.inputrow.status_bar {
grid-template-rows: 20px auto 40px;
}
.inputrow textarea {
grid-area: textarea;
background-color: var(--textarea_background);
@@ -474,6 +479,25 @@ td.sequence:hover {
display: inline;
}
.statusbar_outer {
color: #000;
background-color: #f1f1f1;
grid-area: statusbar;
height: 20px;
}
.statusbar_outer.hidden {
height: 0px;
}
.statusbar_inner {
background-color: #4CAF50;
text-align: center;
font-size: 0.875em;
}
.inputrow .back {
grid-area: back;
padding: 0px;

View File

@@ -46,86 +46,129 @@ function fix_text(val) {
}
function create_options(data) {
//Set all options before the next chunk to hidden
var option_container = document.getElementById("Select Options");
var current_chunk = parseInt(document.getElementById("action_count").textContent)+1;
var children = option_container.children;
for (var i = 0; i < children.length; i++) {
var chunk = children[i];
if (chunk.id == "Select Options Chunk " + current_chunk) {
chunk.classList.remove("hidden");
console.log(current_chunk);
} else {
chunk.classList.add("hidden");
}
}
console.log(current_chunk);
console.log(data);
if (document.getElementById("Select Options Chunk "+data.value.id)) {
var option_chunk = document.getElementById("Select Options Chunk "+data.value.id)
} else {
var option_area = document.getElementById("Select Options");
var option_chunk = document.createElement("div");
option_chunk.id = "Select Options Chunk "+data.value.id;
option_area.append(option_chunk);
var option_chunk = document.getElementById("Select Options Chunk "+data.value.id)
} else {
var option_area = document.getElementById("Select Options");
var option_chunk = document.createElement("div");
option_chunk.id = "Select Options Chunk "+data.value.id;
option_area.append(option_chunk);
}
//first, let's clear out our existing data
while (option_chunk.firstChild) {
option_chunk.removeChild(option_chunk.firstChild);
}
var table = document.createElement("table");
table.classList.add("sequence");
table.style = "border-spacing: 0;";
//Add pins
i=0;
for (item of data.value.options) {
if (item.Pinned) {
var row = document.createElement("tr");
row.classList.add("sequence");
var textcell = document.createElement("td");
textcell.textContent = item.text;
textcell.classList.add("sequence");
textcell.setAttribute("option_id", i);
textcell.setAttribute("option_chunk", data.value.id);
var iconcell = document.createElement("td");
iconcell.setAttribute("option_id", i);
iconcell.setAttribute("option_chunk", data.value.id);
var icon = document.createElement("span");
icon.id = "Pin_"+i;
icon.classList.add("oi");
icon.setAttribute('data-glyph', "pin");
iconcell.append(icon);
textcell.onclick = function () {
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
};
iconcell.onclick = function () {
socket.emit("Pinning", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id"), "set": false});
};
row.append(textcell);
row.append(iconcell);
table.append(row);
}
//first, let's clear out our existing data
while (option_chunk.firstChild) {
option_chunk.removeChild(option_chunk.firstChild);
i+=1;
}
//Add Redo options
i=0;
for (item of data.value.options) {
if ((item['Previous Selection'])) {
var row = document.createElement("tr");
row.classList.add("sequence");
var textcell = document.createElement("td");
textcell.textContent = item.text;
textcell.classList.add("sequence");
textcell.setAttribute("option_id", i);
textcell.setAttribute("option_chunk", data.value.id);
var iconcell = document.createElement("td");
iconcell.setAttribute("option_id", i);
iconcell.setAttribute("option_chunk", data.value.id);
var icon = document.createElement("span");
icon.id = "Pin_"+i;
icon.classList.add("oi");
icon.setAttribute('data-glyph', "loop-circular");
iconcell.append(icon);
textcell.onclick = function () {
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
};
row.append(textcell);
row.append(iconcell);
table.append(row);
}
var table = document.createElement("table");
table.classList.add("sequence");
table.style = "border-spacing: 0;";
//Add pins
i=0;
for (item of data.value.options) {
if (item.Pinned) {
var row = document.createElement("tr");
row.classList.add("sequence");
var textcell = document.createElement("td");
textcell.textContent = item.text;
textcell.classList.add("sequence");
textcell.setAttribute("option_id", i);
textcell.setAttribute("option_chunk", data.value.id);
var iconcell = document.createElement("td");
iconcell.setAttribute("option_id", i);
iconcell.setAttribute("option_chunk", data.value.id);
var icon = document.createElement("span");
icon.id = "Pin_"+i;
icon.classList.add("oi");
icon.setAttribute('data-glyph', "pin");
iconcell.append(icon);
textcell.onclick = function () {
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
};
iconcell.onclick = function () {
socket.emit("Pinning", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id"), "set": false});
};
row.append(textcell);
row.append(iconcell);
table.append(row);
}
i+=1;
i+=1;
}
//Add general options
i=0;
for (item of data.value.options) {
if (!(item.Edited) && !(item.Pinned) && !(item['Previous Selection'])) {
var row = document.createElement("tr");
row.classList.add("sequence");
var textcell = document.createElement("td");
textcell.textContent = item.text;
textcell.classList.add("sequence");
textcell.setAttribute("option_id", i);
textcell.setAttribute("option_chunk", data.value.id);
var iconcell = document.createElement("td");
iconcell.setAttribute("option_id", i);
iconcell.setAttribute("option_chunk", data.value.id);
var icon = document.createElement("span");
icon.id = "Pin_"+i;
icon.classList.add("oi");
icon.setAttribute('data-glyph', "pin");
icon.setAttribute('style', "filter: brightness(50%);");
iconcell.append(icon);
iconcell.onclick = function () {
socket.emit("Pinning", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id"), "set": true});
};
textcell.onclick = function () {
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
};
row.append(textcell);
row.append(iconcell);
table.append(row);
}
//Add general options
i=0;
for (item of data.value.options) {
if (!(item.Edited) && !(item.Pinned) && !(item['Previous Selection'])) {
var row = document.createElement("tr");
row.classList.add("sequence");
var textcell = document.createElement("td");
textcell.textContent = item.text;
textcell.classList.add("sequence");
textcell.setAttribute("option_id", i);
textcell.setAttribute("option_chunk", data.value.id);
var iconcell = document.createElement("td");
iconcell.setAttribute("option_id", i);
iconcell.setAttribute("option_chunk", data.value.id);
var icon = document.createElement("span");
icon.id = "Pin_"+i;
icon.classList.add("oi");
icon.setAttribute('data-glyph', "pin");
icon.setAttribute('style', "filter: brightness(50%);");
iconcell.append(icon);
iconcell.onclick = function () {
socket.emit("Pinning", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id"), "set": true});
};
textcell.onclick = function () {
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
};
row.append(textcell);
row.append(iconcell);
table.append(row);
}
i+=1;
}
option_chunk.append(table);
i+=1;
}
option_chunk.append(table);
}
function do_story_text_updates(data) {
@@ -187,6 +230,27 @@ function selected_preset(data) {
}
}
function update_status_bar(data) {
var total_tokens = document.getElementById('model_genamt').value;
var percent_complete = data.value/total_tokens*100;
var percent_bar = document.getElementsByClassName("statusbar_inner");
for (item of percent_bar) {
item.setAttribute("style", "width:"+percent_complete+"%");
item.textContent = Math.round(percent_complete)+"%"
if ((percent_complete == 0) || (percent_complete == 100)) {
item.parentElement.classList.add("hidden");
document.getElementById("inputrow_container").classList.remove("status_bar");
} else {
item.parentElement.classList.remove("hidden");
document.getElementById("inputrow_container").classList.add("status_bar");
}
}
if ((percent_complete == 0) || (percent_complete == 100)) {
document.title = "KoboldAI Client";
} else {
document.title = "KoboldAI Client Generating (" + percent_complete + "%)";
}
}
function var_changed(data) {
//Special Case for Story Text
if ((data.classname == "actions") && (data.name == "Selected Text")) {
@@ -201,7 +265,7 @@ function var_changed(data) {
selected_preset(data);
//Basic Data Syncing
} else {
var elements_to_change = document.getElementsByClassName("var_sync_"+data.classname+"_"+data.name);
var elements_to_change = document.getElementsByClassName("var_sync_"+data.classname.replace(" ", "_")+"_"+data.name.replace(" ", "_"));
for (item of elements_to_change) {
if ((item.tagName.toLowerCase() === 'input') || (item.tagName.toLowerCase() === 'select')) {
item.value = fix_text(data.value);
@@ -209,11 +273,19 @@ function var_changed(data) {
item.textContent = fix_text(data.value);
}
}
var elements_to_change = document.getElementsByClassName("var_sync_alt_"+data.classname+"_"+data.name);
//alternative syncing method
var elements_to_change = document.getElementsByClassName("var_sync_alt_"+data.classname.replace(" ", "_")+"_"+data.name.replace(" ", "_"));
for (item of elements_to_change) {
item.setAttribute("server_value", fix_text(data.value));
}
}
//if we're updating generated tokens, let's show that in our status bar
if ((data.classname == 'story') && (data.name == 'generated_tkns')) {
update_status_bar(data);
}
//If we have ai_busy, start the favicon swapping
if ((data.classname == 'system') && (data.name == 'aibusy')) {
if (data.value) {
favicon.start_swap()

View File

@@ -39,15 +39,19 @@
</div>
</div>
<!------------ Sequences --------------------->
<div id="action_count" class="var_sync_actions_Action_Count hidden"></div>
<div id="Select Options" class="sequence"></div>
<!------------ Input Area--------------------->
<div class="inputrow">
<div class="inputrow" id="inputrow_container">
<textarea id="input_text" placeholder="Enter text here"></textarea>
<div class="statusbar_outer">
<div class="statusbar_inner" style="width:25%">25%</div>
</div><br>
<button type="button" class="btn action_button submit var_sync_alt_system_aibusy" id="btnsend" onclick="socket.emit('submit', {'data': document.getElementById('input_text').value});">Submit</button>
<button type="button" class="btn action_button submited var_sync_alt_system_aibusy" id="btnsend"><img src="static/thinking.gif" class="force_center"></button>
<button type="button" class="btn action_button back"><span class="oi" data-glyph="action-undo"></span></button>
<button type="button" class="btn action_button redo"><span class="oi" data-glyph="action-redo"></span></button>
<button type="button" class="btn action_button retry"><span class="oi" data-glyph="loop-circular"></span></button>
<button type="button" class="btn action_button back" onclick="socket.emit('back', {});"><span class="oi" data-glyph="action-undo"></span></button>
<button type="button" class="btn action_button redo" onclick="socket.emit('redo', {});"><span class="oi" data-glyph="action-redo"></span></button>
<button type="button" class="btn action_button retry" onclick="socket.emit('retry', {});"><span class="oi" data-glyph="loop-circular"></span></button>
</div>
<!------------ Right Menu Icon--------------------->
<span class="oi right_menu_icon" data-glyph="chevron-left" onclick="toggle_flyout_right(this)"></span>