mirror of
https://github.com/KoboldAI/KoboldAI-Client.git
synced 2025-06-05 21:59:24 +02:00
Presets and Remaining time updates
This commit is contained in:
339
aiserver.py
339
aiserver.py
@@ -1024,8 +1024,12 @@ def get_model_info(model, directory=""):
|
||||
breakmodel = False
|
||||
else:
|
||||
breakmodel = True
|
||||
if path.exists("settings/{}.breakmodel".format(model.replace("/", "_"))):
|
||||
with open("settings/{}.breakmodel".format(model.replace("/", "_")), "r") as file:
|
||||
if model in ["NeoCustom", "GPT2Custom"]:
|
||||
filename = os.path.basename(os.path.normpath(directory))
|
||||
else:
|
||||
filename = "settings/{}.breakmodel".format(model.replace("/", "_"))
|
||||
if path.exists(filename):
|
||||
with open(filename, "r") as file:
|
||||
data = file.read().split("\n")[:2]
|
||||
if len(data) < 2:
|
||||
data.append("0")
|
||||
@@ -1034,10 +1038,6 @@ def get_model_info(model, directory=""):
|
||||
else:
|
||||
break_values = [layer_count]
|
||||
break_values += [0] * (gpu_count - len(break_values))
|
||||
#print("Model_info: {}".format({'cmd': 'selected_model_info', 'key_value': key_value, 'key':key,
|
||||
# 'gpu':gpu, 'layer_count':layer_count, 'breakmodel':breakmodel,
|
||||
# 'break_values': break_values, 'gpu_count': gpu_count,
|
||||
# 'url': url, 'gpu_names': gpu_names}))
|
||||
emit('from_server', {'cmd': 'selected_model_info', 'key_value': key_value, 'key':key,
|
||||
'gpu':gpu, 'layer_count':layer_count, 'breakmodel':breakmodel,
|
||||
'disk_break_value': disk_blocks, 'accelerate': utils.HAS_ACCELERATE,
|
||||
@@ -1341,10 +1341,10 @@ def patch_transformers():
|
||||
scores: torch.FloatTensor,
|
||||
**kwargs,
|
||||
) -> bool:
|
||||
story_settings.generated_tkns += 1
|
||||
if(system_settings.lua_koboldbridge.generated_cols and story_settings.generated_tkns != system_settings.lua_koboldbridge.generated_cols):
|
||||
raise RuntimeError(f"Inconsistency detected between KoboldAI Python and Lua backends ({story_settings.generated_tkns} != {system_settings.lua_koboldbridge.generated_cols})")
|
||||
if(system_settings.abort or story_settings.generated_tkns >= model_settings.genamt):
|
||||
model_settings.generated_tkns += 1
|
||||
if(system_settings.lua_koboldbridge.generated_cols and model_settings.generated_tkns != system_settings.lua_koboldbridge.generated_cols):
|
||||
raise RuntimeError(f"Inconsistency detected between KoboldAI Python and Lua backends ({model_settings.generated_tkns} != {system_settings.lua_koboldbridge.generated_cols})")
|
||||
if(system_settings.abort or model_settings.generated_tkns >= model_settings.genamt):
|
||||
self.regeneration_required = False
|
||||
self.halt = False
|
||||
return True
|
||||
@@ -1356,11 +1356,11 @@ def patch_transformers():
|
||||
system_settings.lua_koboldbridge.regeneration_required = False
|
||||
|
||||
for i in range(model_settings.numseqs):
|
||||
system_settings.lua_koboldbridge.generated[i+1][story_settings.generated_tkns] = int(input_ids[i, -1].item())
|
||||
system_settings.lua_koboldbridge.generated[i+1][model_settings.generated_tkns] = int(input_ids[i, -1].item())
|
||||
|
||||
if(not story_settings.dynamicscan):
|
||||
return self.regeneration_required or self.halt
|
||||
tail = input_ids[..., -story_settings.generated_tkns:]
|
||||
tail = input_ids[..., -model_settings.generated_tkns:]
|
||||
for i, t in enumerate(tail):
|
||||
decoded = utils.decodenewlines(tokenizer.decode(t))
|
||||
_, found = checkworldinfo(decoded, force_use_txt=True, actions=story_settings._actions)
|
||||
@@ -1970,17 +1970,17 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal
|
||||
return scores
|
||||
|
||||
def tpumtjgenerate_stopping_callback(generated, n_generated, excluded_world_info) -> Tuple[List[set], bool, bool]:
|
||||
story_settings.generated_tkns += 1
|
||||
model_settings.generated_tkns += 1
|
||||
|
||||
assert len(excluded_world_info) == len(generated)
|
||||
regeneration_required = system_settings.lua_koboldbridge.regeneration_required
|
||||
halt = system_settings.abort or not system_settings.lua_koboldbridge.generating or story_settings.generated_tkns >= model_settings.genamt
|
||||
halt = system_settings.abort or not system_settings.lua_koboldbridge.generating or model_settings.generated_tkns >= model_settings.genamt
|
||||
system_settings.lua_koboldbridge.regeneration_required = False
|
||||
|
||||
global past
|
||||
|
||||
for i in range(model_settings.numseqs):
|
||||
system_settings.lua_koboldbridge.generated[i+1][story_settings.generated_tkns] = int(generated[i, tpu_mtj_backend.params["seq"] + n_generated - 1].item())
|
||||
system_settings.lua_koboldbridge.generated[i+1][model_settings.generated_tkns] = int(generated[i, tpu_mtj_backend.params["seq"] + n_generated - 1].item())
|
||||
|
||||
if(not story_settings.dynamicscan or halt):
|
||||
return excluded_world_info, regeneration_required, halt
|
||||
@@ -2068,6 +2068,15 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal
|
||||
sendsettings()
|
||||
refresh_settings()
|
||||
|
||||
#Let's load the presets
|
||||
with open('settings/preset/official.presets') as f:
|
||||
presets = json.load(f)
|
||||
if model_settings.model in presets:
|
||||
model_settings.presets = presets[model_settings.model]
|
||||
elif model_settings.model.replace("/", "_") in presets:
|
||||
model_settings.presets = presets[model_settings.model.replace("/", "_")]
|
||||
else:
|
||||
model_settings.presets = {}
|
||||
|
||||
# Set up Flask routes
|
||||
@app.route('/')
|
||||
@@ -2770,6 +2779,9 @@ def do_connect():
|
||||
return
|
||||
join_room("UI_{}".format(request.args.get('ui')))
|
||||
print("Joining Room UI_{}".format(request.args.get('ui')))
|
||||
if request.args.get("ui") == 2:
|
||||
ui2_connect()
|
||||
return
|
||||
#Send all variables to client
|
||||
model_settings.send_to_ui()
|
||||
story_settings.send_to_ui()
|
||||
@@ -3808,9 +3820,9 @@ def _generate(txt, minimum, maximum, found_entries):
|
||||
break
|
||||
assert genout.ndim >= 2
|
||||
assert genout.shape[0] == model_settings.numseqs
|
||||
if(system_settings.lua_koboldbridge.generated_cols and story_settings.generated_tkns != system_settings.lua_koboldbridge.generated_cols):
|
||||
if(system_settings.lua_koboldbridge.generated_cols and model_settings.generated_tkns != system_settings.lua_koboldbridge.generated_cols):
|
||||
raise RuntimeError("Inconsistency detected between KoboldAI Python and Lua backends")
|
||||
if(already_generated != story_settings.generated_tkns):
|
||||
if(already_generated != model_settings.generated_tkns):
|
||||
raise RuntimeError("WI scanning error")
|
||||
for r in range(model_settings.numseqs):
|
||||
for c in range(already_generated):
|
||||
@@ -3850,7 +3862,7 @@ def _generate(txt, minimum, maximum, found_entries):
|
||||
|
||||
|
||||
def generate(txt, minimum, maximum, found_entries=None):
|
||||
story_settings.generated_tkns = 0
|
||||
model_settings.generated_tkns = 0
|
||||
|
||||
if(found_entries is None):
|
||||
found_entries = set()
|
||||
@@ -3886,7 +3898,7 @@ def generate(txt, minimum, maximum, found_entries=None):
|
||||
return
|
||||
|
||||
for i in range(model_settings.numseqs):
|
||||
system_settings.lua_koboldbridge.generated[i+1][story_settings.generated_tkns] = int(genout[i, -1].item())
|
||||
system_settings.lua_koboldbridge.generated[i+1][model_settings.generated_tkns] = int(genout[i, -1].item())
|
||||
system_settings.lua_koboldbridge.outputs[i+1] = utils.decodenewlines(tokenizer.decode(genout[i, -already_generated:]))
|
||||
|
||||
execute_outmod()
|
||||
@@ -4086,7 +4098,7 @@ def sendtocolab(txt, min, max):
|
||||
# Send text to TPU mesh transformer backend
|
||||
#==================================================================#
|
||||
def tpumtjgenerate(txt, minimum, maximum, found_entries=None):
|
||||
story_settings.generated_tkns = 0
|
||||
model_settings.generated_tkns = 0
|
||||
|
||||
if(found_entries is None):
|
||||
found_entries = set()
|
||||
@@ -4173,7 +4185,7 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None):
|
||||
past = genout
|
||||
for i in range(model_settings.numseqs):
|
||||
system_settings.lua_koboldbridge.generated[i+1] = system_settings.lua_state.table(*genout[i].tolist())
|
||||
system_settings.lua_koboldbridge.generated_cols = story_settings.generated_tkns = genout[0].shape[-1]
|
||||
system_settings.lua_koboldbridge.generated_cols = model_settings.generated_tkns = genout[0].shape[-1]
|
||||
|
||||
except Exception as e:
|
||||
if(issubclass(type(e), lupa.LuaError)):
|
||||
@@ -5196,6 +5208,7 @@ def loadRequest(loadpath, filename=None):
|
||||
# Leave Edit/Memory mode before continuing
|
||||
exitModes()
|
||||
|
||||
|
||||
# Read file contents into JSON object
|
||||
if(isinstance(loadpath, str)):
|
||||
with open(loadpath, "r") as file:
|
||||
@@ -5206,107 +5219,115 @@ def loadRequest(loadpath, filename=None):
|
||||
js = loadpath
|
||||
if(filename is None):
|
||||
filename = "untitled.json"
|
||||
js['v1_loadpath'] = loadpath
|
||||
js['v1_filename'] = filename
|
||||
loadJSON(js)
|
||||
|
||||
# Copy file contents to vars
|
||||
story_settings.gamestarted = js["gamestarted"]
|
||||
story_settings.prompt = js["prompt"]
|
||||
story_settings.memory = js["memory"]
|
||||
story_settings.worldinfo = []
|
||||
story_settings.worldinfo = []
|
||||
story_settings.worldinfo_u = {}
|
||||
story_settings.wifolders_d = {int(k): v for k, v in js.get("wifolders_d", {}).items()}
|
||||
story_settings.wifolders_l = js.get("wifolders_l", [])
|
||||
story_settings.wifolders_u = {uid: [] for uid in story_settings.wifolders_d}
|
||||
story_settings.lastact = ""
|
||||
story_settings.submission = ""
|
||||
story_settings.lastctx = ""
|
||||
story_settings.genseqs = []
|
||||
|
||||
del story_settings.actions
|
||||
story_settings.actions = koboldai_settings.KoboldStoryRegister()
|
||||
actions = collections.deque(js["actions"])
|
||||
|
||||
|
||||
if "actions_metadata" in js:
|
||||
|
||||
if type(js["actions_metadata"]) == dict:
|
||||
temp = js["actions_metadata"]
|
||||
story_settings.actions_metadata = {}
|
||||
#we need to redo the numbering of the actions_metadata since the actions list doesn't preserve it's number on saving
|
||||
if len(temp) > 0:
|
||||
counter = 0
|
||||
temp = {int(k):v for k,v in temp.items()}
|
||||
for i in range(max(temp)+1):
|
||||
if i in temp:
|
||||
story_settings.actions_metadata[counter] = temp[i]
|
||||
counter += 1
|
||||
del temp
|
||||
else:
|
||||
#fix if we're using the old metadata format
|
||||
story_settings.actions_metadata = {}
|
||||
i = 0
|
||||
|
||||
for text in js['actions']:
|
||||
story_settings.actions_metadata[i] = {'Selected Text': text, 'Alternative Text': []}
|
||||
i+=1
|
||||
def loadJSON(json_text_or_dict):
|
||||
if isinstance(json_text_or_dict, str):
|
||||
json_data = json.loads(json_text_or_dict)
|
||||
else:
|
||||
json_data = json_text_or_dict
|
||||
if "file_version" in json_data:
|
||||
if json_data['file_version'] == 2:
|
||||
load_story_v2(json_data)
|
||||
else:
|
||||
load_story_v1(json_data)
|
||||
else:
|
||||
load_story_v1(json_data)
|
||||
|
||||
def load_story_v1(js):
|
||||
loadpath = js['v1_loadpath']
|
||||
filename = js['v1_filename']
|
||||
|
||||
# Copy file contents to vars
|
||||
story_settings.gamestarted = js["gamestarted"]
|
||||
story_settings.prompt = js["prompt"]
|
||||
story_settings.memory = js["memory"]
|
||||
story_settings.worldinfo = []
|
||||
story_settings.worldinfo = []
|
||||
story_settings.worldinfo_u = {}
|
||||
story_settings.wifolders_d = {int(k): v for k, v in js.get("wifolders_d", {}).items()}
|
||||
story_settings.wifolders_l = js.get("wifolders_l", [])
|
||||
story_settings.wifolders_u = {uid: [] for uid in story_settings.wifolders_d}
|
||||
story_settings.lastact = ""
|
||||
story_settings.submission = ""
|
||||
story_settings.lastctx = ""
|
||||
story_settings.genseqs = []
|
||||
|
||||
del story_settings.actions
|
||||
story_settings.actions = koboldai_settings.KoboldStoryRegister()
|
||||
actions = collections.deque(js["actions"])
|
||||
|
||||
|
||||
if "actions_metadata" in js:
|
||||
|
||||
if type(js["actions_metadata"]) == dict:
|
||||
temp = js["actions_metadata"]
|
||||
story_settings.actions_metadata = {}
|
||||
#we need to redo the numbering of the actions_metadata since the actions list doesn't preserve it's number on saving
|
||||
if len(temp) > 0:
|
||||
counter = 0
|
||||
temp = {int(k):v for k,v in temp.items()}
|
||||
for i in range(max(temp)+1):
|
||||
if i in temp:
|
||||
story_settings.actions_metadata[counter] = temp[i]
|
||||
counter += 1
|
||||
del temp
|
||||
else:
|
||||
#fix if we're using the old metadata format
|
||||
story_settings.actions_metadata = {}
|
||||
i = 0
|
||||
|
||||
for text in js['actions']:
|
||||
story_settings.actions_metadata[i] = {'Selected Text': text, 'Alternative Text': []}
|
||||
i+=1
|
||||
else:
|
||||
story_settings.actions_metadata = {}
|
||||
i = 0
|
||||
|
||||
for text in js['actions']:
|
||||
story_settings.actions_metadata[i] = {'Selected Text': text, 'Alternative Text': []}
|
||||
i+=1
|
||||
|
||||
|
||||
if(len(story_settings.prompt.strip()) == 0):
|
||||
while(len(actions)):
|
||||
action = actions.popleft()
|
||||
if(len(action.strip()) != 0):
|
||||
story_settings.prompt = action
|
||||
break
|
||||
else:
|
||||
story_settings.gamestarted = False
|
||||
if(story_settings.gamestarted):
|
||||
for s in actions:
|
||||
story_settings.actions.append(s)
|
||||
|
||||
# Try not to break older save files
|
||||
if("authorsnote" in js):
|
||||
story_settings.authornote = js["authorsnote"]
|
||||
if(len(story_settings.prompt.strip()) == 0):
|
||||
while(len(actions)):
|
||||
action = actions.popleft()
|
||||
if(len(action.strip()) != 0):
|
||||
story_settings.prompt = action
|
||||
break
|
||||
else:
|
||||
story_settings.authornote = ""
|
||||
if("anotetemplate" in js):
|
||||
story_settings.authornotetemplate = js["anotetemplate"]
|
||||
else:
|
||||
story_settings.authornotetemplate = "[Author's note: <|>]"
|
||||
story_settings.gamestarted = False
|
||||
if(story_settings.gamestarted):
|
||||
for s in actions:
|
||||
story_settings.actions.append(s)
|
||||
|
||||
if("worldinfo" in js):
|
||||
num = 0
|
||||
for wi in js["worldinfo"]:
|
||||
story_settings.worldinfo.append({
|
||||
"key": wi["key"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["content"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
"constant": wi.get("constant", False),
|
||||
"uid": None,
|
||||
})
|
||||
while(True):
|
||||
uid = int.from_bytes(os.urandom(4), "little", signed=True)
|
||||
if(uid not in story_settings.worldinfo_u):
|
||||
break
|
||||
story_settings.worldinfo_u[uid] = story_settings.worldinfo[-1]
|
||||
story_settings.worldinfo[-1]["uid"] = uid
|
||||
if(story_settings.worldinfo[-1]["folder"] is not None):
|
||||
story_settings.wifolders_u[story_settings.worldinfo[-1]["folder"]].append(story_settings.worldinfo[-1])
|
||||
num += 1
|
||||
# Try not to break older save files
|
||||
if("authorsnote" in js):
|
||||
story_settings.authornote = js["authorsnote"]
|
||||
else:
|
||||
story_settings.authornote = ""
|
||||
if("anotetemplate" in js):
|
||||
story_settings.authornotetemplate = js["anotetemplate"]
|
||||
else:
|
||||
story_settings.authornotetemplate = "[Author's note: <|>]"
|
||||
|
||||
for uid in story_settings.wifolders_l + [None]:
|
||||
story_settings.worldinfo.append({"key": "", "keysecondary": "", "content": "", "comment": "", "folder": uid, "num": None, "init": False, "selective": False, "constant": False, "uid": None})
|
||||
if("worldinfo" in js):
|
||||
num = 0
|
||||
for wi in js["worldinfo"]:
|
||||
story_settings.worldinfo.append({
|
||||
"key": wi["key"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["content"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
"constant": wi.get("constant", False),
|
||||
"uid": None,
|
||||
})
|
||||
while(True):
|
||||
uid = int.from_bytes(os.urandom(4), "little", signed=True)
|
||||
if(uid not in story_settings.worldinfo_u):
|
||||
@@ -5315,32 +5336,49 @@ def loadRequest(loadpath, filename=None):
|
||||
story_settings.worldinfo[-1]["uid"] = uid
|
||||
if(story_settings.worldinfo[-1]["folder"] is not None):
|
||||
story_settings.wifolders_u[story_settings.worldinfo[-1]["folder"]].append(story_settings.worldinfo[-1])
|
||||
stablesortwi()
|
||||
story_settings.worldinfo_i = [wi for wi in story_settings.worldinfo if wi["init"]]
|
||||
num += 1
|
||||
|
||||
# Save path for save button
|
||||
system_settings.savedir = loadpath
|
||||
for uid in story_settings.wifolders_l + [None]:
|
||||
story_settings.worldinfo.append({"key": "", "keysecondary": "", "content": "", "comment": "", "folder": uid, "num": None, "init": False, "selective": False, "constant": False, "uid": None})
|
||||
while(True):
|
||||
uid = int.from_bytes(os.urandom(4), "little", signed=True)
|
||||
if(uid not in story_settings.worldinfo_u):
|
||||
break
|
||||
story_settings.worldinfo_u[uid] = story_settings.worldinfo[-1]
|
||||
story_settings.worldinfo[-1]["uid"] = uid
|
||||
if(story_settings.worldinfo[-1]["folder"] is not None):
|
||||
story_settings.wifolders_u[story_settings.worldinfo[-1]["folder"]].append(story_settings.worldinfo[-1])
|
||||
stablesortwi()
|
||||
story_settings.worldinfo_i = [wi for wi in story_settings.worldinfo if wi["init"]]
|
||||
|
||||
# Clear loadselect var
|
||||
user_settings.loadselect = ""
|
||||
# Save path for save button
|
||||
system_settings.savedir = loadpath
|
||||
|
||||
# Refresh game screen
|
||||
_filename = filename
|
||||
if(filename.endswith('.json')):
|
||||
_filename = filename[:-5]
|
||||
user_settings.laststory = _filename
|
||||
emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1")
|
||||
setgamesaved(True)
|
||||
sendwi()
|
||||
emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1")
|
||||
refresh_story()
|
||||
emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True, room="UI_1")
|
||||
print("{0}Story loaded from {1}!{2}".format(colors.GREEN, filename, colors.END))
|
||||
# Clear loadselect var
|
||||
user_settings.loadselect = ""
|
||||
|
||||
send_debug()
|
||||
# Refresh game screen
|
||||
_filename = filename
|
||||
if(filename.endswith('.json')):
|
||||
_filename = filename[:-5]
|
||||
user_settings.laststory = _filename
|
||||
#set the story_name
|
||||
story_settings.story_name = _filename
|
||||
emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1")
|
||||
setgamesaved(True)
|
||||
sendwi()
|
||||
emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1")
|
||||
refresh_story()
|
||||
emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1")
|
||||
emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True, room="UI_1")
|
||||
print("{0}Story loaded from {1}!{2}".format(colors.GREEN, filename, colors.END))
|
||||
|
||||
send_debug()
|
||||
|
||||
def load_story_v2(js):
|
||||
story_settings.from_json(js)
|
||||
|
||||
#==================================================================#
|
||||
# Import an AIDungon game exported with Mimi's tool
|
||||
@@ -5769,11 +5807,23 @@ def send_debug():
|
||||
|
||||
emit('from_server', {'cmd': 'debug_info', 'data': debug_info}, broadcast=True, room="UI_1")
|
||||
|
||||
|
||||
#==================================================================#
|
||||
# UI V2 CODE
|
||||
#==================================================================#
|
||||
@app.route('/new_ui')
|
||||
def new_ui_index():
|
||||
return render_template('index_new.html', settings=gensettings.gensettingstf if model_settings.model != "InferKit" else gensettings.gensettingsik )
|
||||
|
||||
def ui2_connect():
|
||||
pass
|
||||
|
||||
#==================================================================#
|
||||
# Event triggered when browser SocketIO detects a variable change
|
||||
#==================================================================#
|
||||
@socketio.on('var_change')
|
||||
def UI_2_var_change(data):
|
||||
print(data)
|
||||
classname = data['ID'].split("_")[0]
|
||||
name = data['ID'][len(classname)+1:]
|
||||
classname += "_settings"
|
||||
@@ -5794,13 +5844,22 @@ def UI_2_var_change(data):
|
||||
|
||||
setattr(globals()[classname], name, value)
|
||||
|
||||
#Now let's save except for story changes
|
||||
if classname != "story_settings":
|
||||
with open("settings/{}.v2_settings".format(classname), "w") as settings_file:
|
||||
settings_file.write(globals()[classname].to_json())
|
||||
|
||||
#==================================================================#
|
||||
# UI V2 CODE
|
||||
# Saving Story
|
||||
#==================================================================#
|
||||
@app.route('/new_ui')
|
||||
def new_ui_index():
|
||||
return render_template('index_new.html', settings=gensettings.gensettingstf if model_settings.model != "InferKit" else gensettings.gensettingsik )
|
||||
@socketio.on('save_story')
|
||||
def UI_2_save_story(data):
|
||||
json_data = story_settings.to_json()
|
||||
save_name = story_settings.story_name if story_settings.story_name is not None else "untitled"
|
||||
with open("stories/{}_v2.json".format(save_name), "w") as settings_file:
|
||||
settings_file.write(story_settings.to_json())
|
||||
story_settings.gamesaved = True
|
||||
|
||||
|
||||
#==================================================================#
|
||||
# Event triggered when Selected Text is edited, Option is Selected, etc
|
||||
@@ -5824,10 +5883,7 @@ def UI_2_submit(data):
|
||||
#==================================================================#
|
||||
@socketio.on('Pinning')
|
||||
def UI_2_Pinning(data):
|
||||
if data['set']:
|
||||
story_settings.actions.set_pin(int(data['chunk']), int(data['option']))
|
||||
else:
|
||||
story_settings.actions.unset_pin(int(data['chunk']), int(data['option']))
|
||||
story_settings.actions.toggle_pin(int(data['chunk']), int(data['option']))
|
||||
|
||||
#==================================================================#
|
||||
# Event triggered when user clicks the back button
|
||||
@@ -5870,6 +5926,10 @@ def UI_2_relay(data):
|
||||
def show_actions():
|
||||
return story_settings.actions.actions
|
||||
|
||||
@app.route("/story")
|
||||
def show_story():
|
||||
return story_settings.to_json()
|
||||
|
||||
|
||||
|
||||
#==================================================================#
|
||||
@@ -5952,3 +6012,4 @@ else:
|
||||
model_settings.model = "ReadOnly"
|
||||
load_model(initial_load=True)
|
||||
print("{0}\nServer started in WSGI mode!{1}".format(colors.GREEN, colors.END), flush=True)
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
from flask_socketio import emit, join_room, leave_room, rooms
|
||||
import os, re, time, threading
|
||||
import os, re, time, threading, json, pickle, base64, copy, tqdm, datetime
|
||||
import socketio as socketio_client
|
||||
from io import BytesIO
|
||||
|
||||
socketio = None
|
||||
main_thread_id = threading.get_ident()
|
||||
@@ -48,7 +49,49 @@ def process_variable_changes(classname, name, value, old_value, debug_message=No
|
||||
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")
|
||||
|
||||
|
||||
|
||||
|
||||
class settings(object):
|
||||
def to_json(self):
|
||||
json_data = {'file_version': 2}
|
||||
for (name, value) in vars(self).items():
|
||||
if name not in self.no_save_variables:
|
||||
json_data[name] = value
|
||||
def to_base64(data):
|
||||
if isinstance(data, KoboldStoryRegister):
|
||||
return data.to_json()
|
||||
output = BytesIO()
|
||||
pickle.dump(data, output)
|
||||
output.seek(0)
|
||||
return "base64:{}".format(base64.encodebytes(output.read()).decode())
|
||||
return json.dumps(json_data, default=to_base64)
|
||||
|
||||
def from_json(self, data):
|
||||
if isinstance(data, str):
|
||||
json_data = json.loads(data)
|
||||
else:
|
||||
json_data = data
|
||||
for key, value in data.items():
|
||||
if key in self.__dict__:
|
||||
if isinstance(value, str):
|
||||
if value[:7] == 'base64:':
|
||||
value = pickle.loads(base64.b64decode(value[7:]))
|
||||
#Need to fix the data type of value to match the module
|
||||
if type(getattr(self, key)) == int:
|
||||
value = int(value)
|
||||
elif type(getattr(self, key)) == float:
|
||||
value = float(value)
|
||||
elif type(getattr(self, key)) == bool:
|
||||
value = bool(value)
|
||||
elif type(getattr(self, key)) == str:
|
||||
value = str(value)
|
||||
if isinstance(getattr(self, key), KoboldStoryRegister):
|
||||
self.actions.load_json(value)
|
||||
else:
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
|
||||
def send_to_ui(self):
|
||||
if socketio is not None:
|
||||
for (name, value) in vars(self).items():
|
||||
@@ -58,7 +101,8 @@ class settings(object):
|
||||
|
||||
|
||||
class model_settings(settings):
|
||||
local_only_variables = ['badwordsids', 'apikey', '_class_init']
|
||||
local_only_variables = ['badwordsids', 'apikey', '_class_init', 'tqdm']
|
||||
no_save_variables = ['tqdm']
|
||||
settings_name = "model"
|
||||
def __init__(self):
|
||||
self.model = "" # Model ID string chosen at startup
|
||||
@@ -79,6 +123,9 @@ class model_settings(settings):
|
||||
self.tfs = 1.0 # Default generator tfs (tail-free sampling)
|
||||
self.typical = 1.0 # Default generator typical sampling threshold
|
||||
self.numseqs = 1 # Number of sequences to ask the generator to create
|
||||
self.generated_tkns = 0 # If using a backend that supports Lua generation modifiers, how many tokens have already been generated, otherwise 0
|
||||
self.tqdm = tqdm.tqdm(total=self.genamt, file=self.ignore_tqdm()) # tqdm agent for generating tokens. This will allow us to calculate the remaining time
|
||||
self.tqdm_rem_time = 0 # tqdm calculated reemaining time
|
||||
self.badwordsids = []
|
||||
self.fp32_model = False # Whether or not the most recently loaded HF model was in fp32 format
|
||||
self.url = "https://api.inferkit.com/v1/models/standard/generate" # InferKit API URL
|
||||
@@ -96,20 +143,35 @@ class model_settings(settings):
|
||||
self.selected_preset = ""
|
||||
|
||||
|
||||
#dummy class to eat the tqdm output
|
||||
class ignore_tqdm(object):
|
||||
def write(self, bar):
|
||||
pass
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
old_value = getattr(self, name, None)
|
||||
super().__setattr__(name, value)
|
||||
#Put variable change actions here
|
||||
|
||||
#Setup TQDP
|
||||
if name == "generated_tkns" and 'tqdm' in self.__dict__:
|
||||
if value == 0:
|
||||
self.tqdm.reset(total=self.genamt)
|
||||
else:
|
||||
self.tqdm.update(1)
|
||||
self.tqdm_rem_time = str(datetime.timedelta(seconds=int(float(self.genamt-self.generated_tkns)/self.tqdm.format_dict['rate'])))
|
||||
|
||||
|
||||
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 = []
|
||||
no_save_variables = []
|
||||
settings_name = "story"
|
||||
def __init__(self):
|
||||
self.story_name = None # Title of the story
|
||||
self.lastact = "" # The last action received from the user
|
||||
self.submission = "" # Same as above, but after applying input formatting
|
||||
self.lastctx = "" # The last context submitted to the generator
|
||||
@@ -136,7 +198,6 @@ class story_settings(settings):
|
||||
self.wifolders_u = {} # Dictionary of pairs of folder UID - list of WI UID
|
||||
self.lua_edited = set() # Set of chunk numbers that were edited from a Lua generation modifier
|
||||
self.lua_deleted = set() # Set of chunk numbers that were deleted from a Lua generation modifier
|
||||
self.generated_tkns = 0 # If using a backend that supports Lua generation modifiers, how many tokens have already been generated, otherwise 0
|
||||
self.deletewi = None # Temporary storage for UID to delete
|
||||
self.mode = "play" # Whether the interface is in play, memory, or edit mode
|
||||
self.editln = 0 # Which line was last selected in Edit Mode
|
||||
@@ -159,9 +220,14 @@ class story_settings(settings):
|
||||
#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)
|
||||
#We want to automatically set gamesaved to false if something happens to the actions list (pins, redos, generations, text, etc)
|
||||
#To do that we need to give the actions list a copy of this data so it can set the gamesaved variable as needed
|
||||
if name == 'actions':
|
||||
self.actions.story_settings = self
|
||||
|
||||
class user_settings(settings):
|
||||
local_only_variables = []
|
||||
no_save_variables = []
|
||||
settings_name = "user"
|
||||
def __init__(self):
|
||||
self.wirmvwhtsp = False # Whether to remove leading whitespace from WI entries
|
||||
@@ -190,9 +256,9 @@ class user_settings(settings):
|
||||
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']
|
||||
no_save_variables = []
|
||||
settings_name = "system"
|
||||
def __init__(self):
|
||||
self.noai = False # Runs the script without starting up the transformers pipeline
|
||||
@@ -248,7 +314,6 @@ class system_settings(settings):
|
||||
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):
|
||||
def __init__(self, sequence=[]):
|
||||
self.actions = {}
|
||||
@@ -290,6 +355,7 @@ class KoboldStoryRegister(object):
|
||||
old_text = None
|
||||
self.actions[i] = {"Selected Text": text, "Options": []}
|
||||
process_variable_changes("actions", "Selected Text", {"id": i, "text": text}, {"id": i, "text": old_text})
|
||||
self.set_game_saved()
|
||||
|
||||
def __len__(self):
|
||||
return self.action_count+1 if self.action_count >=0 else 0
|
||||
@@ -317,6 +383,7 @@ class KoboldStoryRegister(object):
|
||||
|
||||
self.action_count = json_data['action_count']
|
||||
self.actions = temp
|
||||
self.set_game_saved()
|
||||
|
||||
def get_action(self, action_id):
|
||||
if action_id not in actions:
|
||||
@@ -342,15 +409,17 @@ class KoboldStoryRegister(object):
|
||||
else:
|
||||
self.actions[self.action_count] = {"Selected Text": text, "Options": []}
|
||||
process_variable_changes("actions", "Selected Text", {"id": self.action_count, "text": text}, None)
|
||||
self.set_game_saved()
|
||||
|
||||
def append_options(self, option_list):
|
||||
if self.action_count+1 in self.actions:
|
||||
old_options = self.actions[self.action_count+1]["Options"].copy()
|
||||
old_options = copy.deepcopy(self.actions[self.action_count+1]["Options"])
|
||||
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})
|
||||
self.set_game_saved()
|
||||
|
||||
def clear_unused_options(self, pointer=None):
|
||||
new_options = []
|
||||
@@ -358,10 +427,11 @@ class KoboldStoryRegister(object):
|
||||
if pointer is None:
|
||||
pointer = self.action_count+1
|
||||
if pointer in self.actions:
|
||||
old_options = self.actions[pointer]["Options"].copy()
|
||||
old_options = copy.deepcopy(self.actions[pointer]["Options"])
|
||||
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})
|
||||
self.set_game_saved()
|
||||
|
||||
def toggle_pin(self, action_step, option_number):
|
||||
if action_step in self.actions:
|
||||
@@ -374,22 +444,32 @@ 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"].copy()
|
||||
old_options = copy.deepcopy(self.actions[action_step]["Options"])
|
||||
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})
|
||||
self.set_game_saved()
|
||||
|
||||
def unset_pin(self, action_step, option_number):
|
||||
if action_step in self.actions:
|
||||
old_options = self.actions[action_step]["Options"].copy()
|
||||
old_options = copy.deepcopy(self.actions[action_step]["Options"])
|
||||
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})
|
||||
self.set_game_saved()
|
||||
|
||||
def toggle_pin(self, action_step, option_number):
|
||||
if action_step in self.actions:
|
||||
old_options = copy.deepcopy(self.actions[action_step]["Options"])
|
||||
if option_number < len(self.actions[action_step]['Options']):
|
||||
self.actions[action_step]['Options'][option_number]['Pinned'] = not self.actions[action_step]['Options'][option_number]['Pinned']
|
||||
process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options})
|
||||
self.set_game_saved()
|
||||
|
||||
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_options = copy.deepcopy(self.actions[action_step]["Options"])
|
||||
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']
|
||||
@@ -400,22 +480,25 @@ class KoboldStoryRegister(object):
|
||||
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})
|
||||
self.set_game_saved()
|
||||
|
||||
def delete_action(self, action_id):
|
||||
if action_id in self.actions:
|
||||
old_options = self.actions[action_id]["Options"].copy()
|
||||
old_options = copy.deepcopy(self.actions[action_id]["Options"])
|
||||
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"] = ""
|
||||
self.action_count -= 1
|
||||
process_variable_changes("actions", "Selected Text", {"id": action_id, "text": None}, {"id": action_id, "text": old_text})
|
||||
process_variable_changes("actions", "Options", {"id": action_id, "options": self.actions[action_id]["Options"]}, {"id": action_id, "options": old_options})
|
||||
self.set_game_saved()
|
||||
|
||||
def pop(self):
|
||||
if self.action_count >= 0:
|
||||
text = self.actions[self.action_count]
|
||||
self.delete_action(self.action_count)
|
||||
process_variable_changes("actions", "Selected Text", {"id": self.action_count, "text": None}, {"id": self.action_count, "text": text})
|
||||
self.set_game_saved()
|
||||
return text
|
||||
else:
|
||||
return None
|
||||
@@ -494,6 +577,9 @@ class KoboldStoryRegister(object):
|
||||
else:
|
||||
return []
|
||||
|
||||
def set_game_saved(self):
|
||||
if 'story_settings' in self.__dict__:
|
||||
self.story_settings.gamesaved = False
|
||||
def __setattr__(self, name, value):
|
||||
old_value = getattr(self, name, None)
|
||||
super().__setattr__(name, value)
|
||||
|
95
settings/preset/official.presets
Normal file
95
settings/preset/official.presets
Normal file
@@ -0,0 +1,95 @@
|
||||
{"EleutherAI_gpt-neo-1.3B":
|
||||
{
|
||||
"Storywriter": {
|
||||
"temp": 0.72,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 0.725,
|
||||
"top_k": 0,
|
||||
"tfs": 1,
|
||||
"rep_pen_slope": 2048,
|
||||
"rep_pen_range": 0.18,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "Optimized settings for relevant output."
|
||||
},
|
||||
"Coherent Creativity": {
|
||||
"temp": 0.51,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 1,
|
||||
"top_k": 0,
|
||||
"tfs": 0.9,
|
||||
"rep_pen_slope": 2048,
|
||||
"rep_pen_range": 0,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "A good balance between coherence, creativity, and quality of prose."
|
||||
},
|
||||
"Luna Moth": {
|
||||
"temp": 2,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 0.235,
|
||||
"top_k": 85,
|
||||
"tfs": 1,
|
||||
"rep_pen_slope": 2048,
|
||||
"rep_pen_range": 0,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "A great degree of creativity without losing coherency."
|
||||
},
|
||||
"Sphinx Moth": {
|
||||
"temp": 2,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 0.175,
|
||||
"top_k": 30,
|
||||
"tfs": 1,
|
||||
"rep_pen_slope": 2048,
|
||||
"rep_pen_range": 0,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "Maximum randomness while still being plot relevant. Like Sphinx riddles!"
|
||||
},
|
||||
"Emperor Moth": {
|
||||
"temp": 1.25,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 0.235,
|
||||
"top_k": 0,
|
||||
"tfs": 1,
|
||||
"rep_pen_slope": 2048,
|
||||
"rep_pen_range": 0,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "Medium randomness with a decent bit of creative writing."
|
||||
},
|
||||
"Best Guess": {
|
||||
"temp": 0.8,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 0.9,
|
||||
"top_k": 100,
|
||||
"tfs": 1,
|
||||
"rep_pen_slope": 512,
|
||||
"rep_pen_range": 3.33,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "A subtle change with alternative context settings."
|
||||
},
|
||||
"Pleasing Results": {
|
||||
"temp": 0.44,
|
||||
"genamt": 40,
|
||||
"rep_pen": 1.2,
|
||||
"top_p": 1,
|
||||
"top_k": 0,
|
||||
"tfs": 0.9,
|
||||
"rep_pen_slope": 1024,
|
||||
"rep_pen_range": 6.75,
|
||||
"typical": 1,
|
||||
"top_a": 0,
|
||||
"description": "Expectable output with alternative context settings."
|
||||
}
|
||||
}
|
||||
}
|
@@ -327,6 +327,8 @@ td.server_vars {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ---------------------------- OVERALL PAGE CONFIG ------------------------------*/
|
||||
body {
|
||||
background-color: var(--background);
|
||||
@@ -336,7 +338,7 @@ body {
|
||||
.main-grid {
|
||||
transition: margin-left .5s;
|
||||
display: grid;
|
||||
min-height: 98vh;
|
||||
height: 98vh;
|
||||
margin-left: var(--flyout_menu_closed_width);
|
||||
/* grid-template-areas: "menuicon gamescreen lefticon"
|
||||
"menuicon actions lefticon"
|
||||
@@ -371,6 +373,13 @@ body {
|
||||
margin-top: auto;
|
||||
padding-bottom: 1px;
|
||||
vertical-align: bottom;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.gametext::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[contenteditable="true"]:active,
|
||||
@@ -384,6 +393,7 @@ body {
|
||||
margin-top: 10px;
|
||||
grid-area: options;
|
||||
background-color: var(--gamescreen_background);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
table.sequence {
|
||||
@@ -446,14 +456,14 @@ td.sequence:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.inputrow .submit[server_value=false] {
|
||||
.inputrow .submit[system_aibusy=false] {
|
||||
grid-area: submit;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
.inputrow .submit[server_value=true] {
|
||||
.inputrow .submit[system_aibusy=true] {
|
||||
grid-area: submit;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -462,7 +472,7 @@ td.sequence:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inputrow .submited[server_value=false] {
|
||||
.inputrow .submited[system_aibusy=false] {
|
||||
grid-area: submit;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -470,7 +480,7 @@ td.sequence:hover {
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
.inputrow .submited[server_value=true] {
|
||||
.inputrow .submited[system_aibusy=true] {
|
||||
grid-area: submit;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
@@ -12,6 +12,7 @@ socket.on('var_changed', function(data){var_changed(data);});
|
||||
|
||||
var backend_vars = {};
|
||||
var presets = {}
|
||||
var ai_busy_start = Date.now();
|
||||
//-----------------------------------Server to UI Functions-----------------------------------------------
|
||||
function connect() {
|
||||
console.log("connected");
|
||||
@@ -54,14 +55,11 @@ function create_options(data) {
|
||||
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 {
|
||||
@@ -77,37 +75,6 @@ function create_options(data) {
|
||||
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;
|
||||
}
|
||||
//Add Redo options
|
||||
i=0;
|
||||
for (item of data.value.options) {
|
||||
@@ -139,7 +106,7 @@ function create_options(data) {
|
||||
//Add general options
|
||||
i=0;
|
||||
for (item of data.value.options) {
|
||||
if (!(item.Edited) && !(item.Pinned) && !(item['Previous Selection'])) {
|
||||
if (!(item.Edited) && !(item['Previous Selection'])) {
|
||||
var row = document.createElement("tr");
|
||||
row.classList.add("sequence");
|
||||
var textcell = document.createElement("td");
|
||||
@@ -154,10 +121,12 @@ function create_options(data) {
|
||||
icon.id = "Pin_"+i;
|
||||
icon.classList.add("oi");
|
||||
icon.setAttribute('data-glyph', "pin");
|
||||
icon.setAttribute('style', "filter: brightness(50%);");
|
||||
if (!(item.Pinned)) {
|
||||
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});
|
||||
socket.emit("Pinning", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
|
||||
};
|
||||
textcell.onclick = function () {
|
||||
socket.emit("Set Selected Text", {"chunk": this.getAttribute("option_chunk"), "option": this.getAttribute("option_id")});
|
||||
@@ -193,6 +162,7 @@ function do_story_text_updates(data) {
|
||||
}
|
||||
|
||||
function do_presets(data) {
|
||||
console.log(data);
|
||||
var select = document.getElementById('presets');
|
||||
//clear out the preset list
|
||||
while (select.firstChild) {
|
||||
@@ -203,11 +173,11 @@ function do_presets(data) {
|
||||
option.value="";
|
||||
option.text="presets";
|
||||
select.append(option);
|
||||
for (item of data.value) {
|
||||
presets[item.preset] = item;
|
||||
for (const [key, value] of Object.entries(data.value)) {
|
||||
presets[key] = value;
|
||||
var option = document.createElement("option");
|
||||
option.value=item.preset;
|
||||
option.text=item.preset;
|
||||
option.value=key;
|
||||
option.text=key;
|
||||
select.append(option);
|
||||
}
|
||||
}
|
||||
@@ -251,6 +221,20 @@ function update_status_bar(data) {
|
||||
document.title = "KoboldAI Client Generating (" + percent_complete + "%)";
|
||||
}
|
||||
}
|
||||
|
||||
function do_ai_busy(data) {
|
||||
if (data.value) {
|
||||
ai_busy_start = Date.now();
|
||||
favicon.start_swap()
|
||||
} else {
|
||||
runtime = Date.now() - ai_busy_start;
|
||||
if (document.getElementById("Execution Time")) {
|
||||
document.getElementById("Execution Time").textContent = Math.round(runtime/1000).toString().toHHMMSS();
|
||||
}
|
||||
favicon.stop_swap()
|
||||
}
|
||||
}
|
||||
|
||||
function var_changed(data) {
|
||||
//Special Case for Story Text
|
||||
if ((data.classname == "actions") && (data.name == "Selected Text")) {
|
||||
@@ -276,22 +260,18 @@ function var_changed(data) {
|
||||
//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));
|
||||
item.setAttribute(data.classname.replace(" ", "_")+"_"+data.name.replace(" ", "_"), 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')) {
|
||||
if ((data.classname == 'model') && (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()
|
||||
} else {
|
||||
favicon.stop_swap()
|
||||
}
|
||||
do_ai_busy(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,6 +279,18 @@ function var_changed(data) {
|
||||
|
||||
|
||||
//--------------------------------------------General UI Functions------------------------------------
|
||||
String.prototype.toHHMMSS = function () {
|
||||
var sec_num = parseInt(this, 10); // don't forget the second param
|
||||
var hours = Math.floor(sec_num / 3600);
|
||||
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
||||
var seconds = sec_num - (hours * 3600) - (minutes * 60);
|
||||
|
||||
if (hours < 10) {hours = "0"+hours;}
|
||||
if (minutes < 10) {minutes = "0"+minutes;}
|
||||
if (seconds < 10) {seconds = "0"+seconds;}
|
||||
return hours+':'+minutes+':'+seconds;
|
||||
}
|
||||
|
||||
function toggle_flyout(x) {
|
||||
if (document.getElementById("SideMenu").classList.contains("open")) {
|
||||
x.classList.remove("change");
|
||||
|
@@ -34,7 +34,7 @@
|
||||
<!------------ Game Text Screen--------------------->
|
||||
<div class="gamescreen" id="gamescreen">
|
||||
<div class="gametext">
|
||||
<span id="prompt" class="var_sync_story_prompt rawtext"></span>
|
||||
<span id="story_prompt" class="var_sync_story_prompt rawtext" contenteditable=true onblur="socket.emit('var_change', {'ID': this.id, 'value': this.textContent});"></span>
|
||||
<span id="Selected Text" class="rawtext"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,8 +44,8 @@
|
||||
<!------------ Input Area--------------------->
|
||||
<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 class="statusbar_outer hidden">
|
||||
<div class="statusbar_inner" style="width:0%">0%</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>
|
||||
@@ -58,9 +58,8 @@
|
||||
</div>
|
||||
|
||||
<!------------ Right Flyout Menu--------------------->
|
||||
<div id="rightSideMenu" class="rightSideMenu"> Status:<hr>
|
||||
|
||||
|
||||
<div id="rightSideMenu" class="rightSideMenu">
|
||||
{% include 'story flyout.html' %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -10,6 +10,16 @@
|
||||
#Model_Info {
|
||||
width: 100%;
|
||||
}
|
||||
#Story_Info {
|
||||
width: 100%;
|
||||
}
|
||||
#save_story[story_gamesaved="true"] {
|
||||
text: var(--disabled_button_text);
|
||||
background-color: var(--disabled_button_background_color);
|
||||
border-color: var(--disabled_button_border_color);
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- top menu bar-->
|
||||
<div class="flex settings_menu">
|
||||
@@ -17,7 +27,7 @@
|
||||
<button class="menu_button" onclick="show_setting_menu('story');">Story</button>
|
||||
<button class="menu_button" onclick="show_setting_menu('user');">User</button>
|
||||
<button class="menu_button" onclick="show_setting_menu('system');">System</button>
|
||||
<select id=presets class="var_sync_model_selected_preset" onchange='socket.emit("var_change", {"ID": "model_selected_preset", "value": this.value});'><option>Preset</option></select>
|
||||
<select id=presets class="var_sync_model_selected_preset settings_select" onchange='socket.emit("var_change", {"ID": "model_selected_preset", "value": this.value});'><option>Preset</option></select>
|
||||
</div>
|
||||
|
||||
<div id="setting_menu_model" class="settings_category_area">
|
||||
@@ -30,6 +40,10 @@
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div id="setting_menu_story" class="hidden settings_category_area">
|
||||
<div id="Story_Info">
|
||||
<div>Story Name: <span class="var_sync_story_story_name"></span></div>
|
||||
<div><button id="save_story" class="btn action_button var_sync_alt_story_gamesaved" onclick='socket.emit("save_story", "Story123");'>Save Story</button></div>
|
||||
</div>
|
||||
{% with menu='Story' %}
|
||||
{% include 'settings item.html' %}
|
||||
{% endwith %}
|
||||
|
Reference in New Issue
Block a user