Merge branch 'UI2' of https://github.com/ebolam/KoboldAI into ui2-gruvbox

This commit is contained in:
somebody
2022-08-29 19:58:45 -05:00
19 changed files with 2579 additions and 631 deletions

View File

@@ -23,6 +23,7 @@ from os import path, getcwd
import time
import re
import json
import datetime
import collections
import zipfile
import packaging
@@ -39,6 +40,7 @@ import traceback
import inspect
import warnings
import multiprocessing
import copy
from collections.abc import Iterable
from collections import OrderedDict
from typing import Any, Callable, TypeVar, Tuple, Union, Dict, Set, List, Optional, Type
@@ -232,6 +234,9 @@ class Send_to_socketio(object):
emit('from_server', {'cmd': 'model_load_status', 'data': bar.replace(" ", " ")}, broadcast=True, room="UI_1")
except:
pass
def flush(self):
pass
# Set logging level to reduce chatter from Flask
import logging
@@ -852,7 +857,9 @@ def loadmodelsettings():
if("dynamicscan" in js):
koboldai_vars.dynamicscan = js["dynamicscan"]
if("formatoptns" in js):
koboldai_vars.formatoptns = js["formatoptns"]
for setting in ['frmttriminc', 'frmtrmblln', 'frmtrmspch', 'frmtadsnsp', 'singleline']:
if setting in js["formatoptns"]:
setattr(koboldai_vars, setting, js["formatoptns"][setting])
if("welcome" in js):
koboldai_vars.welcome = js["welcome"]
if("newlinemode" in js):
@@ -883,7 +890,8 @@ def savesettings():
js["genamt"] = koboldai_vars.genamt
js["max_length"] = koboldai_vars.max_length
js["ikgen"] = koboldai_vars.ikgen
js["formatoptns"] = koboldai_vars.formatoptns
js["formatoptns"] = {'frmttriminc': koboldai_vars.frmttriminc, 'frmtrmblln': koboldai_vars.frmtrmblln,
'frmtrmspch': koboldai_vars.frmtrmspch, 'frmtadsnsp': koboldai_vars.frmtadsnsp, 'singleline': koboldai_vars.singleline}
js["numseqs"] = koboldai_vars.numseqs
js["widepth"] = koboldai_vars.widepth
js["useprompt"] = koboldai_vars.useprompt
@@ -983,7 +991,9 @@ def processsettings(js):
if("ikgen" in js):
koboldai_vars.ikgen = js["ikgen"]
if("formatoptns" in js):
koboldai_vars.formatoptns = js["formatoptns"]
for setting in ['frmttriminc', 'frmtrmblln', 'frmtrmspch', 'frmtadsnsp', 'singleline']:
if setting in js["formatoptns"]:
setattr(koboldai_vars, setting, js["formatoptns"][setting])
if("numseqs" in js):
koboldai_vars.numseqs = js["numseqs"]
if("widepth" in js):
@@ -1081,7 +1091,7 @@ def spRequest(filename):
if 'np' not in globals():
import numpy as np
z, version, shape, fortran_order, dtype = fileops.checksp(filename, koboldai_vars.modeldim)
z, version, shape, fortran_order, dtype = fileops.checksp("./softprompts/"+filename, koboldai_vars.modeldim)
if not isinstance(z, zipfile.ZipFile):
raise RuntimeError(f"{repr(filename)} is not a valid soft prompt file")
with z.open('meta.json') as f:
@@ -1473,6 +1483,8 @@ def patch_transformers_download():
eventlet.sleep(seconds=0)
except:
pass
def flush(self):
pass
def http_get(
url: str,
temp_file: transformers.utils.hub.BinaryIO,
@@ -2624,6 +2636,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal
koboldai_vars.presets = to_use
koboldai_vars.aibusy = False
koboldai_vars.splist = [[f, get_softprompt_desc(os.path.join("./softprompts", f),None,True)] for f in os.listdir("./softprompts") if os.path.isfile(os.path.join("./softprompts", f)) and valid_softprompt(os.path.join("./softprompts", f))]
# Set up Flask routes
@app.route('/')
@@ -3077,11 +3090,11 @@ def lua_get_setting(setting):
if(setting in ("setnopromptgen", "nopromptgen")): return koboldai_vars.nopromptgen
if(setting in ("autosave", "autosave")): return koboldai_vars.autosave
if(setting in ("setrngpersist", "rngpersist")): return koboldai_vars.rngpersist
if(setting in ("frmttriminc", "triminc")): return koboldai_vars.formatoptns["frmttriminc"]
if(setting in ("frmtrmblln", "rmblln")): return koboldai_vars.formatoptns["frmttrmblln"]
if(setting in ("frmtrmspch", "rmspch")): return koboldai_vars.formatoptns["frmttrmspch"]
if(setting in ("frmtadsnsp", "adsnsp")): return koboldai_vars.formatoptns["frmtadsnsp"]
if(setting in ("frmtsingleline", "singleline")): return koboldai_vars.formatoptns["singleline"]
if(setting in ("frmttriminc", "triminc")): return koboldai_vars.frmttriminc
if(setting in ("frmtrmblln", "rmblln")): return koboldai_vars.frmttrmblln
if(setting in ("frmtrmspch", "rmspch")): return koboldai_vars.frmttrmspch
if(setting in ("frmtadsnsp", "adsnsp")): return koboldai_vars.frmtadsnsp
if(setting in ("frmtsingleline", "singleline")): return koboldai_vars.singleline
if(setting == "output_streaming"): return koboldai_vars.output_streaming
if(setting == "show_probs"): return koboldai_vars.show_probs
@@ -3115,11 +3128,11 @@ def lua_set_setting(setting, v):
if(setting in ("autosave", "noautosave")): koboldai_vars.autosave = v
if(setting in ("setrngpersist", "rngpersist")): koboldai_vars.rngpersist = v
if(setting in ("setchatmode", "chatmode")): koboldai_vars.chatmode = v
if(setting in ("frmttriminc", "triminc")): koboldai_vars.formatoptns["frmttriminc"] = v
if(setting in ("frmtrmblln", "rmblln")): koboldai_vars.formatoptns["frmttrmblln"] = v
if(setting in ("frmtrmspch", "rmspch")): koboldai_vars.formatoptns["frmttrmspch"] = v
if(setting in ("frmtadsnsp", "adsnsp")): koboldai_vars.formatoptns["frmtadsnsp"] = v
if(setting in ("frmtsingleline", "singleline")): koboldai_vars.formatoptns["singleline"] = v
if(setting in ("frmttriminc", "triminc")): koboldai_vars.frmttriminc = v
if(setting in ("frmtrmblln", "rmblln")): koboldai_vars.frmttrmblln = v
if(setting in ("frmtrmspch", "rmspch")): koboldai_vars.frmttrmspch = v
if(setting in ("frmtadsnsp", "adsnsp")): koboldai_vars.frmtadsnsp = v
if(setting in ("frmtsingleline", "singleline")): koboldai_vars.singleline = v
if(setting == "output_streaming"): koboldai_vars.output_streaming = v
if(setting == "show_probs"): koboldai_vars.show_probs = v
@@ -3548,28 +3561,23 @@ def get_message(msg):
refresh_settings()
# Format - Trim incomplete sentences
elif(msg['cmd'] == 'frmttriminc'):
if('frmttriminc' in koboldai_vars.formatoptns):
koboldai_vars.formatoptns["frmttriminc"] = msg['data']
koboldai_vars.frmttriminc = msg['data']
settingschanged()
refresh_settings()
elif(msg['cmd'] == 'frmtrmblln'):
if('frmtrmblln' in koboldai_vars.formatoptns):
koboldai_vars.formatoptns["frmtrmblln"] = msg['data']
koboldai_vars.frmtrmblln = msg['data']
settingschanged()
refresh_settings()
elif(msg['cmd'] == 'frmtrmspch'):
if('frmtrmspch' in koboldai_vars.formatoptns):
koboldai_vars.formatoptns["frmtrmspch"] = msg['data']
koboldai_vars.frmtrmspch = msg['data']
settingschanged()
refresh_settings()
elif(msg['cmd'] == 'frmtadsnsp'):
if('frmtadsnsp' in koboldai_vars.formatoptns):
koboldai_vars.formatoptns["frmtadsnsp"] = msg['data']
koboldai_vars.frmtadsnsp = msg['data']
settingschanged()
refresh_settings()
elif(msg['cmd'] == 'singleline'):
if('singleline' in koboldai_vars.formatoptns):
koboldai_vars.formatoptns["singleline"] = msg['data']
koboldai_vars.singleline = msg['data']
settingschanged()
refresh_settings()
elif(msg['cmd'] == 'importselect'):
@@ -3931,17 +3939,19 @@ def sendsettings():
emit('from_server', {'cmd': 'reset_menus'}, room="UI_1")
if(koboldai_vars.model != "InferKit"):
for set in gensettings.gensettingstf:
emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1")
if 'UI_V2_Only' not in set:
emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1")
else:
for set in gensettings.gensettingsik:
emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1")
if 'UI_V2_Only' not in set:
emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1")
# Send formatting options
for frm in gensettings.formatcontrols:
emit('from_server', {'cmd': 'addformat', 'data': frm}, room="UI_1")
# Add format key to vars if it wasn't loaded with client.settings
if(not frm["id"] in koboldai_vars.formatoptns):
koboldai_vars.formatoptns[frm["id"]] = False;
if(not hasattr(koboldai_vars, frm["id"])):
setattr(koboldai_vars, frm["id"], False)
#==================================================================#
# Set value of gamesaved
@@ -4032,6 +4042,8 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
koboldai_vars.submission = re.sub(r"[^\S\r\n]*([\r\n]*)$", r"\1", koboldai_vars.submission) # Remove trailing whitespace, excluding newlines
data = koboldai_vars.submission
if(not force_submit and len(data.strip()) == 0):
set_aibusy(0)
socketio.emit("error", "No prompt or random story theme entered", broadcast=True, room="UI_2")
assert False
# Start the game
koboldai_vars.gamestarted = True
@@ -4060,7 +4072,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
for i in range(koboldai_vars.numseqs):
genout.append({"generated_text": koboldai_vars.lua_koboldbridge.outputs[i+1]})
assert type(genout[-1]["generated_text"]) is str
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"], flash=False)
@@ -4124,7 +4136,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
for i in range(koboldai_vars.numseqs):
genout.append({"generated_text": koboldai_vars.lua_koboldbridge.outputs[i+1] if not no_generate else ""})
assert type(genout[-1]["generated_text"]) is str
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"])
@@ -4223,14 +4235,17 @@ def apiactionsubmit(data, use_memory=False, use_world_info=False, use_story=Fals
mem = koboldai_vars.memory + "\n"
else:
mem = koboldai_vars.memory
if(use_authors_note and koboldai_vars.authornote != ""):
anotetxt = ("\n" + koboldai_vars.authornotetemplate + "\n").replace("<|>", koboldai_vars.authornote)
else:
anotetxt = ""
MIN_STORY_TOKENS = 8
story_tokens = []
mem_tokens = []
wi_tokens = []
story_budget = lambda: koboldai_vars.max_length - koboldai_vars.sp_length - koboldai_vars.genamt - len(tokenizer._koboldai_header) - len(story_tokens) - len(mem_tokens) - len(wi_tokens)
budget = lambda: story_budget() + MIN_STORY_TOKENS
if budget() < 0:
@@ -4238,15 +4253,20 @@ def apiactionsubmit(data, use_memory=False, use_world_info=False, use_story=Fals
"msg": f"Your Max Tokens setting is too low for your current soft prompt and tokenizer to handle. It needs to be at least {koboldai_vars.max_length - budget()}.",
"type": "token_overflow",
}}), mimetype="application/json", status=500))
if use_memory:
mem_tokens = tokenizer.encode(utils.encodenewlines(mem))[-budget():]
if use_world_info:
world_info, _ = checkworldinfo(data, force_use_txt=True, scan_story=use_story)
wi_tokens = tokenizer.encode(utils.encodenewlines(world_info))[-budget():]
if use_story:
if koboldai_vars.useprompt:
story_tokens = tokenizer.encode(utils.encodenewlines(koboldai_vars.prompt))[-budget():]
story_tokens = tokenizer.encode(utils.encodenewlines(data))[-story_budget():] + story_tokens
if use_story:
for i, action in enumerate(reversed(koboldai_vars.actions.values())):
if story_budget() <= 0:
@@ -4257,6 +4277,7 @@ def apiactionsubmit(data, use_memory=False, use_world_info=False, use_story=Fals
story_tokens = tokenizer.encode(utils.encodenewlines(anotetxt))[-story_budget():] + story_tokens
if not koboldai_vars.useprompt:
story_tokens = tokenizer.encode(utils.encodenewlines(koboldai_vars.prompt))[-budget():] + story_tokens
tokens = tokenizer._koboldai_header + mem_tokens + wi_tokens + story_tokens
assert story_budget() >= 0
minimum = len(tokens) + 1
@@ -4418,7 +4439,8 @@ def calcsubmitbudget(actionlen, winfo, mem, anotetxt, actions, submission=None,
budget -= tknlen
else:
count = budget * -1
tokens = acttkns[count:] + tokens
truncated_action_tokens = acttkns[count:]
tokens = truncated_action_tokens + tokens
budget = 0
break
@@ -4440,6 +4462,7 @@ def calcsubmitbudget(actionlen, winfo, mem, anotetxt, actions, submission=None,
# Did we get to add the A.N.? If not, do it here
if(anotetxt != ""):
if((not anoteadded) or forceanote):
# header, mem, wi, anote, prompt, actions
tokens = (tokenizer._koboldai_header if koboldai_vars.model not in ("Colab", "API", "OAI") else []) + memtokens + witokens + anotetkns + prompttkns + tokens
else:
tokens = (tokenizer._koboldai_header if koboldai_vars.model not in ("Colab", "API", "OAI") else []) + memtokens + witokens + prompttkns + tokens
@@ -4450,6 +4473,7 @@ def calcsubmitbudget(actionlen, winfo, mem, anotetxt, actions, submission=None,
# Send completed bundle to generator
assert len(tokens) <= koboldai_vars.max_length - lnsp - koboldai_vars.genamt - budget_deduction
ln = len(tokens) + lnsp
return tokens, ln+1, ln+koboldai_vars.genamt
#==================================================================#
@@ -4578,7 +4602,7 @@ def _generate(txt, minimum, maximum, found_entries):
koboldai_vars._actions = koboldai_vars.actions
koboldai_vars._prompt = koboldai_vars.prompt
if(koboldai_vars.dynamicscan):
koboldai_vars._actions = koboldai_vars._actions.copy()
koboldai_vars._actions = [x for x in koboldai_vars.actions]
with torch.no_grad():
already_generated = 0
@@ -4695,12 +4719,14 @@ def generate(txt, minimum, maximum, found_entries=None):
assert type(genout[-1]["generated_text"]) is str
else:
genout = [{"generated_text": utils.decodenewlines(tokenizer.decode(tokens[-already_generated:]))} for tokens in genout]
print([applyoutputformatting(x["generated_text"]) for x in genout])
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(len(genout) == 1):
genresult(genout[0]["generated_text"])
#koboldai_vars.actions.append(applyoutputformatting(genout[0]["generated_text"]))
else:
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(koboldai_vars.lua_koboldbridge.restart_sequence is not None and koboldai_vars.lua_koboldbridge.restart_sequence > 0):
genresult(genout[koboldai_vars.lua_koboldbridge.restart_sequence-1]["generated_text"])
else:
@@ -4848,7 +4874,7 @@ def sendtocolab(txt, min, max):
assert type(genout[-1]) is str
koboldai_vars.actions.clear_unused_options()
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(len(genout) == 1):
@@ -5084,7 +5110,7 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None):
else:
genout = [{"generated_text": utils.decodenewlines(tokenizer.decode(txt))} for txt in genout]
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if(len(koboldai_vars.actions.get_current_options()) == 1):
genresult(koboldai_vars.actions.get_current_options()[0]['text'])
@@ -5126,7 +5152,7 @@ def getnewcontent(txt):
#==================================================================#
def applyinputformatting(txt):
# Add sentence spacing
if(koboldai_vars.formatoptns["frmtadsnsp"]):
if(koboldai_vars.frmtadsnsp):
txt = utils.addsentencespacing(txt, koboldai_vars)
return txt
@@ -5143,16 +5169,16 @@ def applyoutputformatting(txt):
txt = koboldai_vars.acregex_ai.sub('', txt)
# Trim incomplete sentences
if(koboldai_vars.formatoptns["frmttriminc"] and not koboldai_vars.chatmode):
if(koboldai_vars.frmttriminc and not koboldai_vars.chatmode):
txt = utils.trimincompletesentence(txt)
# Replace blank lines
if(koboldai_vars.formatoptns["frmtrmblln"] or koboldai_vars.chatmode):
if(koboldai_vars.frmtrmblln or koboldai_vars.chatmode):
txt = utils.replaceblanklines(txt)
# Remove special characters
if(koboldai_vars.formatoptns["frmtrmspch"]):
if(koboldai_vars.frmtrmspch):
txt = utils.removespecialchars(txt, koboldai_vars)
# Single Line Mode
if(koboldai_vars.formatoptns["singleline"] or koboldai_vars.chatmode):
if(koboldai_vars.singleline or koboldai_vars.chatmode):
txt = utils.singlelineprocessing(txt, koboldai_vars)
return txt
@@ -5255,11 +5281,11 @@ def refresh_settings():
emit('from_server', {'cmd': 'updatenogenmod', 'data': koboldai_vars.nogenmod}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefulldeterminism', 'data': koboldai_vars.full_determinism}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmttriminc', 'data': koboldai_vars.formatoptns["frmttriminc"]}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtrmblln', 'data': koboldai_vars.formatoptns["frmtrmblln"]}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtrmspch', 'data': koboldai_vars.formatoptns["frmtrmspch"]}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtadsnsp', 'data': koboldai_vars.formatoptns["frmtadsnsp"]}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatesingleline', 'data': koboldai_vars.formatoptns["singleline"]}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmttriminc', 'data': koboldai_vars.frmttriminc}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtrmblln', 'data': koboldai_vars.frmtrmblln}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtrmspch', 'data': koboldai_vars.frmtrmspch}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatefrmtadsnsp', 'data': koboldai_vars.frmtadsnsp}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updatesingleline', 'data': koboldai_vars.singleline}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updateoutputstreaming', 'data': koboldai_vars.output_streaming}, broadcast=True, room="UI_1")
emit('from_server', {'cmd': 'updateshowprobs', 'data': koboldai_vars.show_probs}, broadcast=True, room="UI_1")
@@ -5840,7 +5866,7 @@ def oairequest(txt, min, max):
{"generated_text": utils.decodenewlines(txt)}
for txt in outputs]
koboldai_vars.actions.append_options([x["generated_text"] for x in genout])
koboldai_vars.actions.append_options([applyoutputformatting(x["generated_text"]) for x in genout])
genout = [{"generated_text": x['text']} for x in koboldai_vars.actions.get_current_options()]
if (len(genout) == 1):
genresult(genout[0]["generated_text"])
@@ -6119,7 +6145,7 @@ def load_story_v1(js):
#create the story
#koboldai_vars.create_story(session['story'])
koboldai_vars.create_story('default')
koboldai_vars.laststory = _filename
#set the story_name
koboldai_vars.story_name = _filename
@@ -6162,8 +6188,9 @@ def load_story_v1(js):
for key in js["actions_metadata"]:
if js["actions_metadata"][key]["Alternative Text"] != []:
data = js["actions_metadata"][key]["Alternative Text"]
data["text"] = data.pop("Text")
koboldai_vars.actions.set_options(self, data, key)
for i in range(len(js["actions_metadata"][key]["Alternative Text"])):
data[i]["text"] = data[i].pop("Text")
koboldai_vars.actions.set_options(data, key)
# Try not to break older save files
if("authorsnote" in js):
@@ -6546,7 +6573,8 @@ def final_startup():
file = open("settings/" + getmodelname().replace('/', '_') + ".settings", "r")
js = json.load(file)
if(koboldai_vars.allowsp and "softprompt" in js and type(js["softprompt"]) is str and all(q not in js["softprompt"] for q in ("..", ":")) and (len(js["softprompt"]) != 0 and all(js["softprompt"][0] not in q for q in ("/", "\\")))):
spRequest("softprompts/"+js["softprompt"])
if valid_softprompt("softprompts/"+js["softprompt"]):
spRequest("softprompts/"+js["softprompt"])
else:
koboldai_vars.spfilename = ""
file.close()
@@ -6810,7 +6838,8 @@ def file_popup(popup_title, starting_folder, return_event, upload=True, jailed=T
editable=False, show_breadcrumbs=True, item_check=None, show_hidden=False,
valid_only=False, hide_extention=False, extra_parameter_function=None,
column_names=['File Name'], show_filename=True,
column_widths=["100%"]):
column_widths=["100%"],
sort="Modified", desc=False):
#starting_folder = The folder we're going to get folders and/or items from
#return_event = the socketio event that will be emitted when the load button is clicked
#jailed = if set to true will look for the session variable jailed_folder and prevent navigation outside of that folder
@@ -6840,6 +6869,8 @@ def file_popup(popup_title, starting_folder, return_event, upload=True, jailed=T
session['hide_extention'] = hide_extention
session['show_filename'] = show_filename
session['column_widths'] = column_widths
session['sort'] = sort
session['desc'] = desc
socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "renameable": renameable, "deleteable": deleteable, "editable": editable, 'upload': upload}, broadcast=False, room="UI_2")
socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "renameable": renameable, "deleteable": deleteable, "editable": editable, 'upload': upload}, broadcast=True, room="UI_1")
@@ -6859,6 +6890,8 @@ def get_files_folders(starting_folder):
hide_extention = session['hide_extention']
show_filename = session['show_filename']
column_widths = session['column_widths']
sort = session['sort']
desc = session['desc']
if starting_folder == 'This PC':
breadcrumbs = [['This PC', 'This PC']]
@@ -6885,7 +6918,7 @@ def get_files_folders(starting_folder):
folders = []
files = []
base_path = os.path.abspath(starting_folder).replace("\\", "/")
for item in os.listdir(base_path):
for item in get_files_sorted(base_path, sort, desc=desc):
item_full_path = os.path.join(base_path, item).replace("\\", "/")
if hasattr(os.stat(item_full_path), "st_file_attributes"):
hidden = bool(os.stat(item_full_path).st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN)
@@ -6923,6 +6956,21 @@ def get_files_folders(starting_folder):
socketio.emit("popup_breadcrumbs", breadcrumbs, broadcast=False, room="UI_2")
socketio.emit("popup_breadcrumbs", breadcrumbs, broadcast=True, room="UI_1")
def get_files_sorted(path, sort, desc=False):
data = {}
for file in os.scandir(path=path):
if sort == "Modified":
data[file.name] = datetime.datetime.fromtimestamp(file.stat().st_mtime)
elif sort == "Accessed":
data[file.name] = datetime.datetime.fromtimestamp(file.stat().st_atime)
elif sort == "Created":
data[file.name] = datetime.datetime.fromtimestamp(file.stat().st_ctime)
elif sort == "Name":
data[file.name] = file.name
return [key[0] for key in sorted(data.items(), key=lambda kv: (kv[1], kv[0]), reverse=desc)]
#==================================================================#
# Event triggered when browser SocketIO detects a variable change
#==================================================================#
@@ -7014,8 +7062,7 @@ def UI_2_Set_Selected_Text(data):
# Event triggered when Option is Selected
#==================================================================#
@socketio.on('Use Option Text')
def UI_2_Set_Selected_Text(data):
print("Using Option Text: {}".format(data))
def UI_2_Use_Option_Text(data):
if koboldai_vars.prompt == "":
koboldai_vars.prompt = koboldai_vars.actions.get_current_options()[int(data['option'])]['text']
koboldai_vars.actions.clear_unused_options()
@@ -7041,14 +7088,19 @@ def UI_2_submit(data):
koboldai_vars.actions.clear_unused_options()
koboldai_vars.lua_koboldbridge.feedback = None
koboldai_vars.recentrng = koboldai_vars.recentrngm = None
actionsubmit(data['data'], actionmode=koboldai_vars.actionmode)
if koboldai_vars.actions.action_count == -1:
actionsubmit(data['data'], actionmode=0)
else:
actionsubmit(data['data'], actionmode=koboldai_vars.actionmode)
#==================================================================#
# Event triggered when user clicks the submit button
#==================================================================#
@socketio.on('abort')
def UI_2_abort(data):
print("got abort")
koboldai_vars.abort = True
print(koboldai_vars.abort)
#==================================================================#
@@ -7082,7 +7134,7 @@ def UI_2_redo(data):
@socketio.on('retry')
def UI_2_retry(data):
if len(koboldai_vars.actions.get_current_options()) == 0:
if len(koboldai_vars.actions.get_current_options_no_edits()) == 0:
UI_2_back(None)
koboldai_vars.actions.clear_unused_options()
koboldai_vars.lua_koboldbridge.feedback = None
@@ -7100,7 +7152,7 @@ def UI_2_load_model_button(data):
# Event triggered when user clicks the a model
#==================================================================#
@socketio.on('select_model')
def UI_2_load_model_button(data):
def UI_2_select_model(data):
print(data)
#We've selected a menu
@@ -7158,7 +7210,8 @@ def UI_2_load_story_list(data):
deleteable=True, show_breadcrumbs=True, item_check=valid_story,
valid_only=True, hide_extention=True, extra_parameter_function=get_story_length,
column_names=['Story Name', 'Action Count'],
column_widths=['auto', '100px'])
column_widths=['auto', '100px'],
sort="Modified", desc=True)
def get_story_length(item_full_path, item, valid_selection):
if not valid_selection:
@@ -7232,19 +7285,20 @@ def UI_2_Rename_World_Info_Folder(data):
#==================================================================#
@socketio.on('edit_world_info')
def UI_2_edit_world_info(data):
print("Rename_World_Info_Folder")
print("edit_world_info")
print(data)
if data['uid'] == -1:
if data['uid'] < 0:
koboldai_vars.worldinfo_v2.add_item(data['title'], data['key'],
data['keysecondary'], data['folder'],
data['constant'], data['content'],
data['comment'])
data['constant'], data['manual_text'],
data['comment'], wpp=data['wpp'], use_wpp=data['use_wpp'])
emit("delete_new_world_info_entry", {})
else:
koboldai_vars.worldinfo_v2.edit_item(data['uid'], data['title'], data['key'],
data['keysecondary'], data['folder'],
data['constant'], data['content'],
data['comment'])
data['constant'], data['manual_text'],
data['comment'], wpp=data['wpp'], use_wpp=data['use_wpp'])
#==================================================================#
@@ -7261,6 +7315,57 @@ def UI_2_create_world_info_folder(data):
def UI_2_delete_world_info(uid):
koboldai_vars.worldinfo_v2.delete(int(uid))
#==================================================================#
# Event triggered when user exports world info folder
#==================================================================#
@app.route('/export_world_info_folder')
def UI_2_export_world_info_folder():
if 'folder' in request.args:
data = koboldai_vars.worldinfo_v2.to_json(folder=request.args['folder'])
folder = request.args['folder']
else:
data = koboldai_vars.worldinfo_v2.to_json()
folder = koboldai_vars.story_name
return Response(
json.dumps(data, indent="\t"),
mimetype="application/json",
headers={"Content-disposition":
"attachment; filename={}_world_info.json".format(folder)}
)
#==================================================================#
# Event triggered when user exports world info folder
#==================================================================#
@socketio.on('upload_world_info_folder')
def UI_2_upload_world_info_folder(data):
json_data = json.loads(data['data'])
koboldai_vars.worldinfo_v2.load_json(json_data, folder=data['folder'])
@socketio.on('import_world_info')
def UI_2_import_world_info(data):
wi_data = data["data"]
uids = {}
for folder_name, children in wi_data["folders"].items():
koboldai_vars.worldinfo_v2.add_folder(folder_name)
for child in children:
# Child is index
if child not in uids:
entry_data = wi_data["entries"][str(child)]
uids[child] = koboldai_vars.worldinfo_v2.add_item(
title=entry_data["title"],
key=entry_data["key"],
keysecondary=entry_data["keysecondary"],
folder=folder_name,
constant=entry_data["constant"],
manual_text=entry_data["manual_text"],
comment=entry_data["comment"],
use_wpp=entry_data["use_wpp"],
wpp=entry_data["wpp"],
)
koboldai_vars.worldinfo_v2.add_item_to_folder(uids[child], folder_name)
#==================================================================#
# Event triggered when user edits phrase biases
#==================================================================#
@@ -7293,6 +7398,19 @@ def my_except_hook(exctype, value, traceback):
sys.__excepthook__(exctype, value, traceback)
sys.excepthook = my_except_hook
from werkzeug.exceptions import HTTPException
@app.errorhandler(Exception)
def handle_exception(e):
# pass through HTTP errors
if isinstance(e, HTTPException):
return e
# now you're handling non-HTTP exceptions only
print("sending error to clients")
socketio.emit("error", "{}: {}".format(e.message, e.args), broadcast=True, room="UI_2")
return render_template("500_generic.html", e=e), 500
#==================================================================#
# Event triggered when Softprompt is clicked
@@ -7336,6 +7454,8 @@ def UI_2_load_softprompt(data):
print("Load softprompt: {}".format(data))
spRequest(data)
#==================================================================#
# Event triggered when aidg.club loaded
#==================================================================#
@@ -7350,13 +7470,28 @@ def UI_2_load_aidg_club(data):
#==================================================================#
@socketio.on('theme_change')
def UI_2_theme_change(data):
with open("themes/user.css", "w") as f:
f.write(":root {")
for var in data:
f.write("\t{}: {};\n".format(var[0], var[1].replace(";", "")))
with open("themes/{}.css".format(data['name']), "w") as f:
f.write(":root {\n")
for key, value in data['theme'].items():
f.write("\t{}: {};\n".format(key, value.replace(";", "")))
f.write("}")
print("Theme Saved")
#==================================================================#
# Refresh SP List
#==================================================================#
@socketio.on('sp_list_refresh')
def UI_2_sp_list_refresh(data):
koboldai_vars.splist = [[f, get_softprompt_desc(os.path.join("./softprompts", f),None,True)] for f in os.listdir("./softprompts") if os.path.isfile(os.path.join("./softprompts", f)) and valid_softprompt(os.path.join("./softprompts", f))]
#==================================================================#
# Refresh Theme List
#==================================================================#
@socketio.on('theme_list_refresh')
def UI_2_theme_list_refresh(data):
koboldai_vars.theme_list = [".".join(f.split(".")[:-1]) for f in os.listdir("./themes") if os.path.isfile(os.path.join("./themes", f))]
#==================================================================#
# Test
@@ -7635,11 +7770,11 @@ def _generate_text(body: GenerationInputSchema):
"tfs": ("koboldai_vars", "tfs", None),
"typical": ("koboldai_vars", "typical", None),
"temperature": ("koboldai_vars", "temp", None),
"frmtadsnsp": ("koboldai_vars.formatoptns", "@frmtadsnsp", "input"),
"frmttriminc": ("koboldai_vars.formatoptns", "@frmttriminc", "output"),
"frmtrmblln": ("koboldai_vars.formatoptns", "@frmtrmblln", "output"),
"frmtrmspch": ("koboldai_vars.formatoptns", "@frmtrmspch", "output"),
"singleline": ("koboldai_vars.formatoptns", "@singleline", "output"),
"frmtadsnsp": ("koboldai_vars", "frmtadsnsp", "input"),
"frmttriminc": ("koboldai_vars", "frmttriminc", "output"),
"frmtrmblln": ("koboldai_vars", "frmtrmblln", "output"),
"frmtrmspch": ("koboldai_vars", "frmtrmspch", "output"),
"singleline": ("koboldai_vars", "singleline", "output"),
"max_length": ("koboldai_vars", "genamt", None),
"max_context_length": ("koboldai_vars", "max_length", None),
"n": ("koboldai_vars", "numseqs", None),
@@ -7655,7 +7790,7 @@ def _generate_text(body: GenerationInputSchema):
output_streaming = koboldai_vars.output_streaming
koboldai_vars.output_streaming = False
for key, entry in mapping.items():
obj = {"koboldai_vars": koboldai_vars, "koboldai_vars.formatoptns": koboldai_vars.formatoptns}[entry[0]]
obj = {"koboldai_vars": koboldai_vars}[entry[0]]
if entry[2] == "input" and koboldai_vars.disable_input_formatting and not hasattr(body, key):
setattr(body, key, False)
if entry[2] == "output" and koboldai_vars.disable_output_formatting and not hasattr(body, key):
@@ -7678,7 +7813,7 @@ def _generate_text(body: GenerationInputSchema):
finally:
for key in saved_settings:
entry = mapping[key]
obj = {"koboldai_vars": koboldai_vars, "koboldai_vars.formatoptns": koboldai_vars.formatoptns}[entry[0]]
obj = {"koboldai_vars": koboldai_vars}[entry[0]]
if getattr(body, key, None) is not None:
if entry[1].startswith("@"):
if obj[entry[1][1:]] == getattr(body, key):
@@ -9725,7 +9860,7 @@ def _make_f_get(obj, _var_name, _name, _schema, _example_yaml_value):
example:
value: {}
"""
_obj = {"koboldai_vars": koboldai_vars, "koboldai_vars.formatoptns": koboldai_vars.formatoptns}[obj]
_obj = {"koboldai_vars": koboldai_vars}[obj]
if _var_name.startswith("@"):
return {"value": _obj[_var_name[1:]]}
else:
@@ -9755,7 +9890,7 @@ def _make_f_put(schema_class: Type[KoboldSchema], obj, _var_name, _name, _schema
schema: EmptySchema
{api_validation_error_response}
"""
_obj = {"koboldai_vars": koboldai_vars, "koboldai_vars.formatoptns": koboldai_vars.formatoptns}[obj]
_obj = {"koboldai_vars": koboldai_vars}[obj]
if _var_name.startswith("@"):
_obj[_var_name[1:]] = body.value
else:
@@ -9981,8 +10116,8 @@ class TrimIncompleteSentencesSettingsSchema(KoboldSchema):
value = fields.Boolean(required=True)
class KoboldMeta:
route_name = "frmttriminc"
obj = "koboldai_vars.formatoptns"
var_name = "@frmttriminc"
obj = "koboldai_vars"
var_name = "frmttriminc"
name = "trim incomplete sentences (output formatting)"
example_yaml_value = "false"
@@ -9991,8 +10126,8 @@ class RemoveBlankLinesSettingsSchema(KoboldSchema):
value = fields.Boolean(required=True)
class KoboldMeta:
route_name = "frmtrmblln"
obj = "koboldai_vars.formatoptns"
var_name = "@frmtrmblln"
obj = "koboldai_vars"
var_name = "frmtrmblln"
name = "remove blank lines (output formatting)"
example_yaml_value = "false"
@@ -10001,8 +10136,8 @@ class RemoveSpecialCharactersSettingsSchema(KoboldSchema):
value = fields.Boolean(required=True)
class KoboldMeta:
route_name = "frmtrmspch"
obj = "koboldai_vars.formatoptns"
var_name = "@frmtrmspch"
obj = "koboldai_vars"
var_name = "frmtrmspch"
name = "remove special characters (output formatting)"
example_yaml_value = "false"
@@ -10011,8 +10146,8 @@ class SingleLineSettingsSchema(KoboldSchema):
value = fields.Boolean(required=True)
class KoboldMeta:
route_name = "singleline"
obj = "koboldai_vars.formatoptns"
var_name = "@singleline"
obj = "koboldai_vars"
var_name = "singleline"
name = "single line (output formatting)"
example_yaml_value = "false"
@@ -10021,8 +10156,8 @@ class AddSentenceSpacingSettingsSchema(KoboldSchema):
value = fields.Boolean(required=True)
class KoboldMeta:
route_name = "frmtadsnsp"
obj = "koboldai_vars.formatoptns"
var_name = "@frmtadsnsp"
obj = "koboldai_vars"
var_name = "frmtadsnsp"
name = "add sentence spacing (input formatting)"
example_yaml_value = "false"

View File

@@ -154,7 +154,7 @@ def getspfiles(model_dimension: int):
for file in listdir("softprompts"):
if not file.endswith(".zip"):
continue
z, version, shape, fortran_order, dtype = checksp(file, model_dimension)
z, version, shape, fortran_order, dtype = checksp("./softprompts/"+file, model_dimension)
if z == 1:
print(f"Browser SP loading error: {file} is malformed or not a soft prompt ZIP file.")
continue

View File

@@ -2,7 +2,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "int",
"label": "Amount to Generate",
"label": "Output Length",
"id": "setoutput",
"min": 16,
"max": 512,
@@ -32,7 +32,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "float",
"label": "Top p Sampling",
"label": "Top P Sampling",
"id": "settopp",
"min": 0.0,
"max": 1.0,
@@ -48,7 +48,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "int",
"label": "Top k Sampling",
"label": "Top K Sampling",
"id": "settopk",
"min": 0,
"max": 100,
@@ -63,7 +63,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "float",
"label": "Tail-free Sampling",
"label": "Tail Free Sampling",
"id": "settfs",
"min": 0.0,
"max": 1.0,
@@ -84,7 +84,7 @@ gensettingstf = [
"max": 1.0,
"step": 0.01,
"default": 1.0,
"tooltip": "Alternative sampling method described in the paper \"Typical Decoding for Natural Language Generation\" (10.48550/ARXIV.2202.00666). The paper suggests 0.2 as a good value for this setting. Set this setting to 1 to disable its effect.",
"tooltip": "Alternative sampling method described in the paper \"Typical Decoding for Natural Language Generation\" (10.48550/ARXIV.2202.00666). The paper suggests 0.2 as a good value for this setting. (Put this value on 1 to disable its effect)",
"menu_path": "Settings",
"sub_path": "Sampling",
"classname": "model",
@@ -93,13 +93,13 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "float",
"label": "Top a Sampling",
"label": "Top A Sampling",
"id": "settopa",
"min": 0.0,
"max": 1.0,
"step": 0.01,
"default": 0.0,
"tooltip": "Alternative sampling method that reduces the randomness of the AI whenever the probability of one token is much higher than all the others. Higher values have a stronger effect. Set this setting to 0 to disable its effect.",
"tooltip": "Alternative sampling method that reduces the randomness of the AI whenever the probability of one token is much higher than all the others. Higher values have a stronger effect. (Put this value on 0 to disable its effect)",
"menu_path": "Settings",
"sub_path": "Sampling",
"classname": "model",
@@ -114,7 +114,7 @@ gensettingstf = [
"max": 3.0,
"step": 0.01,
"default": 1.1,
"tooltip": "Used to penalize words that were already generated or belong to the context (Going over 1.2 breaks 6B models).",
"tooltip": "Used to penalize words that were already generated or belong to the context.",
"menu_path": "Settings",
"sub_path": "Repetition",
"classname": "model",
@@ -123,7 +123,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "int",
"label": "Rep Penalty Range",
"label": "Rep Pen Range",
"id": "setreppenrange",
"min": 0,
"max": 4096,
@@ -138,7 +138,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "float",
"label": "Rep Penalty Slope",
"label": "Rep Pen Slope",
"id": "setreppenslope",
"min": 0.0,
"max": 10.0,
@@ -153,7 +153,7 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "int",
"label": "Max Tokens",
"label": "Context Tokens",
"id": "settknmax",
"min": 512,
"max": 2048,
@@ -183,13 +183,13 @@ gensettingstf = [
{
"uitype": "slider",
"unit": "int",
"label": "W Info Depth",
"label": "WI Depth",
"id": "setwidepth",
"min": 1,
"max": 5,
"step": 1,
"default": 3,
"tooltip": "Number of historic actions to scan for W Info keys.",
"tooltip": "Number of historic actions to scan for World Info keys.",
"menu_path": "World Info",
"sub_path": "",
"classname": "user",
@@ -213,7 +213,7 @@ gensettingstf = [
{
"uitype": "toggle",
"unit": "bool",
"label": "Always Add Prompt",
"label": "Add Prompt",
"id": "setuseprompt",
"min": 0,
"max": 1,
@@ -264,7 +264,7 @@ gensettingstf = [
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Scan the AI's output for world info keys as it's generating the output.",
"tooltip": "Scan the AI's output for World Info keys as it's generating the output.",
"menu_path": "World Info",
"sub_path": "",
"classname": "story",
@@ -273,7 +273,7 @@ gensettingstf = [
{
"uitype": "toggle",
"unit": "bool",
"label": "No Prompt Generation",
"label": "No Prompt Gen",
"id": "setnopromptgen",
"min": 0,
"max": 1,
@@ -288,7 +288,7 @@ gensettingstf = [
{
"uitype": "toggle",
"unit": "bool",
"label": "Random Story Persist",
"label": "Prefilled Memory",
"id": "setrngpersist",
"min": 0,
"max": 1,
@@ -347,7 +347,7 @@ gensettingstf = [
"label": "Story Mode",
"id": "actionmode",
"default": 0,
"tooltip": "Choose the mode of KoboldAI",
"tooltip": "Choose the mode of KoboldAI.",
"menu_path": "Home",
"sub_path": "",
"classname": "story",
@@ -372,7 +372,7 @@ gensettingstf = [
{
"uitype": "toggle",
"unit": "bool",
"label": "Probability Calc",
"label": "Token Probabilities",
"id": "setshowprobs",
"min": 0,
"max": 1,
@@ -387,18 +387,114 @@ gensettingstf = [
{
"uitype": "toggle",
"unit": "bool",
"label": "Alt Text Generation",
"label": "Alt Text Gen",
"id": "alttextgen",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Inserts world info entries behind text that first triggers them for better context with unlimited depth",
"tooltip": "Inserts world info entries behind text that first triggers them for better context with unlimited depth.",
"menu_path": "Settings",
"sub_path": "Other",
"classname": "system",
"name": "alt_gen"
}
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Trim Sentences",
"id": "frmttriminc",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Remove text after last sentence closure. If no closure is found, all tokens will be returned.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmttriminc"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "No Blank Lines",
"id": "frmtrmblln",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Replace double newlines (\\n\\n) with single newlines to avoid blank lines.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtrmblln"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "No Special Chars",
"id": "frmtrmspch",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Remove special characters (@,#,%,^, etc).",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtrmspch"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Auto Spacing",
"id": "frmtadsnsp",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Add spaces automatically if needed.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtadsnsp"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Single Line",
"id": "singleline",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Only allows the AI to output anything before the enter",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "singleline"
},
{
"UI_V2_Only": True,
"uitype": "slider",
"unit": "int",
"label": "AN Depth",
"id": "singleline",
"min": 1,
"max": 5,
"step": 1,
"default": 3,
"tooltip": "The Author's Note will be entered this many actions back from the end of the game text",
"menu_path": "author_notes",
"sub_path": "",
"classname": "story",
"name": "andepth"
},
]
gensettingsik =[{
@@ -419,7 +515,7 @@ gensettingsik =[{
{
"uitype": "slider",
"unit": "float",
"label": "Top p Sampling",
"label": "Top P Sampling",
"id": "settopp",
"min": 0.0,
"max": 1.0,
@@ -434,7 +530,7 @@ gensettingsik =[{
{
"uitype": "slider",
"unit": "int",
"label": "Top k Sampling",
"label": "Top K Sampling",
"id": "settopk",
"min": 0,
"max": 100,
@@ -449,7 +545,7 @@ gensettingsik =[{
{
"uitype": "slider",
"unit": "float",
"label": "Tail-free Sampling",
"label": "Tail Free Sampling",
"id": "settfs",
"min": 0.0,
"max": 1.0,
@@ -464,7 +560,7 @@ gensettingsik =[{
{
"uitype": "slider",
"unit": "int",
"label": "Amount to Generate",
"label": "Output Length",
"id": "setikgen",
"min": 50,
"max": 3000,
@@ -479,13 +575,13 @@ gensettingsik =[{
{
"uitype": "slider",
"unit": "int",
"label": "W Info Depth",
"label": "WI Depth",
"id": "setwidepth",
"min": 1,
"max": 5,
"step": 1,
"default": 3,
"tooltip": "Number of historic actions to scan for W Info keys.",
"tooltip": "Number of historic actions to scan for World Info keys.",
"menu_path": "User",
"classname": "user",
"name": "widepth"
@@ -507,7 +603,7 @@ gensettingsik =[{
{
"uitype": "toggle",
"unit": "bool",
"label": "Always Add Prompt",
"label": "Add Prompt",
"id": "setuseprompt",
"min": 0,
"max": 1,
@@ -549,7 +645,7 @@ gensettingsik =[{
{
"uitype": "toggle",
"unit": "bool",
"label": "No Prompt Generation",
"label": "No Prompt Gen",
"id": "setnopromptgen",
"min": 0,
"max": 1,
@@ -563,7 +659,7 @@ gensettingsik =[{
{
"uitype": "toggle",
"unit": "bool",
"label": "Random Story Persist",
"label": "Prefilled Memory",
"id": "setrngpersist",
"min": 0,
"max": 1,
@@ -605,7 +701,7 @@ gensettingsik =[{
{
"uitype": "toggle",
"unit": "bool",
"label": "Probability Calculation",
"label": "Token Probabilities",
"id": "setshowprobs",
"min": 0,
"max": 1,
@@ -620,18 +716,98 @@ gensettingsik =[{
{
"uitype": "toggle",
"unit": "bool",
"label": "Alt Text Generation",
"label": "Alt Text Gen",
"id": "alttextgen",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Inserts world info entries behind text that first triggers them for better context with unlimited depth",
"tooltip": "Inserts world info entries behind text that first triggers them for better context with unlimited depth.",
"menu_path": "Settings",
"sub_path": "Other",
"classname": "system",
"name": "alt_gen"
}
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Trim Sentences",
"id": "frmttriminc",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Remove text after last sentence closure. If no closure is found, all tokens will be returned.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmttriminc"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "No Blank Lines",
"id": "frmtrmblln",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Replace double newlines (\\n\\n) with single newlines to avoid blank lines.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtrmblln"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "No Special Chars",
"id": "frmtrmspch",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Remove special characters (@,#,%,^, etc).",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtrmspch"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Auto Spacing",
"id": "frmtadsnsp",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Add spaces automatically if needed.",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "frmtadsnsp"
},
{
"UI_V2_Only": True,
"uitype": "toggle",
"unit": "bool",
"label": "Single Line",
"id": "singleline",
"min": 0,
"max": 1,
"step": 1,
"default": 0,
"tooltip": "Only allows the AI to output anything before the enter",
"menu_path": "Interface",
"sub_path": "Formatting",
"classname": "user",
"name": "singleline"
},
]
formatcontrols = [{
@@ -647,15 +823,15 @@ formatcontrols = [{
{
"label": "Remove special characters",
"id": "frmtrmspch",
"tooltip": "Remove special characters (@,#,%,^, etc)"
"tooltip": "Remove special characters (@,#,%,^, etc)."
},
{
"label": "Automatic spacing",
"id": "frmtadsnsp",
"tooltip": "Add spaces automatically if needed"
"tooltip": "Add spaces automatically if needed."
},
{
"label": "Single Line",
"id": "singleline",
"tooltip": "Only allows the AI to output anything before the enter"
}]
}]

View File

@@ -4,9 +4,7 @@ from flask import has_request_context
from flask_socketio import SocketIO
from collections import OrderedDict
rely_clients = {}
serverstarted = False
port = 5000
queue = None
def clean_var_for_emit(value):
@@ -17,15 +15,6 @@ def clean_var_for_emit(value):
else:
return value
def create_loopback_socketio():
sio = socketio_client.Client()
@sio.event
def connect():
pass
sio.connect('ws://localhost:{}/?rely=true'.format(port))
rely_clients[threading.get_ident()] = sio
return sio
def process_variable_changes(socketio, classname, name, value, old_value, debug_message=None):
if serverstarted and name != "serverstarted":
if debug_message is not None:
@@ -35,7 +24,7 @@ def process_variable_changes(socketio, classname, name, value, old_value, debug_
if isinstance(value, KoboldStoryRegister):
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)):
for i in value.actions:
socketio.emit("var_changed", {"classname": "story", "name": "actions", "old_value": None, "value":{"id": i, "action": value.actions[i]}}, broadcast=True, room="UI_2")
elif isinstance(value, KoboldWorldInfo):
value.send_to_ui()
@@ -109,32 +98,51 @@ class koboldai_vars(object):
self._model_settings.reset_for_model_load()
def calc_ai_text(self, submitted_text=""):
context = []
token_budget = self.max_length
used_world_info = []
used_tokens = self.sp_length
if self.tokenizer is None:
used_tokens = 99999999999999999999999
else:
used_tokens = self.sp_length
text = ""
# TODO: We may want to replace the "text" variable with a list-type
# class of context blocks, the class having a __str__ function.
if self.sp:
context.append({"type": "soft_prompt", "text": f"<{self.sp_length} tokens of Soft Prompt.>"})
# Header is never used?
# if koboldai_vars.model not in ("Colab", "API", "OAI") and self.tokenizer._koboldai_header:
# context.append({"type": "header", "text": f"{len(self.tokenizer._koboldai_header})
self.worldinfo_v2.reset_used_in_game()
#Add memory
memory_length = self.max_memory_length if self.memory_length > self.max_memory_length else self.memory_length
memory_text = None
if memory_length+used_tokens <= token_budget:
if self.memory_length > self.max_memory_length:
if self.tokenizer is None:
text = self.memory
memory_text = self.memory
else:
text += self.tokenizer.decode(self.tokenizer.encode(self.memory)[-self.max_memory_length-1:])
memory_text = self.tokenizer.decode(self.tokenizer.encode(self.memory)[-self.max_memory_length-1:])
else:
text += self.memory
memory_text = self.memory
context.append({"type": "memory", "text": memory_text})
if memory_text:
text += memory_text
#Add constant world info entries to memory
for wi in self.worldinfo_v2:
if wi['constant']:
if used_tokens+wi['token_length'] <= token_budget:
if used_tokens+0 if 'token_length' not in wi else wi['token_length'] <= token_budget:
used_tokens+=wi['token_length']
used_world_info.append(wi['uid'])
self.worldinfo_v2.set_world_info_used(wi['uid'])
text += wi['content']
wi_text = wi['content']
context.append({"type": "world_info", "text": wi_text})
text += wi_text
#Add prompt lenght/text if we're set to always use prompt
if self.useprompt:
@@ -156,18 +164,21 @@ class koboldai_vars(object):
match=True
break
if match:
if used_tokens+wi['token_length'] <= token_budget:
if used_tokens+0 if 'token_length' not in wi else wi['token_length'] <= token_budget:
used_tokens+=wi['token_length']
used_world_info.append(wi['uid'])
text += wi['content']
wi_text = wi['content']
context.append({"type": "world_info", "text": wi_text})
text += wi_text
self.worldinfo_v2.set_world_info_used(wi['uid'])
if self.prompt_length > self.max_prompt_length:
if self.tokenizer is None:
text += self.prompt
else:
text += self.tokenizer.decode(self.tokenizer.encode(self.prompt)[-self.max_prompt_length-1:])
else:
text += self.prompt
prompt_text = self.prompt
if self.tokenizer and self.prompt_length > self.max_prompt_length:
if self.tokenizer:
prompt_text += self.tokenizer.decode(self.tokenizer.encode(self.prompt)[-self.max_prompt_length-1:])
text += prompt_text
context.append({"type": "prompt", "text": self.prompt})
self.prompt_in_ai = True
else:
self.prompt_in_ai = False
@@ -177,13 +188,18 @@ class koboldai_vars(object):
#Start going through the actions backwards, adding it to the text if it fits and look for world info entries
game_text = ""
game_context = []
authors_note_final = self.authornotetemplate.replace("<|>", self.authornote)
used_all_tokens = False
for i in range(len(self.actions)-1, -1, -1):
if len(self.actions) - i == self.andepth and self.authornote != "":
game_text = "{}{}".format(self.authornotetemplate.replace("<|>", self.authornote), game_text)
game_text = "{}{}".format(authors_note_final, game_text)
game_context.insert(0, {"type": "authors_note", "text": authors_note_final})
if self.actions.actions[i]["Selected Text Length"]+used_tokens <= token_budget and not used_all_tokens:
used_tokens += self.actions.actions[i]["Selected Text Length"]
game_text = "{}{}".format(self.actions.actions[i]["Selected Text"], game_text)
selected_text = self.actions.actions[i]["Selected Text"]
game_text = "{}{}".format(selected_text, game_text)
game_context.insert(0, {"type": "action", "text": selected_text})
self.actions.set_action_in_ai(i)
#Now we need to check for used world info entries
for wi in self.worldinfo_v2:
@@ -201,10 +217,12 @@ class koboldai_vars(object):
match=True
break
if match:
if used_tokens+wi['token_length'] <= token_budget:
if used_tokens+0 if 'token_length' not in wi else wi['token_length'] <= token_budget:
used_tokens+=wi['token_length']
used_world_info.append(wi['uid'])
game_text = "{}{}".format(wi['content'], game_text)
wi_text = wi["content"]
game_text = "{}{}".format(wi_text, game_text)
game_context.insert(0, {"type": "world_info", "text": wi_text})
self.worldinfo_v2.set_world_info_used(wi['uid'])
else:
self.actions.set_action_in_ai(i, used=False)
@@ -212,7 +230,8 @@ class koboldai_vars(object):
#if we don't have enough actions to get to author's note depth then we just add it right before the game text
if len(self.actions) < self.andepth and self.authornote != "":
game_text = "{}{}".format(self.authornotetemplate.replace("<|>", self.authornote), game_text)
game_text = "{}{}".format(authors_note_final, game_text)
game_context.insert(0, {"type": "authors_note", "text": authors_note_final})
if not self.useprompt:
if self.prompt_length + used_tokens < token_budget:
@@ -233,20 +252,28 @@ class koboldai_vars(object):
match=True
break
if match:
if used_tokens+wi['token_length'] <= token_budget:
if used_tokens+0 if 'token_length' not in wi else wi['token_length'] <= token_budget:
used_tokens+=wi['token_length']
used_world_info.append(wi['uid'])
text += wi['content']
wi_text = wi["content"]
text += wi_text
context.append({"type": "world_info", "text": wi_text})
self.worldinfo_v2.set_world_info_used(wi['uid'])
self.prompt_in_ai = True
else:
self.prompt_in_ai = False
text += self.prompt
context.append({"type": "prompt", "text": self.prompt})
text += game_text
context += game_context
if self.tokenizer is None:
tokens = []
else:
tokens = self.tokenizer.encode(text)
self.context = context
return tokens, used_tokens, used_tokens+self.genamt
def __setattr__(self, name, value):
@@ -283,7 +310,7 @@ class koboldai_vars(object):
else:
return getattr(self._story_settings['default'], name)
class settings(object):
def to_json(self):
json_data = {'file_version': 2}
@@ -339,7 +366,7 @@ class settings(object):
class model_settings(settings):
local_only_variables = ['badwordsids', 'apikey', 'tqdm', 'socketio', 'default_preset']
no_save_variables = ['tqdm', 'tqdm_progress', 'tqdm_rem_time', 'socketio', 'modelconfig', 'custmodpth', 'generated_tkns',
'loaded_layers', 'total_layers', 'total_download_chunks', 'downloaded_chunks']
'loaded_layers', 'total_layers', 'total_download_chunks', 'downloaded_chunks', 'presets', 'default_preset']
settings_name = "model"
def __init__(self, socketio):
self.socketio = socketio
@@ -451,7 +478,7 @@ class model_settings(settings):
class story_settings(settings):
local_only_variables = ['socketio', 'tokenizer', 'koboldai_vars']
no_save_variables = ['socketio', 'tokenizer', 'koboldai_vars']
no_save_variables = ['socketio', 'tokenizer', 'koboldai_vars', 'context']
settings_name = "story"
def __init__(self, socketio, koboldai_vars, tokenizer=None):
self.socketio = socketio
@@ -505,11 +532,12 @@ class story_settings(settings):
self.story_id = int.from_bytes(os.urandom(16), 'little', signed=True) # this is a unique ID for the story. We'll use this to ensure when we save that we're saving the same story
self.memory_length = 0
self.prompt_length = 0
self.authornote_length = 512
self.authornote_length = 0
self.max_memory_length = 512
self.max_prompt_length = 512
self.max_authornote_length = 512
self.prompt_in_ai = False
self.context = []
def save_story(self):
print("Saving")
@@ -567,10 +595,10 @@ class story_settings(settings):
if name == 'tokenizer' and not new_variable:
self.memory_length = len(self.tokenizer.encode(self.memory))
self.prompt_length = len(self.tokenizer.encode(self.prompt))
self.authornote_length = len(self.tokenizer.encode(self.authornotetemplate.replace("<|>", self.authornote)))
self.authornote_length = 0 if self.authornote=="" else len(self.tokenizer.encode(self.authornotetemplate.replace("<|>", self.authornote)))
ignore = self.koboldai_vars.calc_ai_text()
elif name == 'authornote' or name == 'authornotetemplate':
self.authornote_length = len(self.tokenizer.encode(self.authornotetemplate.replace("<|>", self.authornote)))
self.authornote_length = 0 if self.authornote=="" else len(self.tokenizer.encode(self.authornotetemplate.replace("<|>", self.authornote)))
ignore = self.koboldai_vars.calc_ai_text()
elif name == 'memory':
self.memory_length = len(self.tokenizer.encode(self.memory))
@@ -610,6 +638,11 @@ class user_settings(settings):
self.wirmvwhtsp = False # Whether to remove leading whitespace from WI entries
self.widepth = 3 # How many historical actions to scan for WI hits
self.formatoptns = {'frmttriminc': True, 'frmtrmblln': False, 'frmtrmspch': False, 'frmtadsnsp': False, 'singleline': False} # Container for state of formatting options
self.frmttriminc = True
self.frmtrmblln = False
self.frmtrmspch = False
self.frmtadsnsp = False
self.singleline = False
self.importnum = -1 # Selection on import popup list
self.importjs = {} # Temporary storage for import data
self.loadselect = "" # Temporary storage for story filename to load
@@ -663,6 +696,7 @@ class system_settings(settings):
self.savedir = os.getcwd()+"\\stories"
self.hascuda = False # Whether torch has detected CUDA on the system
self.usegpu = False # Whether to launch pipeline with GPU support
self.splist = []
self.spselect = "" # Temporary storage for soft prompt filename to load
self.spmeta = None # Metadata of current soft prompt, or None if not using a soft prompt
self.spname = "Not in Use" # Name of the soft prompt
@@ -695,18 +729,31 @@ class system_settings(settings):
self.seed_specified = False # Whether or not the current RNG seed was specified by the user (in their settings file)
self.seed = None # The current RNG seed (as an int), or None if unknown
self.alt_gen = False # Use the calc_ai_text method for generating text to go to the AI
self.theme_list = [".".join(f.split(".")[:-1]) for f in os.listdir("./themes") if os.path.isfile(os.path.join("./themes", f))]
def __setattr__(self, name, value):
if name == "abort":
print("setting abort")
new_variable = name not in self.__dict__
old_value = getattr(self, name, None)
super().__setattr__(name, value)
if name == "abort":
print("set abort to {}".format(self.abort))
#Put variable change actions here
if name == 'serverstarted':
global serverstarted
serverstarted = value
if name not in self.local_only_variables and name[0] != "_" and not new_variable:
process_variable_changes(self.socketio, self.__class__.__name__.replace("_settings", ""), name, value, old_value)
if name == "aibusy" and value == False:
print("resetting abort as AI busy was set to false")
koboldai_vars.abort = False
if name == "abort":
print("set abort to {}".format(self.abort))
class KoboldStoryRegister(object):
def __init__(self, socketio, story_settings, koboldai_vars, tokenizer=None, sequence=[]):
@@ -768,7 +815,7 @@ class KoboldStoryRegister(object):
if self.tokenizer is not None:
self.actions[i]['Selected Text Length'] = len(self.tokenizer.encode(text))
else:
self.actions[i]['Selected Text Length'] = None
self.actions[i]['Selected Text Length'] = 0
self.actions[i]["In AI Input"] = False
process_variable_changes(self.socketio, "story", 'actions', {"id": i, 'action': self.actions[i]}, old)
ignore = self.koboldai_vars.calc_ai_text()
@@ -809,6 +856,7 @@ class KoboldStoryRegister(object):
def append(self, text):
self.clear_unused_options()
print("setting action_count {} -> {}".format(self.action_count, self.action_count+1))
self.action_count+=1
if self.action_count in self.actions:
if self.actions[self.action_count]["Selected Text"] != text:
@@ -839,11 +887,27 @@ class KoboldStoryRegister(object):
def append_options(self, option_list):
if self.action_count+1 in self.actions:
#First let's check if we did streaming, as we can just replace those items with these
old_options = copy.deepcopy(self.actions[self.action_count+1]["Options"])
old_options_text = [x['text'] for x in old_options]
for item in option_list:
if item not in old_options_text:
self.actions[self.action_count+1]['Options'].append({"text": item, "Pinned": False, "Previous Selection": False, "Edited": False, "Probabilities": []})
i=-1
for option in option_list:
i+=1
found = False
for item in self.actions[self.action_count+1]["Options"]:
if 'stream_id' in item and item['stream_id'] == i:
item['text'] = option
del item['stream_id']
found = True
break
elif item['text'] == option:
found = True
if 'stream_id' in item:
del item['stream_id']
found = True
break
if not found:
self.actions[self.action_count+1]['Options'].append({"text": option, "Pinned": False, "Previous Selection": False, "Edited": False, "Probabilities": []})
else:
old_options = None
self.actions[self.action_count+1] = {"Selected Text": "", "Selected Text Length": 0, "In AI Input": False, "Options": [{"text": x, "Pinned": False, "Previous Selection": False, "Edited": False, "Probabilities": []} for x in option_list]}
@@ -853,7 +917,7 @@ class KoboldStoryRegister(object):
def set_options(self, option_list, action_id):
if action_id not in self.actions:
old_options = None
self.action_id[action_id] = {"Selected Text": "", "Options": option_list}
self.actions[action_id] = {"Selected Text": "", "Options": option_list}
else:
old_options = self.actions[action_id]["Options"]
self.actions[action_id]["Options"] = []
@@ -919,14 +983,16 @@ class KoboldStoryRegister(object):
old_length = self.actions[action_step]["Selected Text Length"]
if option_number < len(self.actions[action_step]['Options']):
self.actions[action_step]["Selected Text"] = self.actions[action_step]['Options'][option_number]['text']
self.actions[action_step]["Probabilities"] = self.actions[action_step]['Options'][option_number]['Probabilities']
if 'Probabilities' in self.actions[action_step]['Options'][option_number]:
self.actions[action_step]["Probabilities"] = self.actions[action_step]['Options'][option_number]['Probabilities']
if self.tokenizer is not None:
self.actions[action_step]['Selected Text Length'] = len(self.tokenizer.encode(self.actions[action_step]['Options'][option_number]['text']))
else:
self.actions[action_step]['Selected Text Length'] = None
self.actions[action_step]['Selected Text Length'] = 0
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:
print("setting action_count {} -> {}".format(self.action_count, self.action_count+1))
self.action_count+=1
self.socketio.emit("var_changed", {"classname": "actions", "name": "Action Count", "old_value": None, "value":self.action_count}, broadcast=True, room="UI_2")
process_variable_changes(self.socketio, "story", 'actions', {"id": action_step, 'action': self.actions[action_step]}, None)
@@ -941,6 +1007,7 @@ class KoboldStoryRegister(object):
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.actions[action_id]['Selected Text Length'] = 0
print("setting action_count {} -> {}".format(self.action_count, self.action_count-1))
self.action_count -= 1
process_variable_changes(self.socketio, "story", 'actions', {"id": action_id, 'action': self.actions[action_id]}, None)
self.set_game_saved()
@@ -992,7 +1059,7 @@ class KoboldStoryRegister(object):
process_variable_changes(self.socketio, "story", 'actions', {"id": key, 'action': self.actions[key]}, None)
else:
for key in self.actions:
self.actions[key]['Selected Text Length'] = None
self.actions[key]['Selected Text Length'] = 0
process_variable_changes(self.socketio, "story", 'actions', {"id": key, 'action': self.actions[key]}, None)
ignore = self.koboldai_vars.calc_ai_text()
@@ -1031,7 +1098,6 @@ class KoboldStoryRegister(object):
process_variable_changes(self.socketio, "story", 'actions', {"id": self.action_count+1, 'action': self.actions[self.action_count+1]}, None)
def set_probabilites(self, probabilities, action_id=None):
print(probabilities)
if action_id is None:
action_id = self.action_count
if action_id in self.actions:
@@ -1137,15 +1203,28 @@ class KoboldWorldInfo(object):
self.sync_world_info_to_old_format()
self.socketio.emit("world_info_folder", {x: self.world_info_folder[x] for x in self.world_info_folder}, broadcast=True, room="UI_2")
def add_item(self, title, key, keysecondary, folder, constant, content, comment):
def add_item(self, title, key, keysecondary, folder, constant, manual_text, comment, use_wpp=False, wpp={'name': "", 'type': "", 'format': "W++", 'attributes': {}}):
if len(self.world_info) == 0:
uid = 0
else:
uid = max(self.world_info)+1
if use_wpp:
if wpp['format'] == "W++":
content = '[{}("{}")\n{{\n'.format(wpp['type'], wpp['name'])
for attribute in wpp['attributes']:
content = "{}{}({})\n".format(content, attribute, " + ".join(['"{}"'.format(x) for x in wpp['attributes'][attribute]]))
content = "{}}}]".format(content)
else:
content = '[ {}: "{}";'.format(wpp['type'], wpp['name'])
for attribute in wpp['attributes']:
content = "{} {}: {};".format(content, attribute, ", ".join(['"{}"'.format(x) for x in wpp['attributes'][attribute]]))
content = "{} ]".format(content[:-1])
else:
content = manual_text
if self.tokenizer is not None:
token_length = len(self.tokenizer.encode(content))
else:
token_length = None
token_length = 0
if folder is None:
folder = "root"
@@ -1165,11 +1244,14 @@ class KoboldWorldInfo(object):
"keysecondary": keysecondary,
"folder": folder,
"constant": constant,
'manual_text': manual_text,
"content": content,
"comment": comment,
"token_length": token_length,
"selective": len(keysecondary) > 0,
"used_in_game": constant
"used_in_game": constant,
'wpp': wpp,
'use_wpp': use_wpp
}
except:
print("Error:")
@@ -1185,16 +1267,30 @@ class KoboldWorldInfo(object):
self.socketio.emit("world_info_folder", {x: self.world_info_folder[x] for x in self.world_info_folder}, broadcast=True, room="UI_2")
self.socketio.emit("world_info_entry", self.world_info[uid], broadcast=True, room="UI_2")
ignore = self.koboldai_vars.calc_ai_text()
return uid
def edit_item(self, uid, title, key, keysecondary, folder, constant, content, comment, before=None):
def edit_item(self, uid, title, key, keysecondary, folder, constant, manual_text, comment, use_wpp=False, before=None, wpp={'name': "", 'type': "", 'format': "W++", 'attributes': {}}):
old_folder = self.world_info[uid]['folder']
#move the world info entry if the folder changed or if there is a new order requested
if old_folder != folder or before is not None:
self.add_item_to_folder(uid, folder, before=before)
if use_wpp:
if wpp['format'] == "W++":
content = '[{}("{}")\n{{\n'.format(wpp['type'], wpp['name'])
for attribute in wpp['attributes']:
content = "{}{}({})\n".format(content, attribute, " + ".join(['"{}"'.format(x) for x in wpp['attributes'][attribute]]))
content = "{}}}]".format(content)
else:
content = '[ {}: "{}";'.format(wpp['type'], wpp['name'])
for attribute in wpp['attributes']:
content = "{} {}: {};".format(content, attribute, ", ".join(['"{}"'.format(x) for x in wpp['attributes'][attribute]]))
content = "{} ]".format(content[:-1])
else:
content = manual_text
if self.tokenizer is not None:
token_length = len(self.tokenizer.encode(content))
else:
token_length = None
token_length = 0
if folder is None:
folder = "root"
@@ -1204,10 +1300,14 @@ class KoboldWorldInfo(object):
"keysecondary": keysecondary,
"folder": folder,
"constant": constant,
'manual_text': manual_text,
"content": content,
"comment": comment,
"token_length": token_length,
"selective": len(keysecondary) > 0
"selective": len(keysecondary) > 0,
"used_in_game": constant,
'wpp': wpp,
'use_wpp': use_wpp
}
self.story_settings.gamesaved = False
@@ -1265,22 +1365,38 @@ class KoboldWorldInfo(object):
for uid in self.world_info:
self.socketio.emit("world_info_entry", self.world_info[uid], broadcast=True, room="UI_2")
def to_json(self):
return {
"folders": {x: self.world_info_folder[x] for x in self.world_info_folder},
"entries": self.world_info
}
def to_json(self, folder=None):
if folder is None:
return {
"folders": {x: self.world_info_folder[x] for x in self.world_info_folder},
"entries": self.world_info
}
else:
return {
"folders": {x: self.world_info_folder[x] for x in self.world_info_folder if x == folder},
"entries": {x: self.world_info[x] for x in self.world_info if self.world_info[x]['folder'] == folder}
}
def load_json(self, data):
self.world_info = {int(x): data['entries'][x] for x in data['entries']}
self.world_info_folder = data['folders']
try:
self.sync_world_info_to_old_format()
except:
print(self.world_info)
print(data)
raise
self.send_to_ui()
def load_json(self, data, folder=None):
if folder is None:
self.world_info = {int(x): data['entries'][x] for x in data['entries']}
self.world_info_folder = data['folders']
#Make sure we have all the appropriate variables:
for item in self.world_info:
for column in ["uid","title","key","keysecondary","folder","constant","content","comment","token_length","selective","used_in_game"]:
if column not in item:
item[column] = None
try:
self.sync_world_info_to_old_format()
except:
print(self.world_info)
print(data)
raise
self.send_to_ui()
else:
for uid, item in data['entries'].items():
self.add_item(item['title'], item['key'], item['keysecondary'], folder, item['constant'], item['manual_text'], item['comment'],
use_wpp=item['use_wpp'], wpp=item['wpp'])
def sync_world_info_to_old_format(self):
#Since the old UI uses world info entries for folders, we need to make some up
@@ -1337,11 +1453,11 @@ class KoboldWorldInfo(object):
for key in self.world_info:
if self.world_info[key]["used_in_game"] != self.world_info[key]["constant"]:
self.world_info[key]["used_in_game"] = self.world_info[key]["constant"]
self.socketio.emit("world_info_entry", self.world_info[key], broadcast=True, room="UI_2")
self.socketio.emit("world_info_entry_used_in_game", {"uid": key, "used_in_game": False}, broadcast=True, room="UI_2")
def set_world_info_used(self, uid):
self.world_info[uid]["used_in_game"] = True
self.socketio.emit("world_info_entry", self.world_info[uid], broadcast=True, room="UI_2")
self.socketio.emit("world_info_entry_used_in_game", {"uid": uid, "used_in_game": True}, broadcast=True, room="UI_2")
def __setattr__(self, name, value):
new_variable = name not in self.__dict__

1
static/encoder.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -67,16 +67,16 @@ input[type="range"]::-ms-fill-upper {
list-style: none;
/*margin: 200px 0 20px;*/
padding: 0;
padding-left: 30px; /*Gui: this value should change to 10px when pinned*/
padding-left: 40px;
line-height: 24px;
height: 26px;
overflow: hidden;
font-size: 14px;
font-size: calc(12px + var(--font_size_adjustment));
font-family: verdana;
position: relative;
}
.tabrow.nomenu_icon {
padding-left: 10px;
padding-left: 35px;
}
.tabrow span {
cursor: pointer;
@@ -87,23 +87,22 @@ input[type="range"]::-ms-fill-upper {
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Edge, Opera and Firefox */
border: 1px solid var(--tab_color);
border: 1px solid #888;
background: var(--tab_color);
/*background: -o-linear-gradient(top, #337ab7 50%, #285070 100%);
background: -ms-linear-gradient(top, #337ab7 50%, #285070 100%);
background: -moz-linear-gradient(top, #337ab7 50%, #285070 100%);
background: -webkit-linear-gradient(top, #337ab7 50%, #285070 100%);
background: linear-gradient(top, #337ab7 50%, #285070 100%);*/
/*background: -o-linear-gradient(top, #337ab70 50%, #28507 100%);
background: -ms-linear-gradient(top, #337ab70 50%, #28507 100%);
background: -moz-linear-gradient(top, #337ab70 50%, #28507 100%);
background: -webkit-linear-gradient(top, #337ab70 50%, #28507 100%);
background: linear-gradient(top, #337ab70 50%, #28507 100%);*/
display: inline-block;
position: relative;
z-index: 0;
border-radius: 6px 6px 6px 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
/*box-shadow: 0 3px 3px rgba(0, 0, 0, 0.4), inset 0 1px 0 var(--tab_color);*/
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.4), inset 0 1px 0 #AAA;
text-shadow: 0 1px #AAA;
margin: 0 -2px;
padding: 0 12px;
margin: 0 -5px;
padding: 0 15px;
}
.tabrow span.selected {
background: #FFF;
@@ -111,8 +110,6 @@ input[type="range"]::-ms-fill-upper {
z-index: 2;
border-bottom-color: #FFF;
}
.tabrow:before {
position: absolute;
content: " ";
@@ -124,7 +121,7 @@ input[type="range"]::-ms-fill-upper {
}
.tabrow span:before,
.tabrow span:after {
border: 1px solid var(--tab_color);
border: 1px solid #AAA;
position: absolute;
bottom: -1px;
width: 5px;
@@ -132,34 +129,22 @@ input[type="range"]::-ms-fill-upper {
content: " ";
}
.tabrow span:before {
left: -6px;
left: -5px;
border-bottom-right-radius: 6px;
border-width: 0 1px 1px 0;
box-shadow: 2px 2px 0 var(--tab_color);
}
.tabrow span:after {
right: -6px;
right: -5px;
border-bottom-left-radius: 6px;
border-width: 0 0 1px 1px;
box-shadow: -2px 2px 0 var(--tab_color);
}
.tabrow span.selected:before {
box-shadow: 4px 2px 0 #FFF;
box-shadow: 2px 2px 0 #FFF;
}
.tabrow span.selected:after {
box-shadow: -4px 2px 0 #FFF;
}
.themerow .tabrow{
margin-top: 5px;
}
.themerow .tabrow:before {
position: absolute;
content: " ";
width: 100%;
bottom: 0;
left: 0;
border-bottom: 0px solid rgb(195, 50, 50);
z-index: 1;
box-shadow: -2px 2px 0 #FFF;
}
@@ -180,6 +165,10 @@ input[type="range"]::-ms-fill-upper {
width: 100%;
background: var(--layer1_palette);
grid-row: 2;
overflow-y: scroll;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-color);
}
@@ -192,12 +181,14 @@ input[type="range"]::-ms-fill-upper {
width: 100%;
}
.setting_container {
display: grid;
grid-template-areas: "label value"
"item item"
"minlabel maxlabel";
grid-template-rows: 20px 20px 20px;
grid-template-rows: 20px 23px 20px;
grid-template-columns: 147px 30px;
row-gap: 0.2em;
background-color: var(--setting_background);
@@ -207,12 +198,28 @@ input[type="range"]::-ms-fill-upper {
margin: 2px;
}
#story_menu_author .setting_container {
display: grid;
grid-template-areas: "label value"
"item item"
"minlabel maxlabel";
grid-template-rows: 20px 23px 20px;
grid-template-columns: 288px 60px;
row-gap: 0.2em;
background-color: var(--setting_background);
color: var(--setting_text);
border-radius: var(--radius_settings_background);
padding: 3px;
margin: 2px;
}
.setting_container_single {
display: grid;
grid-template-areas: "label"
"item";
grid-template-rows: 20px 110px;
grid-template-columns: 167px;
grid-template-rows: 20px auto;
grid-template-columns: 177px;
row-gap: 0.2em;
background-color: var(--setting_background);
color: var(--text);
@@ -221,7 +228,7 @@ input[type="range"]::-ms-fill-upper {
margin: 2px;
}
.setting_container_single .setting_item{
font-size: 0.93em;
font-size: calc(0.93em + var(--font_size_adjustment));
margin-left: 10px;
}
@@ -232,7 +239,7 @@ input[type="range"]::-ms-fill-upper {
overflow: hidden;
padding: 5px;
padding-top: 0px;
font-size: 0.8em;
font-size: calc(0.8em + var(--font_size_adjustment));
}
.setting_maxlabel {
@@ -242,7 +249,7 @@ input[type="range"]::-ms-fill-upper {
padding: 5px;
padding-top: 0px;
text-align: right;
font-size: 0.8em;
font-size: calc(0.8em + var(--font_size_adjustment));
}
.setting_label {
@@ -257,7 +264,7 @@ input[type="range"]::-ms-fill-upper {
.setting_value {
text-align: right;
grid-area: value;
font-size: 12px;
font-size: calc(12px + var(--font_size_adjustment));
padding: 2px;
padding-top: 0px;
background-color: inherit;
@@ -278,11 +285,13 @@ input[type="range"]::-ms-fill-upper {
.setting_item_input {
width:95%;
}
/*-----------------------------------------------*/
.helpicon {
color: var(--help_icon);
cursor: help;
font-size: 14px !important;
font-size: calc(14px + var(--font_size_adjustment)) !important;
flex: auto;
width: 15px;
align-self: flex-end;
@@ -314,7 +323,7 @@ input[type="range"]::-ms-fill-upper {
.menu_pin {
position: absolute;
top:10px;
left: calc(var(--flyout_menu_width) - 25px);
left: calc(var(--flyout_menu_width) - 20px);
z-index:50;
width: 25px;
height: 25px;
@@ -336,12 +345,12 @@ input[type="range"]::-ms-fill-upper {
.SideMenu {
height: 100%;
z-index: 4;
width: var(--flyout_menu_closed_width);
width: var(--flyout_menu_width);
box-shadow: var(--left_menu_strong_shadow);
position: fixed;
z-index: 3;
top: 0;
left: 0;
right: 100%;
background-color: var(--flyout_background);
overflow-x: hidden;
transition: 0.5s;
@@ -351,23 +360,15 @@ input[type="range"]::-ms-fill-upper {
@media only screen and (min-aspect-ratio: 7/5) {
.SideMenu.pinned {
height: 100%;
width: var(--flyout_menu_width);
position: fixed;
z-index: 3;
top: 0;
left: 0;
right: calc(100% - var(--flyout_menu_width));
background-color: var(--flyout_background_pinned);
box-shadow: var(--light_shadow_value);
overflow-x: hidden;
transition: 0.5s;
box-shadow: var(--left_menu_light_shadow);
border-radius: 0px;
}
}
.SideMenu.open {
width: var(--flyout_menu_width);
z-index: 3;
right: calc(100% - var(--flyout_menu_width));
}
.SideMenu .flyout_menu_contents {
@@ -376,19 +377,32 @@ input[type="range"]::-ms-fill-upper {
height: calc(100vh - 40px);
}
.settings_footer {
border-top:2px;
border-top-color: var(--setting_footer_border_color);
border-top-style: solid;
color: var(--setting_footer_text_color);
background-color: var(--setting_footer_background_color);
}
.Model_Info{
position: relative;
margin: 25px 0 0 10px;
}
#model_title{
font-size: x-large;
.Model_Icon{
text-align: center;
}
#model_title{
font-size: calc(1.8em + var(--font_size_adjustment));
text-align: center;
padding: 5px 0 0 0;
}
#text_runningmodel{
position: absolute;
font-size: small;
font-size: calc(0.9em + var(--font_size_adjustment));
top: -15px;
}
@@ -397,10 +411,12 @@ input[type="range"]::-ms-fill-upper {
position: relative;
}
/*
.story_title_area .var_sync_story_story_name {
border-bottom: 1px solid;
padding-bottom: 3px;
}
*/
.story_title_area .var_sync_story_story_name[contenteditable="true"]:active,
.story_title_area .var_sync_story_story_name[contenteditable="true"]:focus{
@@ -412,18 +428,23 @@ input[type="range"]::-ms-fill-upper {
}
.story_title {
font-size: x-large;
font-size: calc(1.8em + var(--font_size_adjustment));
text-align: center;
border-bottom: 1px;
border-bottom-style: solid;
margin-left: 40px;
margin-right: 40px;
padding: 10px 0 0 0;
}
#text_storyname{
font-size: small;
font-size: calc(0.9em + var(--font_size_adjustment));
top: -10px;
position: absolute;
margin: 0 0 0 10px;
}
.story_title_icons {
font-size: 18px;
font-size: calc(18px + var(--font_size_adjustment));
padding: 10px 0 0 0;
margin-left: 125px;
}
@@ -545,7 +566,7 @@ input[type="range"]::-ms-fill-upper {
.bias_slider_min {
grid-area: min;
font-size: x-small;
font-size: calc(0.8em + var(--font_size_adjustment));
margin-right: 5px;
margin-left: 5px;
}
@@ -557,7 +578,7 @@ input[type="range"]::-ms-fill-upper {
.bias_slider_max {
grid-area: max;
font-size: x-small;
font-size: calc(0.8em + var(--font_size_adjustment));
text-align: right;
margin-right: 5px;
margin-left: 5px;
@@ -571,19 +592,91 @@ input[type="range"]::-ms-fill-upper {
.bias_header_phrase {
grid-area: phrase;
font-size: small;
font-size: calc(0.9em + var(--font_size_adjustment));
}
.bias_header_score {
grid-area: percent;
font-size: small;
font-size: calc(0.9em + var(--font_size_adjustment));
}
.bias_header_max {
grid-area: max;
font-size: small;
font-size: calc(0.9em + var(--font_size_adjustment));
}
/* Theme */
.collapsable_header .material-icons-outlined {
padding-top: 5px;
}
.var_sync_system_theme_list{
padding: 6px 0 9px 0;
margin-left: 10px;
border-radius: 5px;
color: var(--dropdown_text);
background: var(--dropdown_background);
}
#palette_area {
width: 100%;
text-align: center;
}
#save_theme_area {
width: 100%;
position: relative;
}
#save_theme_name {
width: 88%;
margin: 0 0 5px -25px;
}
#palette_area .material-icons-outlined {
position: absolute;
}
#Palette {
width: 100%;
}
#Palette_Table{
width: 100%;
}
.Theme_Input {
width: 100%;
}
.advanced_theme {
margin: 10px 10px 0 auto;
padding: 2px 4px 2px 4px;
border-radius: var(--radius_wi_card);
background-color: var(--wi_tag_color);
}
.advanced_theme:hover {
filter: brightness(85%);
}
/* Tweaks */
.tweak-container {
display: flex;
align-items: center;
justify-content: space-between;
color: var(--setting_text);
background-color: var(--setting_background);
border-radius: var(--radius_settings_background);
padding: 10px 8px;
margin-bottom: 5px;
width: 100%;
}
#Tweaks {
/* Don't add space under last tweak-container. Also, CSS, why no last-of-class!?!? */
margin-bottom: 0px;
}
/*----------------RIGHT FLYOUT MENU------------------*/
.right_menu_icon {
@@ -606,7 +699,6 @@ input[type="range"]::-ms-fill-upper {
.rightSideMenu {
z-index: 3;
height: 100%;
width: 0;
position: fixed;
box-shadow: var(--right_menu_strong_shadow);
z-index: 3;
@@ -616,30 +708,29 @@ input[type="range"]::-ms-fill-upper {
overflow-x: hidden;
overflow-y: hidden;
transition: 0.5s;
padding-top: 20px;
padding-bottom: 10px;
padding-top: 8px;
border-radius: var(--radius_unpinned_menu) 0px 0px var(--radius_unpinned_menu);
width: var(--flyout_menu_width);
left: 100%;
}
.rightSideMenu.open {
width: var(--flyout_menu_width);
z-index: 3;
left: calc(100% - var(--flyout_menu_width));
}
@media only screen and (min-aspect-ratio: 7/5) {
/* Desktop Mode */
.rightSideMenu.pinned {
width: var(--flyout_menu_width);
box-shadow: var(--right_menu_light_shadow);
border-radius: 0px 0px 0px 0px;
left: calc(100% - var(--flyout_menu_width));
box-shadow: var(--right_menu_light_shadow);
border-radius: 0px 0px 0px 0px;
}
}
.rightSideMenu .flyout_menu_contents {
overflow-x: hidden;
overflow-y: auto;
height: calc(100vh - 150px);
overflow-y: hidden;
height: calc(100vh - 34px);
}
@@ -654,10 +745,20 @@ input[type="range"]::-ms-fill-upper {
}
}
@media only screen and (min-aspect-ratio: 7/5) {
.story_menu_pin {
position: absolute;
top:10px;
right: calc(var(--flyout_menu_width) - 35px);
z-index:50;
width: 25px;
height: 25px;
color: #999;
display: inline-block;
transition: left 0.5s;
cursor: pointer;
}
}
table.server_vars {
@@ -681,22 +782,73 @@ td.server_vars {
white-space: pre-wrap;
}
.story_category_area{
.story_category_area:not(#story_menu_wi){
margin: 10px 10px 0 10px;
overflow-y: scroll;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-color);
}
#story_menu_wi{
margin-top: 10px;
}
#story_menu_notes{
margin: 10px 10px 0 10px;
.story_category_area {
padding-bottom: 10px;
overflow-y: scroll;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-color);
}
#story_menu_memory{
margin: 10px 10px 0 10px;
.token_breakdown {
height: 5px;
overflow: hidden;
display: block;
width: 100%;
padding-left: 20px;
padding-right: 35px;
margin-bottom: 10px;
flex-shrink: 0;
cursor: pointer;
}
.token_breakdown div {
float: left;
height: 100%;
text-align: center;
}
.WI_Folder_Header {
margin-left: 10px;
display: grid;
grid-template-areas: "folder expand title upload_box upload download";
grid-template-columns: 15px 30px auto 0px 25px 25px;
}
.WI_Folder_Header .folder {
grid-area: folder;
}
.WI_Folder_Header .expand {
grid-area: expand;
}
.WI_Folder_Header .title {
grid-area: title;
}
.WI_Folder_Header .upload_box {
grid-area: upload_box;
display: none;
}
.WI_Folder_Header .download {
grid-area: download;
}
#story_menu_author{
margin: 10px 10px 0 10px;
}
#world_info_folder_root.WI_Folder {
margin-left: 10px;
@@ -706,11 +858,27 @@ td.server_vars {
margin: 5px;
}
.wi_title {
position: relative;
bottom: 4px;
margin-left: 4px;
}
.wi_add_text {
position: relative;
top: 1px;
}
.wi_add_button{
margin: 0 0 0 10px;
padding: 4px 4px 4px 4px;
border-radius: var(--radius_wi_card);
background-color: #004397;
background-color: var(--wi_tag_color);
}
.wi_add_button .material-icons-outlined{
position: relative;
top: 7px;
}
.wi_folder_collapser, .wi_add_button, #new_world_info_button {
@@ -794,6 +962,7 @@ td.server_vars {
body {
background-color: var(--background);
color: var(--text);
font-size: calc(14px + var(--font_size_adjustment));
/* Firefox scroll */
scrollbar-width: thin;
@@ -887,7 +1056,7 @@ body {
margin-top: 10px;
vertical-align: bottom;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
font-size: calc((1em*var(--game_screen_font_size_adjustment)) + var(--font_size_adjustment));
line-height: 1.42857143;
}
@@ -1005,6 +1174,17 @@ body {
.themerow {
grid-area: theme;
width: 500px;
margin-left: 10px;
}
.themerow .tabrow:before {
border-bottom: 0;
}
.themerow .tabrow {
line-height: 25px;
padding-left: 10px;
margin-top: 2px;
}
.inputrow {
@@ -1020,6 +1200,8 @@ body {
}
#random_game_prompt{
display: flex;
flex-direction: column;
grid-area: textarea;
}
@@ -1097,7 +1279,7 @@ body {
z-index: 0;
height: 100%;
text-align: center;
font-size: 0.875em;
font-size: calc(0.875em + var(--font_size_adjustment));
}
/*#btnsend{
@@ -1159,11 +1341,11 @@ body {
width: 80%;
height: 80vh;
border-radius: 15px;
box-shadow: 0 0 35px 20px#1b1b1f;
box-shadow: var(--popup_shadow);
background-color: var(--popup_background_color);
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow: hidden;
}
}
@@ -1176,35 +1358,20 @@ body {
width: 50%;
height: 80vh;
border-radius: 15px;
box-shadow: 0 0 35px 20px#1b1b1f;
box-shadow: var(--popup_shadow);
background-color: var(--popup_background_color);
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow: hidden;
}
}
.popup#error_message {
background-color: var(--error_palette);
color: var(--on_error_palette);
height: 30vh;
top: 35vh;
}
.popup .title {
width: 100%;
background-color: var(--popup_title_bar_color);
color: var(--popup_title_bar_color_text);
text-align: center;
font-size: 1.3em;
}
#error_message .title {
width: 100%;
background-color: var(--error_container_palette);
color: var(--on_error_container_palette);
text-align: center;
font-size: 1.3em;
font-size: calc(1.3em + var(--font_size_adjustment));
}
.popup .action_button {
@@ -1212,17 +1379,11 @@ body {
color: var(--popup_button_color_text);
}
.popup#error_message .btn-primary {
background-color: var(--error_palette);
color: var(--on_error_palette);
border-color: var(--on_error_palette);
}
.popup .popup_list_area {
overflow-x: hidden;
overflow-y: scroll;
flex-grow: 1;
flex-shrink: 0;
flex-shrink: 1;
flex-basis: auto;
}
@@ -1288,10 +1449,6 @@ body {
padding: 0 10px 0 10px;
}
#error_message .popup_load_cancel{
background-color: var(--error_container_palette);
color: var(--on_error_container_palette);
}
.popup_load_cancel_button {
color: var(--popup_cancel_button_color_text);
@@ -1301,6 +1458,45 @@ body {
display: inline;
}
#error_message.popup {
background-color: var(--error_palette);
color: var(--on_error_palette);
height: 30vh;
top: 35vh;
overflow: hidden;
}
#error_message .title {
width: 100%;
background-color: var(--error_container_palette);
color: var(--on_error_container_palette);
text-align: center;
font-size: calc(1.3em + var(--font_size_adjustment));
}
#error_message.popup .btn-primary {
background-color: var(--error_palette);
color: var(--on_error_palette);
border-color: var(--on_error_palette);
}
#error_message .popup_load_cancel{
background-color: var(--error_container_palette);
color: var(--on_error_container_palette);
}
#error_message.popup .popup_list_area {
overflow-x: hidden;
overflow-y: scroll;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
background-color: var(--error_container_palette);
color: var(--on_error_container_palette);
}
.breadcrumbitem {
padding: 5px 10px 5px 10px;
color: #ffffff;
@@ -1355,7 +1551,7 @@ body {
color: var(--popup_title_bar_color_text);
overflow: hidden;
text-align: left;
font-size: 0.8em;
font-size: calc(0.8em + var(--font_size_adjustment));
}
.model_setting_maxlabel {
@@ -1364,7 +1560,7 @@ body {
grid-area: maxlabel;
overflow: hidden;
text-align: right;
font-size: 0.8em;
font-size: calc(0.8em + var(--font_size_adjustment));
}
.model_setting_label {
@@ -1397,7 +1593,109 @@ body {
.model_setting_item_input {
width:95%;
}
/*------------------------------ Context Viewer --------------------------------------------*/
#context-viewer-container {
position: absolute;
left: 0px;
top: 0px;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.7);
width: 100vw;
height: 100vh;
z-index: 20;
}
#context-viewer {
display: flex;
flex-direction: column;
width: 50%;
height: 75%;
padding-bottom: 10px;
background-color: var(--layer1_palette);
}
#context-viewer-header {
display: flex;
justify-content: space-between;
padding: 5px;
background-color: var(--background);
margin-bottom: 3px;
}
#context-viewer-header-right {
display: flex;
flex-direction: row;
}
#context-viewer-close {
cursor: pointer;
float: right;
}
#context-viewer-header > h3 {
margin: 0px;
margin-top: 3px;
}
#context-container {
overflow-y: auto;
height: 100%;
flex-grow: 1;
padding: 0px 10px;
}
.context-symbol {
font-size: 1em !important;
position: relative;
top: 3px;
opacity: 0.5;
}
.context-block, .context-block-example{
margin: 0px 2px;
}
.context-block:hover {
outline: 1px solid gray;
}
.context-sp {background-color: var(--context_colors_soft_prompt);}
.context-prompt {background-color: var(--context_colors_prompt);}
.context-wi {background-color: var(--context_colors_world_info);}
.context-memory {background-color: var(--context_colors_memory);}
.context-an {background-color: var(--context_colors_authors_notes);}
.context-action {background-color: var(--context_colors_game_text);}
/* File Drag Indicator */
#file-upload-notice {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
left: 0px;
top: 0px;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99999999;
width: 100vw;
height: 100vh;
}
#file-upload-notice > span {
font-size: 50vh;
opacity: 0.7;
}
/*---------------------------------- Global ------------------------------------------------*/
.hidden {
display: none;
@@ -1421,7 +1719,8 @@ input {
resize: none;
border-color: white;
border-width: 1px;
border-style:solid;
border-style: solid;
outline: none;
}
.action_button {
@@ -1473,6 +1772,7 @@ button.disabled {
textarea {
background-color: var(--input_background);
color: var(--text);
outline: none;
}
.pulse {
@@ -1519,7 +1819,7 @@ body.NotConnected {
font-family: 'Material Icons Outlined';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
font-size: calc(24px + var(--font_size_adjustment)); /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
@@ -1540,10 +1840,48 @@ body.NotConnected {
font-feature-settings: 'liga';
}
.material-icons-outlined.cursor:hover{
filter: brightness(85%);
}
h2 .material-icons-outlined {
font-size: 32px;
font-size: calc(32px + var(--font_size_adjustment));
}
.flyout_menu_contents {
scrollbar-width: thin;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.collapsable_header {
cursor: pointer;
}
.material-icons-outlined,
.collapsable_header,
.section_header,
.help_text,
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.section_header {
margin-left: 2px;
margin-bottom: 4px;
}
.help_text {
margin-left: 6px;
margin-bottom: 0.7em;
opacity: 0.7;
font-size: calc(0.9em + var(--font_size_adjustment));
display: block;
color: var(--setting_category_help_text_color);
}

File diff suppressed because it is too large Load Diff

169
static/tokenizer.js Normal file
View File

@@ -0,0 +1,169 @@
import encoder from "./encoder.js";
import bpe_file from "./vocab.bpe.js";
const range = (x, y) => {
const res = Array.from(Array(y).keys()).slice(x)
return res
}
const ord = x => {
return x.charCodeAt(0)
}
const chr = x => {
return String.fromCharCode(x)
}
const textEncoder = new TextEncoder("utf-8")
const encodeStr = str => {
return Array.from(textEncoder.encode(str)).map(x => x.toString())
}
const textDecoder = new TextDecoder("utf-8")
const decodeStr = arr => {
return textDecoder.decode(new Uint8Array(arr));
}
const dictZip = (x, y) => {
const result = {}
x.map((_, i) => { result[x[i]] = y[i] })
return result
}
function bytes_to_unicode() {
const bs = range(ord('!'), ord('~') + 1).concat(range(ord('¡'), ord('¬') + 1), range(ord('®'), ord('ÿ') + 1))
let cs = bs.slice()
let n = 0
for (let b = 0; b < 2 ** 8; b++) {
if (!bs.includes(b)) {
bs.push(b)
cs.push(2 ** 8 + n)
n = n + 1
}
}
cs = cs.map(x => chr(x))
const result = {}
bs.map((_, i) => { result[bs[i]] = cs[i] })
return result
}
function get_pairs(word) {
const pairs = new Set()
let prev_char = word[0]
for (let i = 1; i < word.length; i++) {
const char = word[i]
pairs.add([prev_char, char])
prev_char = char
}
return pairs
}
const pat = /'s|'t|'re|'ve|'m|'l l|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu
const decoder = {}
Object.keys(encoder).map(x => { decoder[encoder[x]] = x })
const lines = bpe_file.split('\n')
// bpe_merges = [tuple(merge_str.split()) for merge_str in bpe_data.split("\n")[1:-1]]
const bpe_merges = lines.slice(1, lines.length - 1).map(x => {
return x.split(/(\s+)/).filter(function(e) { return e.trim().length > 0 })
})
const byte_encoder = bytes_to_unicode()
const byte_decoder = {}
Object.keys(byte_encoder).map(x => { byte_decoder[byte_encoder[x]] = x })
const bpe_ranks = dictZip(bpe_merges, range(0, bpe_merges.length))
const cache = {}
function bpe(token) {
if (token in cache) {
return cache[token]
}
let word = token.split('')
let pairs = get_pairs(word)
if (!pairs) {
return token
}
while (true) {
const minPairs = {}
Array.from(pairs).map(pair => {
const rank = bpe_ranks[pair]
minPairs[(isNaN(rank) ? 10e10 : rank)] = pair
})
const bigram = minPairs[Math.min(...Object.keys(minPairs).map(x => {
return parseInt(x)
}
))]
if (!(bigram in bpe_ranks)) {
break
}
const first = bigram[0]
const second = bigram[1]
let new_word = []
let i = 0
while (i < word.length) {
const j = word.indexOf(first, i)
if (j === -1) {
new_word = new_word.concat(word.slice(i))
break
}
new_word = new_word.concat(word.slice(i, j))
i = j
if (word[i] === first && i < word.length - 1 && word[i + 1] === second) {
new_word.push(first + second)
i = i + 2
} else {
new_word.push(word[i])
i = i + 1
}
}
word = new_word
if (word.length === 1) {
break
} else {
pairs = get_pairs(word)
}
}
word = word.join(' ')
cache[token] = word
return word
}
export function encode(text) {
let bpe_tokens = []
const matches = Array.from(text.matchAll(pat)).map(x => x[0])
for (let token of matches) {
token = encodeStr(token).map(x => {
return byte_encoder[x]
}).join('')
const new_tokens = bpe(token).split(' ').map(x => encoder[x])
bpe_tokens = bpe_tokens.concat(new_tokens)
}
return bpe_tokens
}
export function decode(tokens) {
let text = tokens.map(x => decoder[x]).join('')
text = decodeStr(text.split('').map(x => byte_decoder[x]))
return text
}

1
static/vocab.bpe.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<script type="module">import {encode, decode} from "./static/tokenizer.js";window.encode = encode;window.decode = decode;</script>
<link href="static/open-iconic/css/open-iconic.css" rel="stylesheet">
<link rel="stylesheet" href="static/bootstrap-toggle.min.css">
<link rel="stylesheet" href="static/bootstrap.min.css">
@@ -39,6 +40,15 @@
<div id="disconnect_message"><center><h1>Disconnected</h1></center></div>
<div class="gametext" id="Selected Text">
<span id="story_prompt" class="var_sync_story_prompt var_sync_alt_story_prompt_length var_sync_alt_story_prompt_in_ai rawtext" contenteditable=true onblur="if (getAttribute(this, 'old_text') != this.textContent) {sync_to_server(this);}" onkeydown="detect_enter_text"></span>
<span id="Delete Me">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</div>
</div>
<!------------ Sequences --------------------->
@@ -60,19 +70,21 @@
<!------------ Input Area--------------------->
<div class="inputrow" id="inputrow_container">
<div id="random_game_prompt" class="hidden">
<input type="text" autocomplete="off" style="width: 100%;" id="themetext" placeholder="Theme for Random Story" oninput='if (this.value != "") {
document.getElementById("input_text").value = "";'/>
<input type="text" autocomplete="off" id="themetext" placeholder="Theme for Random Story" oninput='if (this.value != "") {
document.getElementById("input_text").value = "";}'/>
<span class="help_text" style="margin:0px;margin-top:5px;">The AI can create a prompt for you! Optionally type in one or more themes above, or let the AI do it's thing.</span>
</div>
<textarea autocomplete="off" row=5 id="input_text" placeholder="Enter Prompt Here" oninput='if (this.value != "") {
document.getElementById("themetext").value = "";
}'></textarea>
<div class="statusbar_outer hidden">
<div class="statusbar_inner" style="width:0%">0%</div>
}'
onkeyup="calc_token_usage()"></textarea>
<div class="statusbar_outer hidden" id="status_bar" onclick="socket.emit('abort','');">
<div class="statusbar_inner" style="width:0%" onclick="socket.emit('abort','');">0%</div>
</div><br>
<button type="button" class="btn action_button submit var_sync_alt_system_aibusy" system_aibusy=False id="btnsend"
<button type="button" class="btn action_button submit var_sync_alt_system_aibusy" system_aibusy=False id="btnsubmit"
onclick="socket.emit('submit', {'data': document.getElementById('input_text').value, 'theme': document.getElementById('themetext').value});document.getElementById('input_text').value = '';document.getElementById('themetext').value = '';"
>Submit</button>
<button type="button" class="btn action_button submited var_sync_alt_system_aibusy" system_aibusy=False id="btnsend"><img id="thinking" src="static/thinking.gif" class="force_center" onclick="socket.emit('abort','');"></button>
<button type="button" class="btn action_button submited var_sync_alt_system_aibusy" system_aibusy=False id="btnsent"><img id="thinking" src="static/thinking.gif" class="force_center" onclick="socket.emit('abort','');"></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>
@@ -100,5 +112,36 @@
{% include 'templates.html' %}
</div>
<iframe id="download_iframe" style="display:none;"></iframe>
<div id="context-viewer-container" class="hidden">
<div id="context-viewer">
<div id="context-viewer-header">
<h3 class="noselect">Context Viewer</h3>
<div id="context-viewer-header-right">
<div>
<span class="noselect">Key:</span>
<div>
<span class="noselect context-block-example context-sp">Soft Prompt</span>
<span class="noselect context-block-example context-prompt">Prompt</span>
<span class="noselect context-block-example context-wi">World Info</span>
<span class="noselect context-block-example context-memory">Memory</span>
<span class="noselect context-block-example context-an">Author's Note</span>
<span class="noselect context-block-example context-action">Action</span>
</div>
</div>
<span id="context-viewer-close" class="material-icons-outlined">close</span>
</div>
</div>
<span class="help_text">
Context is the text the AI is sent when you ask it to generate text.
As the context is limited in size, you can use the Context Viewer to check if things you want the AI to know are in the context.
</span>
<div id="context-container"></div>
</div>
</div>
<div id="file-upload-notice" class="hidden">
<span class="material-icons-outlined">upload_file</span>
</div>
</body>
</html>

View File

@@ -106,4 +106,16 @@
<div class="popup_load_cancel">
<button type="button" class="btn btn-primary" onclick="document.getElementById('error_message').classList.add('hidden');">Ok</button>
</div>
</div>
<!---------------- Advanced Theme Editor ---------------------->
<div class="popup hidden" id="advanced_theme_editor">
<div class="title">
<div class="popuptitletext">Advanced Theme Editor</div>
</div>
<div id="popup_list_area" class="popup_list_area">
<table border=1 id="advanced_theme_editor_table"></table>
</div>
<div class="popup_load_cancel">
<button type="button" class="btn btn-primary" onclick="document.getElementById('advanced_theme_editor').classList.add('hidden');">Ok</button>
</div>
</div>

View File

@@ -30,7 +30,10 @@
<span class="setting_menu_button selected" onclick="show_setting_menu(this);">Home</span>
<span class="setting_menu_button" onclick="show_setting_menu(this);">Settings</span>
<span class="setting_menu_button" onclick="show_setting_menu(this);">Interface</span>
<span style="float: right;margin-right: 30px;" onclick="window.open('https://github.com/KoboldAI/KoboldAI-Client/wiki');">Help</span>
<span style="float: right;margin-right: 30px;padding: 0px 10px;" onclick="window.open('https://github.com/KoboldAI/KoboldAI-Client/wiki');">
Help
<icon class="material-icons-outlined" style="font-size:14px;position:relative;top:2px;">open_in_new</icon>
</span>
</div>
<div class="flyout_menu_contents">
@@ -44,8 +47,10 @@
<div id="text_runningmodel">
<b>Running Model: </b>
</div>
<div>
<button class="btn action_button" onclick="socket.emit('load_model_button', {});">Load Model</button>
<div class="Model_Icon">
<span class="material-icons-outlined cursor" title="Load Model" onclick="socket.emit('load_model_button', {});">folder_open</span>
</div>
<div style="text-align: center;">
<select class="var_sync_model_selected_preset settings_select presets" onchange='sync_to_server(this)'><option>Preset</option></select>
</div>
</div>
@@ -86,7 +91,7 @@
<select class="var_sync_model_selected_preset settings_select presets" onchange='sync_to_server(this)'><option>Preset</option></select>
</div>
{% with menu='Settings' %}
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Generation</h4>
</div>
<div class="setting_tile_area">
@@ -95,23 +100,24 @@
{% endwith %}
</div>
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Sampling</h4>
</div>
<span class="help_text">Change how the AI decides what to say.</span>
<div class="setting_tile_area">
<div class="setting_container_single">
<!---Top Row---->
<span class="setting_label">
<span>Sample Order:&nbsp;</span><span class="helpicon material-icons-outlined" title="Help Text Here">help_icon</span>
<span>Samplers Order:&nbsp;</span><span class="helpicon material-icons-outlined" title="Changes the order of the samplers to have a considerably different effect than just leaving the samplers at their default order.">help_icon</span>
</span>
<!---Bottom Row---->
<span class="setting_item">
<div style="display:flex;flex-direction:row;">
<ul id="sample_order_list" style="width:calc(var(--flyout_menu_width) - 60px);list-style-position: inside; padding: 0;">
<li class="sample_order cursor" onclick="select_sample(this);">Top-k Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Top-a Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Top-p Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Tail-free Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Top K Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Top A Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Top P Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Tail Free Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Typical Sampling</li>
<li class="sample_order cursor" onclick="select_sample(this);">Temperature</li>
</ul>
@@ -122,25 +128,23 @@
</div>
</div>
</span>
<!---Slider Labels--->
<span class="setting_minlabel"><span style="top: -4px; position: relative;"></span></span>
<span class="setting_maxlabel"><span style="top: -4px; position: relative;"></span></span>
</div>
{% with sub_path='Sampling' %}
{% include 'settings item.html' %}
{% endwith %}
</div>
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Repetition</h4>
</div>
<span class="help_text">Change how the AI combats repetition.</span>
<div class="setting_tile_area">
{% with sub_path='Repetition' %}
{% include 'settings item.html' %}
{% endwith %}
</div>
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Other</h4>
</div>
<div class="setting_tile_area">
@@ -149,7 +153,7 @@
{% endwith %}
</div>
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Modifiers</h4>
</div>
<div class="setting_tile_area">
@@ -160,11 +164,14 @@
<!---Top Row---->
<span class="setting_label">
<span style="white-space: pre-wrap;">Soft Prompt: </span>
<span class="helpicon material-icons-outlined" title="Changes how the AI decides what to output">help_icon</span>
<span class="helpicon material-icons-outlined" title="Changes how the AI decides what to output.">help_icon</span>
</span>
<!---Bottom Row---->
<span class="setting_item">
<span class="material-icons-outlined cursor" onclick="socket.emit('load_softprompt_list', '');">folder_open</span> <span class="var_sync_system_spname"></span>
<!---<span class="material-icons-outlined cursor" onclick="socket.emit('load_softprompt_list', '');">folder_open</span> <span class="var_sync_system_spname"></span>--->
<select autocomplete="off" id="sp" class="var_sync_system_splist var_sync_system_spfilename settings_select" style="width: 140px;margin-right:0px;padding-bottom: 0px;" onclick="socket.emit('load_softprompt', this.value);">
</select>
<span class="material-icons-outlined cursor" style="font-size: 18px;" title="Refresh List" onclick="socket.emit('sp_list_refresh', '');">autorenew</span>
</span>
<!---Slider Labels--->
<span class="setting_minlabel"><span style="top: -4px; position: relative;"></span></span>
@@ -172,9 +179,10 @@
</div>
</div>
{% endwith %}
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Biasing</h4>
</div>
<span class="help_text">Influence the likelihood for the AI to output certain phrases.</span>
<div id="biasing">
<div class="bias_header">
<div class="bias_header_phrase">Phrase</div>
@@ -184,7 +192,7 @@
</div>
</div>
<div id="setting_menu_interface" class="hidden settings_category_area">
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> UI</h4>
</div>
<div class="setting_tile_area">
@@ -195,7 +203,7 @@
{% endwith %}
<div class="setting_container">
<span class="setting_label">
<span>Maximize Game Text Space: &nbsp;</span><span class="helpicon material-icons-outlined" title="When enabled and both menus are un-pinned, the game screen will take up all avaialable space. When disabled, the game screen will be centered.">help_icon</span>
<span>Max Game Screen: &nbsp;</span><span class="helpicon material-icons-outlined" title="When enabled and both menus are un-pinned, the game screen will take up all avaialable space. When disabled, the game screen will be centered.">help_icon</span>
</span>
<span class="setting_item">
<input type=checkbox id="preserve_game_space_setting" data-size=mini data-onstyle=success data-toggle=toggle onchange="preserve_game_space(this.checked)"/>
@@ -206,7 +214,7 @@
</div>
<div class="setting_container">
<span class="setting_label">
<span>Keep options on Right:&nbsp;</span><span class="helpicon material-icons-outlined" title="When enabled and only the story menu is pinned, the generated story options will be shown on the right instead of the left of the game text.">help_icon</span>
<span>Options on Right:&nbsp;</span><span class="helpicon material-icons-outlined" title="When enabled and only the story menu is pinned, the generated story options will be shown on the right instead of the left of the game text.">help_icon</span>
</span>
<span class="setting_item">
<input type=checkbox id="options_on_right" data-size=mini data-onstyle=success data-toggle=toggle onchange="options_on_right(this.checked)"/>
@@ -216,73 +224,96 @@
<span class="setting_maxlabel"><span style="top: -4px; position: relative;"></span></span>
</div>
</div>
<div onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Theme</h4>
</div>
<div class="setting_tile_area" id="Theme">
<select style="color: black;" onchange="Change_Theme(this.value);">
<option selected>Monochrome</option>
<option>Material You</option>
<option>user</option>
<option>Gruvbox Dark</option>
</select>
<!-- REMOVE THIS-->
<script>Change_Theme("Gruvbox Dark");</script>
<div onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Palette</h4>
</div>
<div class="setting_tile_area" id="Palette">
<table border=1>
<tr>
<th></th>
<th colspan=2>Main</th>
<th colspan=2>Alternative</th>
</tr>
<tr>
<th></th>
<th>Background</th>
<th>Text</th>
<th>Background</th>
<th>Text</th>
</tr>
<tr>
<td>Primary</td>
<td><input type=color id="primary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_primary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="primary_containter_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_primary_containter_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Secondary</td>
<td><input type=color id="secondary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_secondary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="secondary_containter_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_secondary_containter_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Tertiary</td>
<td><input type=color id="tertiary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_tertiary_palette" onchange="palette_color(this)"></td>
<td><input type=color id="tertiary_containter_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_tertiary_containter_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Error</td>
<td><input type=color id="error_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_error_palette" onchange="palette_color(this)"></td>
<td><input type=color id="error_containter_palette" onchange="palette_color(this)"></td>
<td><input type=color id="on_error_containter_palette" onchange="palette_color(this)"></td>
</tr>
</table>
</div>
</div>
<div onclick="toggle_setting_category(this);">
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Formatting</h4>
</div>
<div class="setting_tile_area">
{% with menu='Interface' %}
{% with sub_path='Formatting' %}
{% include 'settings item.html' %}
{% endwith %}
{% endwith %}
</div>
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Theme</h4>
</div>
<div class="setting_tile_area" id="Theme">
<select id="selected_theme" class="var_sync_system_theme_list" autocomplete="off" onchange="Change_Theme(this.value);">
</select><span class="material-icons-outlined cursor" title="Refresh List" onclick="socket.emit('theme_list_refresh', '');">autorenew</span>
<div id="palette_area">
<b style="font-size: 20px;">Palette</b>
<div id="save_theme_area" >
<input type="text" id="save_theme_name" autocomplete="off" placeholder="New Theme Name"/>
<span class="material-icons-outlined cursor" title="Save Theme" onclick='save_theme();'>save</span>
</div>
<div class="setting_tile_area" id="Palette">
<table id="Palette_Table" border=1>
<tr>
<td></td>
<td colspan=2><b>Main</b></td>
<td colspan=2><b>Alternative</b></td>
</tr>
<tr>
<td></td>
<td>Background</td>
<td>Text</td>
<td>Background</td>
<td>Text</td>
</tr>
<tr>
<td>Primary</td>
<td><input class="Theme_Input" autocomplete="off" type=color id="primary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_primary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="primary_container_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_primary_container_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Secondary</td>
<td><input class="Theme_Input" autocomplete="off" type=color id="secondary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_secondary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="secondary_container_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_secondary_container_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Tertiary</td>
<td><input class="Theme_Input" autocomplete="off" type=color id="tertiary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_tertiary_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="tertiary_container_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_tertiary_container_palette" onchange="palette_color(this)"></td>
</tr>
<tr>
<td>Error</td>
<td><input class="Theme_Input" autocomplete="off" type=color id="error_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_error_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="error_container_palette" onchange="palette_color(this)"></td>
<td><input class="Theme_Input" autocomplete="off" type=color id="on_error_container_palette" onchange="palette_color(this)"></td>
</tr>
</table>
</div>
</div>
<div class="advanced_theme cursor" onclick='document.getElementById("advanced_theme_editor").classList.remove("hidden");'>
<span>Advanced Theme</h4>
</div>
</div>
<div class="collapsable_header" onclick="toggle_setting_category(this);">
<h4 style="width:var(--flyout_menu_width);"><span class="material-icons-outlined cursor">expand_more</span> Tweaks</h4>
</div>
<div class="setting_tile_area" id="Tweaks">
<span class="help_text">Small UI changes that can be mixed and matched.</span>
<div class="tweak-container" tweak-path="hide-timing">
<span>Hide timing information</span>
<input type=checkbox class="setting_item_input" data-size="mini" data-onstyle="success" data-toggle="toggle">
</div>
<div class="tweak-container" tweak-path="hide-token-bar">
<span>Hide token bar</span>
<input type=checkbox class="setting_item_input" data-size="mini" data-onstyle="success" data-toggle="toggle">
</div>
</div>
</div>
</div>
<div id="settings_footer" class="settings_footer">
<span>Execution Time: <span id="Execution Time"></span></span> |
<span>Remaining Time: <span class="var_sync_model_tqdm_rem_time"></span></span> | <span id="var_time"></span>
</div>
</div>

View File

@@ -16,10 +16,7 @@
}
}
</script>
<div>Execution Time: <span id="Execution Time"></span></div>
<div>Remaining Time: <span class="var_sync_model_tqdm_rem_time"></span></div>
<div class="used_token_length"></div>
<hr/>
<div class="tabrow nomenu_icon">
<span class="story_menu_button selected" onclick="show_story_menu(this, 'story_menu_memory');">Memory</span>
<span class="story_menu_button" onclick="show_story_menu(this, 'story_menu_author');">Author's Note</span>
@@ -29,34 +26,49 @@
<div class="flyout_menu_contents">
<div id="story_menu_memory" class="story_category_area">
<div id="Memory">
Memory:<br/>
<textarea rows=20 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);' autocomplete="off"></textarea>
<h4 class="section_header">Memory</h4>
<span class="help_text">
Important information the AI should always keep in mind.
</span>
<textarea rows=20 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);' oninput="autoResize(this)" autocomplete="off"></textarea>
</div>
</div>
<div id="story_menu_author" class="story_category_area hidden">
<div id="author_notes">
<h4 class="section_header">Author's Note</h4>
<span class="help_text">
Heavily influences the direction and style of the AI's writing.
</span>
Template:<br/>
<input autocomplete="off" type=text class="var_sync_story_authornotetemplate fullwidth" onchange='sync_to_server(this);'><br/>
Author's Notes:<br/>
<textarea autocomplete="off" rows=5 id="authors_notes" class="var_sync_story_authornote var_sync_alt_story_authornote_length fullwidth" onchange='sync_to_server(this);'></textarea><br/>
Depth<br/>
<input type="range" min="0" max="5" step="1"
value="3" class="setting_item_input var_sync_story_andepth"
onchange='sync_to_server(this);'>
<span style='display: grid; grid-template-areas: "minlabel maxlabel"'>
<span class=setting_minlabel>0</span>
<span class=setting_maxlabel>5</span>
</span>
<textarea autocomplete="off" rows=17 id="authors_notes" class="var_sync_story_authornote var_sync_alt_story_authornote_length fullwidth" oninput="autoResize(this)" onchange='sync_to_server(this);'></textarea><br/>
<div class="setting_tile_area">
{% with menu='author_notes' %}
{% with sub_path='' %}
{% include 'settings item.html' %}
{% endwith %}
{% endwith %}
</div>
</div>
</div>
<div id="story_menu_notes" class="story_category_area hidden">
<div id="Notes">
Notes (ignored by AI):<br/>
<textarea autocomplete="off" rows=20 class="var_sync_story_notes fullwidth" onchange='sync_to_server(this);'></textarea>
<h4 class="section_header">Notes</h4>
<span class="help_text">
Notes about the story. These notes are not read by the AI!
</span>
<textarea autocomplete="off" rows=20 class="var_sync_story_notes fullwidth" onchange='sync_to_server(this);' oninput="autoResize(this)"></textarea>
</div>
</div>
<div id="story_menu_wi" class="story_category_area hidden">
<div class="setting_tile_area">
<h4 class="section_header" style="margin-left: 10px;">World Info</h4>
<span class="help_text" style="margin-left: 20px;">
Lore information, which the AI recalls by certain words.
<span class="helpicon material-icons-outlined" title="Use this instead of Memory for information on things like characters, objects, events, places, and anything else with detail.">help_icon</span>
</span>
<div class="setting_tile_area wi_settings">
{% with menu='World Info' %}
{% with sub_path='' %}
{% include 'settings item.html' %}
@@ -64,7 +76,30 @@
{% endwith %}
</div>
<div id="WI_Area">
<span id="world_info_folder_root" class="WI_Folder"><h2>root</h2></span>
<span id="world_info_folder_New Folder" class="WI_Folder">
<h2>
<span id="world_info_folder_collapse_root" class="wi_folder_collapser material-icons-outlined" folder="root">expand_more</span>
<span id="world_info_folder_expand_root" class="wi_folder_collapser material-icons-outlined hidden" folder="root">chevron_right</span>
<span class="material-icons-outlined" folder="root">folder</span>
<span class="wi_title" original_text="root" contenteditable="true">root</span>
</h2>
<span class="wi_add_button" onclick='create_new_wi_entry(this.getAttribute("folder"));'>
<span class="material-icons-outlined">post_add</span>
<span class="wi_add_text" folder="root">Add World Info Entry</span>
</span>
</span>
</div>
</div>
</div>
<div id="token-breakdown-container" style="border-top:2px;border-top-color:grey;border-top-style: solid;padding-top: 10px;">
<div class="token_breakdown">
<div id="soft_prompt_tokens" style="width:0%; background-color: var(--context_colors_soft_prompt);"></div>
<div id="memory_tokens" style="width:40%; background-color: var(--context_colors_memory);"></div>
<div id="authors_notes_tokens" style="width:10%; background-color: var(--context_colors_authors_notes);"></div>
<div id="world_info_tokens" style="width:20%; background-color: var(--context_colors_world_info);"></div>
<div id="prompt_tokens" style="width:40%; background-color: var(--context_colors_prompt);"></div>
<div id="game_text_tokens" style="width:10%; background-color: var(--context_colors_game_text);"></div>
<div id="submit_tokens" style="width:20%; background-color: var(--context_colors_submit);"></div>
<div id="unused_tokens" style="width:20%; background-color: var(--context_colors_unused);"></div>
</div>
</div>
</div>

View File

@@ -12,9 +12,30 @@
<div id="world_info_secondtags_" class="world_info_tag_area">
<div>And (if present):</div>
</div>
<div>
<div class="world_info_tag_area" id="world_info_wpp_toggle_area_">
Use W++
</div>
<div class="world_info_tag_area hidden" id="world_info_wpp_area_">
<!--this part is very sensitive to location. Javascript uses parents to find the above tag for each of the inputs, so don't add stuff without messing with JS-->
<select id="wpp_format_" class="settings_select">
<option>W++</option>
<option>Square Bracket Format (SBF)</option>
</select>
<table>
<tr>
<td>Type:</td>
<td><input type=text id="wpp_type_" onchange="do_wpp(this.parentElement.parentElement.parentElement.parentElement.parentElement)"></td>
</tr>
<tr>
<td>Name:</td>
<td><input type=text id="wpp_name_" onchange="do_wpp(this.parentElement.parentElement.parentElement.parentElement.parentElement)"></td>
</tr>
</table>
</div>
<div id="world_info_basic_text_">
Text:
<textarea id="world_info_entry_text_" class="world_info_text fullwidth"></textarea>
<textarea id="world_info_entry_text_" class="world_info_text fullwidth" oninput="autoResize(this)"></textarea>
</div>
<div id="world_info_entry_w++_" class="hidden">
<input type=text placeholder="Type"/><input type=text placeholder="Name"/>
@@ -24,7 +45,7 @@
</div>
<div>
Comment:
<textarea rows=1 id="world_info_comment_" class="world_info_text fullwidth"></textarea>
<textarea rows=1 id="world_info_comment_" class="world_info_text fullwidth" oninput="autoResize(this)"></textarea>
</div>
</div>
<div id="empty_bias">

168
themes/Darkness.css Normal file
View File

@@ -0,0 +1,168 @@
:root {
/*----------------Palette Theme--------------------*/
--primary_palette: #afc6ff;
--on_primary_palette: #002d6c;
--primary_container_palette: #004397;
--on_primary_container_palette: #d9e2ff;
--secondary_palette: #f7c5ee;
--on_secondary_palette: #5c0059;
--secondary_container_palette: #d663bd;
--on_secondary_container_palette: #4e0039;
--tertiary_palette: #a8d473;
--on_tertiary_palette: #1f3700;
--tertiary_container_palette: #2f4f00;
--on_tertiary_container_palette: #c3f18c;
--error_palette: #ffb4ab;
--on_error_palette: #690005;
--error_container_palette: #93000a;
--on_error_container_palette: #ffdad6;
--background_palette: #1b1b1f;
--on_background_palette:#e3e2e6;
--layer1_palette: #181818;
--layer2_palette: #28282D;
--layer3_palette: #2F2F35;
--layer4_palette: #35353D;
--outline_palette: #8e9099;
--middle_palette: #232328;
--on_middle_palette: #86868e;
--surface_palette: #2f2f36;
--on_surface_palette: #e3e2e6;
/*----------------Advanced Theme--------------------*/
/*General*/
--background: #1c1e1f;
--gamescreen_background: #1c1e1f;
--input_background: #151717;
--text: #e0e0e0;
--text_to_ai_color: #34c5d0;
--text_edit: #187275;
--statusbar_color: #1a625fa1;
--statusbar_text_color: #e0e0e0;
--scrollbar-color: #1a615e7a;
/*Buttons*/
--enabled_button_text: #e0e0e0;
--enabled_button_background_color: #424243;
--enabled_button_border_color: #2e2e2fe8;
--disabled_button_text: #303030;
--disabled_button_background_color: #495762;
--disabled_button_border_color: #686c68;
/*Sequence, AKA Gens Per Action*/
--sequence_area_background: #1c1e1f;
--sequence_background: #1c1e1f;
--sequence_text: #e0e0e0;
/*Side Menus*/
--tab_color: #1a625f;
--flyout_background: #181818;
--flyout_background_pinned:var(--layer1_palette);
--setting_background: #242424;
--setting_text: #e0e0e0;
--sample_order_select_color: #1d434a;
--sample_order_select_color_text: #e0e0e0;
--dropdown_text: #e0e0e0;
--dropdown_background: #181818;
--rangeslider_background_color: #1b1b1b;
--rangeslider_color: #1d434a;
--rangeslider_circle_color: #385262;
--help_icon: #c07ec5;
--tooltip_text:var(--on_secondary_palette);
--tooltip_background:var(--secondary_palette);
--setting_category_help_text_color: #E0E0E0;
--setting_footer_border_color: grey;
--setting_footer_text_color: #e0e0e0;
--setting_footer_background_color: var(--layer1_palette);
/*World Info*/
--wi_card_border_color: #002d6c00;
--wi_card_border_color_to_ai: #002d6c00;
--wi_card_bg_color: #1c1c1c;
--wi_card_text_color: #e0e0e0;
--wi_card_tag_bg_color: #242424;
--wi_card_tag_text_color: #e0e0e0;
--wi_tag_color: #1d434a;
--wi_tag_text_color: #e0e0e0;
/*Popup*/
--popup_background_color: #121414;
--popup_title_bar_color: #1a625f;
--popup_title_bar_color_text: #e0e0e0;
--popup_item_color: #1c1c1c;
--popup_item_color_text: #e0e0e0;
--popup_hover_color: #1a2e30;
--popup_hover_color_text: #e0e0e0;
--popup_selected_color: #2c5357;
--popup_selected_color_text:var(--on_secondary_container_palette_palette);
--popup_button_color: #1a625f;
--popup_button_color_text: #e0e0e0;
--popup_cancel_button_color: #1a625f;
--popup_cancel_button_color_text: #e0e0e0;
/*Context Bar Colors*/
--context_colors_memory: #3572A5;
--context_colors_authors_notes: #f1e05a;
--context_colors_world_info: #563d7c;
--context_colors_prompt: #e34c26;
--context_colors_game_text: #c6538c;
--context_colors_submit: #ededed;
--context_colors_unused: white;
--context_colors_soft_prompt: #000080;
/*Parameters*/
--scrollbar-size: 7px;
--light_shadow_value: 0;
--left_menu_strong_shadow: 0;
--right_menu_light_shadow: 0;
--right_menu_strong_shadow: 0;
--radius_inputbox: 10px;
--radius_unpinned_menu: 20px;
--radius_sequence: 10px;
--radius_settings_background: 10px;
--radius_buttons: 5px;
--radius_item_popup: 5px;
--radius_wi_card: 10px;
/*----------------VARIABLES--------------------*/
--flyout_menu_closed_width: 0px;
--setting_menu_closed_width_no_pins_width: 0px;
--story_options_size: 30%;
--story_pinned_areas_left: "menuicon options gamescreen lefticon"
"menuicon theme theme lefticon"
"menuicon inputrow inputrow lefticon";
--story_pinned_areas_right: "menuicon gamescreen options lefticon"
"menuicon theme theme lefticon"
"menuicon inputrow inputrow lefticon";
--story_pinned_area_widths_left: 30px var(--story_options_size) auto 30px;
--story_pinned_area_widths_right: 30px auto var(--story_options_size) 30px;
--story_pinned_areas: var(--story_pinned_areas_left);
--story_pinned_area_widths: var(--story_pinned_area_widths_left);
--font_size_adjustment: 0px;
--game_screen_font_size_adjustment: 1;
}

View File

@@ -2,8 +2,8 @@
/*----------------Palette Theme--------------------*/
--primary_palette: #afc6ff;
--on_primary_palette: #002d6c;
--primary_containter_palette: #004397;
--on_primary_containter_palette: #d9e2ff;
--primary_container_palette: #004397;
--on_primary_container_palette: #d9e2ff;
--secondary_palette: #f7c5ee;
--on_secondary_palette: #5c0059;
@@ -61,7 +61,7 @@
--sequence_text: var(--on_primary_palette);
/*Side Menus*/
--tab_color: var(--primary_containter_palette);
--tab_color: var(--primary_container_palette);
--flyout_background: var(--layer1_palette);
--flyout_background_pinned: var(--layer1_palette);
@@ -75,14 +75,18 @@
--dropdown_text: var(--on_secondary_palette);
--dropdown_background: var(--secondary_palette);
--rangeslider_background_color: var(--on_primary_containter_palette);
--rangeslider_color: var(--primary_containter_palette);
--rangeslider_background_color: var(--on_primary_container_palette);
--rangeslider_color: var(--primary_container_palette);
--rangeslider_circle_color: var(--on_primary_palette);
--help_icon: var(--secondary_palette);
--help_icon_text: var(--on_secondary_palette);
--tooltip_text: var(--on_secondary_palette);
--tooltip_background: var(--secondary_palette);
--setting_category_help_text_color: #E0E0E0;
--setting_footer_border_color: grey;
--setting_footer_text_color: var(--on_surface_palette);
--setting_footer_background_color: var(--layer1_palette);
/*World Info*/
--wi_card_border_color: var(--on_primary_palette);
@@ -94,9 +98,8 @@
--wi_card_tag_bg_color: var(--primary_palette);
--wi_card_tag_text_color:var(--on_primary_palette);
--wi_tag_color: var(--primary_containter_palette);
--wi_tag_text_color: var(--on_primary_containter_palette);
--wi_folder_background: var(--middle_palette);
--wi_tag_color: var(--primary_container_palette);
--wi_tag_text_color: var(--on_primary_container_palette);
/*Popup*/
--popup_background_color: var(--layer4_palette);
@@ -109,19 +112,31 @@
--popup_hover_color: var(--secondary_palette);
--popup_hover_color_text: var(--on_secondary_palette);
--popup_selected_color: var(--secondary_container_palette);
--popup_selected_color_text: var(--on_secondary_container_palette_palette);
--popup_selected_color_text: var(--on_secondary_container_palette);
--popup_button_color: var(--primary_containter_palette);
--popup_button_color_text: var(--on_primary_containter_palette);
--popup_button_color: var(--primary_container_palette);
--popup_button_color_text: var(--on_primary_container_palette);
--popup_cancel_button_color: var(--primary_palette);
--popup_cancel_button_color_text: var(--on_primary_palette);
/*Context Bar Colors*/
--context_colors_memory: #3572A5;
--context_colors_authors_notes: #f1e05a;
--context_colors_world_info: #563d7c;
--context_colors_prompt: #e34c26;
--context_colors_game_text: #c6538c;
--context_colors_submit: #ededed;
--context_colors_unused: white;
--context_colors_soft_prompt: #000080;
/*Parameters*/
--scrollbar-size: 6px;
--light_shadow_value: 0 0px 8px 0 rgba(0, 0, 0, 0.2), 0px 0px 20px 0 rgba(0, 0, 0, 0.19);
--left_menu_light_shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.2), 0px 0px 20px 0 rgba(0, 0, 0, 0.19);
--left_menu_strong_shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.2), 25px 0px 20px 0 rgba(0, 0, 0, 0.19);
--right_menu_light_shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.2), 0px 0px 20px 0 rgba(0, 0, 0, 0.19);
--right_menu_strong_shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.2), -25px 0px 20px 0 rgba(0, 0, 0, 0.19);
--popup_shadow: 0 0 35px 20px#1b1b1f;
--radius_inputbox: 10px;
--radius_unpinned_menu: 20px;
--radius_sequence: 10px;
@@ -149,4 +164,6 @@
--story_pinned_area_widths_right: 30px auto var(--story_options_size) 30px;
--story_pinned_areas: var(--story_pinned_areas_left);
--story_pinned_area_widths: var(--story_pinned_area_widths_left);
--font_size_adjustment: 0px;
--game_screen_font_size_adjustment: 1;
}

View File

@@ -1,8 +1,9 @@
:root {
/*----------------Palette Theme--------------------*/--primary_palette: #afc6ff;
/*----------------Palette Theme--------------------*/
--primary_palette: #afc6ff;
--on_primary_palette: #002d6c;
--primary_containter_palette: #004397;
--on_primary_containter_palette: #d9e2ff;
--primary_container_palette: #004397;
--on_primary_container_palette: #d9e2ff;
--secondary_palette: #f7c5ee;
--on_secondary_palette: #5c0059;
@@ -34,30 +35,30 @@
/*----------------Advanced Theme--------------------*/
/*General*/
--background: #222f39;
--background: #222f3a;
--gamescreen_background: #12181c;
--input_background: #111b22;
--input_background: #121b21;
--text: #e0e0e0;
--text_to_ai_color: #cdd9e0;
--text_edit: #759bc5;
--statusbar_color: #002d6ca1;
--statusbar_text_color: white;
--statusbar_color: #3e53679e;
--statusbar_text_color: #e0e0e0;
--scrollbar-color: #3e536780;
/*Buttons*/
--enabled_button_text: #e0e0e0;
--enabled_button_background_color: #446899;
--enabled_button_border_color: #91acd4;
--enabled_button_background_color: #2f4563;
--enabled_button_border_color: #263a54;
--disabled_button_text: #303030;
--disabled_button_background_color: #495762;
--disabled_button_border_color: #686c68;
/*Sequence, AKA Gens Per Action*/
--sequence_area_background: #161e24;
--sequence_background: #222f39;
--sequence_text: #e0e0e0;
--sequence_area_background: #121b21;
--sequence_background: #131c22;
--sequence_text: #cfd7a2;
/*Side Menus*/
--tab_color: #2b5471;
@@ -72,48 +73,61 @@
--sample_order_select_color_text: #e0e0e0;
--dropdown_text: #cfd7a2;
--dropdown_background: #151e26;
--dropdown_background: #131c22;
--rangeslider_background_color: #1f2934;
--rangeslider_color: #244c65;
--rangeslider_circle_color: #1b354d;
--help_icon: #cfd7a2;
--help_icon_text: #282c2c;
--tooltip_text:var(--on_secondary_palette);
--tooltip_background:var(--secondary_palette);
--setting_category_help_text_color: #E0E0E0;
--setting_footer_border_color: grey;
--setting_footer_text_color: #e0e0e0;
--setting_footer_background_color: var(--layer1_palette);
/*World Info*/
--wi_card_border_color: #002d6c;
--wi_card_border_color_to_ai:var(--on_secondary_palette);
--wi_card_border_color: #eeeeeead;
--wi_card_border_color_to_ai: #eeeeeead;
--wi_card_bg_color: #afc6ff;
--wi_card_text_color:var(--on_primary_palette);
--wi_card_bg_color: #273141;
--wi_card_text_color: #e0e0e0;
--wi_card_tag_bg_color: #afc6ff;
--wi_card_tag_text_color:var(--on_primary_palette);
--wi_card_tag_bg_color: #273141;
--wi_card_tag_text_color: #e0e0e0;
--wi_tag_color: #004397;
--wi_tag_text_color:var(--on_primary_containter_palette);
--wi_folder_background: #232328;
--wi_tag_color: #244c65;
--wi_tag_text_color: #e0e0e0;
/*Popup*/
--popup_background_color: #1f262e;
--popup_background_color: #141c23;
--popup_title_bar_color: #2b5471;
--popup_title_bar_color_text: #e0e0e0;
--popup_item_color: #272f38;
--popup_item_color: #252f3a;
--popup_item_color_text: #e0e0e0;
--popup_hover_color: #244c65;
--popup_hover_color: #1f4358;
--popup_hover_color_text: #e0e0e0;
--popup_selected_color: #2f677f;
--popup_selected_color: #295c72;
--popup_selected_color_text:var(--on_secondary_container_palette_palette);
--popup_button_color: #446899;
--popup_button_color: #406494;
--popup_button_color_text: #e0e0e0;
--popup_cancel_button_color: #446899;
--popup_cancel_button_color: #406494;
--popup_cancel_button_color_text: #e0e0e0;
/*Context Bar Colors*/
--context_colors_memory: #3572A5;
--context_colors_authors_notes: #f1e05a;
--context_colors_world_info: #563d7c;
--context_colors_prompt: #e34c26;
--context_colors_game_text: #c6538c;
--context_colors_submit: #ededed;
--context_colors_unused: white;
--context_colors_soft_prompt: #000080;
/*Parameters*/
--scrollbar-size: 6px;
@@ -148,4 +162,6 @@
--story_pinned_area_widths_right: 30px auto var(--story_options_size) 30px;
--story_pinned_areas: var(--story_pinned_areas_left);
--story_pinned_area_widths: var(--story_pinned_area_widths_left);
}
--font_size_adjustment: 0px;
--game_screen_font_size_adjustment: 1;
}

View File

@@ -0,0 +1,2 @@
.show_footer_icon { display: none; }
#settings_footer { display: none; }

View File

@@ -0,0 +1 @@
#token-breakdown-container { display: none; }