Merge pull request #74 from ebolam/united
Redo, Pinning, and docker enhancements
This commit is contained in:
commit
e1ef4e4fa8
257
aiserver.py
257
aiserver.py
|
@ -121,6 +121,12 @@ class vars:
|
||||||
setauthornotetemplate = authornotetemplate # Saved author's note template in settings
|
setauthornotetemplate = authornotetemplate # Saved author's note template in settings
|
||||||
andepth = 3 # How far back in history to append author's note
|
andepth = 3 # How far back in history to append author's note
|
||||||
actions = structures.KoboldStoryRegister() # Actions submitted by user and AI
|
actions = structures.KoboldStoryRegister() # Actions submitted by user and AI
|
||||||
|
actions_metadata = [] # List of dictonaries, one dictonary for every action that contains information about the action like alternative options.
|
||||||
|
# Contains at least the same number of items as actions. Back action will remove an item from actions, but not actions_metadata
|
||||||
|
# Dictonary keys are:
|
||||||
|
# Selected Text: (text the user had selected. None when this is a newly generated action)
|
||||||
|
# Alternative Generated Text: {Text, Pinned, Previous Selection, Edited}
|
||||||
|
#
|
||||||
worldinfo = [] # List of World Info key/value objects
|
worldinfo = [] # List of World Info key/value objects
|
||||||
worldinfo_i = [] # List of World Info key/value objects sans uninitialized entries
|
worldinfo_i = [] # List of World Info key/value objects sans uninitialized entries
|
||||||
worldinfo_u = {} # Dictionary of World Info UID - key/value pairs
|
worldinfo_u = {} # Dictionary of World Info UID - key/value pairs
|
||||||
|
@ -202,6 +208,8 @@ class vars:
|
||||||
nogenmod = False
|
nogenmod = False
|
||||||
welcome = False # Custom Welcome Text (False is default)
|
welcome = False # Custom Welcome Text (False is default)
|
||||||
newlinemode = "n"
|
newlinemode = "n"
|
||||||
|
quiet = False # If set will suppress any story text from being printed to the console (will only be seen on the client web page)
|
||||||
|
debug = False # If set to true, will send debug information to the client for display
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Function to get model selection at startup
|
# Function to get model selection at startup
|
||||||
|
@ -465,6 +473,8 @@ parser.add_argument("--override_rename", action='store_true', help="Renaming sto
|
||||||
parser.add_argument("--configname", help="Force a fixed configuration name to aid with config management.")
|
parser.add_argument("--configname", help="Force a fixed configuration name to aid with config management.")
|
||||||
parser.add_argument("--colab", action='store_true', help="Optimize for Google Colab.")
|
parser.add_argument("--colab", action='store_true', help="Optimize for Google Colab.")
|
||||||
parser.add_argument("--nobreakmodel", action='store_true', help="Disables Breakmodel support completely.")
|
parser.add_argument("--nobreakmodel", action='store_true', help="Disables Breakmodel support completely.")
|
||||||
|
parser.add_argument("--share", action='store_true', default=False, help="If present will launch KoboldAI available to all computers rather than local only")
|
||||||
|
parser.add_argument("--quiet", action='store_true', default=False, help="If present will suppress any story related text from showing on the console")
|
||||||
|
|
||||||
args: argparse.Namespace = None
|
args: argparse.Namespace = None
|
||||||
if(os.environ.get("KOBOLDAI_ARGS") is not None):
|
if(os.environ.get("KOBOLDAI_ARGS") is not None):
|
||||||
|
@ -475,6 +485,9 @@ else:
|
||||||
|
|
||||||
vars.model = args.model;
|
vars.model = args.model;
|
||||||
|
|
||||||
|
if args.quiet:
|
||||||
|
vars.quiet = True
|
||||||
|
|
||||||
if args.colab:
|
if args.colab:
|
||||||
args.remote = True;
|
args.remote = True;
|
||||||
args.override_rename = True;
|
args.override_rename = True;
|
||||||
|
@ -972,43 +985,50 @@ if(not vars.model in ["InferKit", "Colab", "OAI", "ReadOnly", "TPUMeshTransforme
|
||||||
lowmem = {}
|
lowmem = {}
|
||||||
|
|
||||||
# Download model from Huggingface if it does not exist, otherwise load locally
|
# Download model from Huggingface if it does not exist, otherwise load locally
|
||||||
|
|
||||||
|
#If we specify a model and it's in the root directory, we need to move it to the models directory (legacy folder structure to new)
|
||||||
|
if os.path.isdir(vars.model.replace('/', '_')):
|
||||||
|
import shutil
|
||||||
|
shutil.move(vars.model.replace('/', '_'), "models/{}".format(vars.model.replace('/', '_')))
|
||||||
if(os.path.isdir(vars.custmodpth)):
|
if(os.path.isdir(vars.custmodpth)):
|
||||||
with(maybe_use_float16()):
|
with(maybe_use_float16()):
|
||||||
try:
|
try:
|
||||||
tokenizer = AutoTokenizer.from_pretrained(vars.custmodpth, cache_dir="cache/")
|
tokenizer = AutoTokenizer.from_pretrained(vars.custmodpth, cache_dir="cache")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
tokenizer = GPT2TokenizerFast.from_pretrained(vars.custmodpth, cache_dir="cache/")
|
tokenizer = GPT2TokenizerFast.from_pretrained(vars.custmodpth, cache_dir="cache")
|
||||||
try:
|
try:
|
||||||
model = AutoModelForCausalLM.from_pretrained(vars.custmodpth, cache_dir="cache/", **lowmem)
|
model = AutoModelForCausalLM.from_pretrained(vars.custmodpth, cache_dir="cache", **lowmem)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
model = GPTNeoForCausalLM.from_pretrained(vars.custmodpth, cache_dir="cache/", **lowmem)
|
model = GPTNeoForCausalLM.from_pretrained(vars.custmodpth, cache_dir="cache", **lowmem)
|
||||||
elif(os.path.isdir(vars.model.replace('/', '_'))):
|
elif(os.path.isdir("models/{}".format(vars.model.replace('/', '_')))):
|
||||||
with(maybe_use_float16()):
|
with(maybe_use_float16()):
|
||||||
try:
|
try:
|
||||||
tokenizer = AutoTokenizer.from_pretrained(vars.model.replace('/', '_'), cache_dir="cache/")
|
tokenizer = AutoTokenizer.from_pretrained("models/{}".format(vars.model.replace('/', '_')), cache_dir="cache")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
tokenizer = GPT2TokenizerFast.from_pretrained(vars.model.replace('/', '_'), cache_dir="cache/")
|
tokenizer = GPT2TokenizerFast.from_pretrained("models/{}".format(vars.model.replace('/', '_')), cache_dir="cache")
|
||||||
try:
|
try:
|
||||||
model = AutoModelForCausalLM.from_pretrained(vars.model.replace('/', '_'), cache_dir="cache/", **lowmem)
|
model = AutoModelForCausalLM.from_pretrained("models/{}".format(vars.model.replace('/', '_')), cache_dir="cache", **lowmem)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
model = GPTNeoForCausalLM.from_pretrained(vars.model.replace('/', '_'), cache_dir="cache/", **lowmem)
|
model = GPTNeoForCausalLM.from_pretrained("models/{}".format(vars.model.replace('/', '_')), cache_dir="cache", **lowmem)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
tokenizer = AutoTokenizer.from_pretrained(vars.model, cache_dir="cache/")
|
tokenizer = AutoTokenizer.from_pretrained(vars.model, cache_dir="cache")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
tokenizer = GPT2TokenizerFast.from_pretrained(vars.model, cache_dir="cache/")
|
tokenizer = GPT2TokenizerFast.from_pretrained(vars.model, cache_dir="cache")
|
||||||
with(maybe_use_float16()):
|
with(maybe_use_float16()):
|
||||||
try:
|
try:
|
||||||
model = AutoModelForCausalLM.from_pretrained(vars.model, cache_dir="cache/", **lowmem)
|
model = AutoModelForCausalLM.from_pretrained(vars.model, cache_dir="cache", **lowmem)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
model = GPTNeoForCausalLM.from_pretrained(vars.model, cache_dir="cache/", **lowmem)
|
model = GPTNeoForCausalLM.from_pretrained(vars.model, cache_dir="cache", **lowmem)
|
||||||
|
|
||||||
if not args.colab:
|
if not args.colab:
|
||||||
model = model.half()
|
print("Trying to save model")
|
||||||
import shutil
|
import shutil
|
||||||
shutil.rmtree("cache/")
|
shutil.rmtree("cache/")
|
||||||
model.save_pretrained(vars.model.replace('/', '_'))
|
model = model.half()
|
||||||
tokenizer.save_pretrained(vars.model.replace('/', '_'))
|
model.save_pretrained("models/{}".format(vars.model.replace('/', '_')))
|
||||||
|
tokenizer.save_pretrained("models/{}".format(vars.model.replace('/', '_')))
|
||||||
|
print("Saved")
|
||||||
|
|
||||||
if(vars.hascuda):
|
if(vars.hascuda):
|
||||||
if(vars.usegpu):
|
if(vars.usegpu):
|
||||||
|
@ -1173,6 +1193,7 @@ def download():
|
||||||
js["authorsnote"] = vars.authornote
|
js["authorsnote"] = vars.authornote
|
||||||
js["anotetemplate"] = vars.authornotetemplate
|
js["anotetemplate"] = vars.authornotetemplate
|
||||||
js["actions"] = tuple(vars.actions.values())
|
js["actions"] = tuple(vars.actions.values())
|
||||||
|
js["actions_metadata"] = vars.actions_metadata
|
||||||
js["worldinfo"] = []
|
js["worldinfo"] = []
|
||||||
|
|
||||||
# Extract only the important bits of WI
|
# Extract only the important bits of WI
|
||||||
|
@ -1637,7 +1658,11 @@ def lua_set_chunk(k, v):
|
||||||
del vars._actions[chunk-1]
|
del vars._actions[chunk-1]
|
||||||
vars.lua_deleted.add(chunk)
|
vars.lua_deleted.add(chunk)
|
||||||
if(not hasattr(vars, "_actions") or vars._actions is not vars.actions):
|
if(not hasattr(vars, "_actions") or vars._actions is not vars.actions):
|
||||||
del vars.actions[chunk-1]
|
#Instead of deleting we'll blank out the text. This way our actions and actions_metadata stay in sync and we can restore the chunk on an undo
|
||||||
|
vars.actions[chunk-1] = ""
|
||||||
|
vars.actions_metadata[chunk-1]['Alternative Text'] = [{"Text": vars.actions_metadata[chunk-1]['Selected Text'], "Pinned": False, "Editted": True}] + vars.actions_metadata[chunk-1]['Alternative Text']
|
||||||
|
vars.actions_metadata[chunk-1]['Selected Text'] = ''
|
||||||
|
send_debug()
|
||||||
else:
|
else:
|
||||||
if(k == 0):
|
if(k == 0):
|
||||||
print(colors.GREEN + f"{lua_log_format_name(vars.lua_koboldbridge.logging_name)} edited prompt chunk" + colors.END)
|
print(colors.GREEN + f"{lua_log_format_name(vars.lua_koboldbridge.logging_name)} edited prompt chunk" + colors.END)
|
||||||
|
@ -1654,6 +1679,9 @@ def lua_set_chunk(k, v):
|
||||||
vars._actions[chunk-1] = v
|
vars._actions[chunk-1] = v
|
||||||
vars.lua_edited.add(chunk)
|
vars.lua_edited.add(chunk)
|
||||||
vars.actions[chunk-1] = v
|
vars.actions[chunk-1] = v
|
||||||
|
vars.actions_metadata[chunk-1]['Alternative Text'] = [{"Text": vars.actions_metadata[chunk-1]['Selected Text'], "Pinned": False, "Editted": True}] + vars.actions_metadata[chunk-1]['Alternative Text']
|
||||||
|
vars.actions_metadata[chunk-1]['Selected Text'] = v
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Get model type as "gpt-2-xl", "gpt-neo-2.7B", etc.
|
# Get model type as "gpt-2-xl", "gpt-neo-2.7B", etc.
|
||||||
|
@ -1843,6 +1871,7 @@ def do_connect():
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
@socketio.on('message')
|
@socketio.on('message')
|
||||||
def get_message(msg):
|
def get_message(msg):
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Data received:{1}{2}".format(colors.GREEN, msg, colors.END))
|
print("{0}Data received:{1}{2}".format(colors.GREEN, msg, colors.END))
|
||||||
# Submit action
|
# Submit action
|
||||||
if(msg['cmd'] == 'submit'):
|
if(msg['cmd'] == 'submit'):
|
||||||
|
@ -1882,6 +1911,9 @@ def get_message(msg):
|
||||||
# Back/Undo Action
|
# Back/Undo Action
|
||||||
elif(msg['cmd'] == 'back'):
|
elif(msg['cmd'] == 'back'):
|
||||||
actionback()
|
actionback()
|
||||||
|
# Forward/Redo Action
|
||||||
|
elif(msg['cmd'] == 'redo'):
|
||||||
|
actionredo()
|
||||||
# EditMode Action (old)
|
# EditMode Action (old)
|
||||||
elif(msg['cmd'] == 'edit'):
|
elif(msg['cmd'] == 'edit'):
|
||||||
if(vars.mode == "play"):
|
if(vars.mode == "play"):
|
||||||
|
@ -2119,6 +2151,8 @@ def get_message(msg):
|
||||||
vars.saveow = False
|
vars.saveow = False
|
||||||
elif(msg['cmd'] == 'seqsel'):
|
elif(msg['cmd'] == 'seqsel'):
|
||||||
selectsequence(msg['data'])
|
selectsequence(msg['data'])
|
||||||
|
elif(msg['cmd'] == 'seqpin'):
|
||||||
|
pinsequence(msg['data'])
|
||||||
elif(msg['cmd'] == 'setnumseq'):
|
elif(msg['cmd'] == 'setnumseq'):
|
||||||
vars.numseqs = int(msg['data'])
|
vars.numseqs = int(msg['data'])
|
||||||
emit('from_server', {'cmd': 'setlabelnumseq', 'data': msg['data']})
|
emit('from_server', {'cmd': 'setlabelnumseq', 'data': msg['data']})
|
||||||
|
@ -2165,6 +2199,11 @@ def get_message(msg):
|
||||||
refresh_settings()
|
refresh_settings()
|
||||||
elif(not vars.remote and msg['cmd'] == 'importwi'):
|
elif(not vars.remote and msg['cmd'] == 'importwi'):
|
||||||
wiimportrequest()
|
wiimportrequest()
|
||||||
|
elif(msg['cmd'] == 'debug'):
|
||||||
|
vars.debug = msg['data']
|
||||||
|
emit('from_server', {'cmd': 'set_debug', 'data': msg['data']}, broadcast=True)
|
||||||
|
if vars.debug:
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Send userscripts list to client
|
# Send userscripts list to client
|
||||||
|
@ -2493,7 +2532,25 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False,
|
||||||
vars.prompt = data
|
vars.prompt = data
|
||||||
else:
|
else:
|
||||||
vars.actions.append(data)
|
vars.actions.append(data)
|
||||||
|
# we now need to update the actions_metadata
|
||||||
|
# we'll have two conditions.
|
||||||
|
# 1. This is totally new (user entered)
|
||||||
|
if len(vars.actions_metadata) < len(vars.actions):
|
||||||
|
vars.actions_metadata.append({"Selected Text": data, "Alternative Text": []})
|
||||||
|
else:
|
||||||
|
# 2. We've selected a chunk of text that is was presented previously
|
||||||
|
try:
|
||||||
|
alternatives = [item['Text'] for item in vars.actions_metadata[len(vars.actions)-1]["Alternative Text"]]
|
||||||
|
except:
|
||||||
|
print(len(vars.actions))
|
||||||
|
print(vars.actions_metadata)
|
||||||
|
raise
|
||||||
|
if data in alternatives:
|
||||||
|
alternatives = [item for item in vars.actions_metadata[len(vars.actions)-1]["Alternative Text"] if item['Text'] != data]
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]["Alternative Text"] = alternatives
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]["Selected Text"] = data
|
||||||
update_story_chunk('last')
|
update_story_chunk('last')
|
||||||
|
send_debug()
|
||||||
|
|
||||||
if(not vars.noai and vars.lua_koboldbridge.generating):
|
if(not vars.noai and vars.lua_koboldbridge.generating):
|
||||||
# Off to the tokenizer!
|
# Off to the tokenizer!
|
||||||
|
@ -2548,6 +2605,15 @@ def actionretry(data):
|
||||||
# Remove last action if possible and resubmit
|
# Remove last action if possible and resubmit
|
||||||
if(vars.gamestarted if vars.useprompt else len(vars.actions) > 0):
|
if(vars.gamestarted if vars.useprompt else len(vars.actions) > 0):
|
||||||
if(not vars.recentback and len(vars.actions) != 0 and len(vars.genseqs) == 0): # Don't pop if we're in the "Select sequence to keep" menu or if there are no non-prompt actions
|
if(not vars.recentback and len(vars.actions) != 0 and len(vars.genseqs) == 0): # Don't pop if we're in the "Select sequence to keep" menu or if there are no non-prompt actions
|
||||||
|
# We are going to move the selected text to alternative text in the actions_metadata variable so we can redo this action
|
||||||
|
vars.actions_metadata[vars.actions]['Alternative Text'] = [{'Text': vars.actions_metadata[len(vars.actions)]['Selected Text'],
|
||||||
|
'Pinned': False,
|
||||||
|
"Previous Selection": True,
|
||||||
|
"Edited": False}] + vars.actions_metadata[vars.actions]['Alternative Text']
|
||||||
|
vars.actions_metadata[vars.actions]['Selected Text'] = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
last_key = vars.actions.get_last_key()
|
last_key = vars.actions.get_last_key()
|
||||||
vars.actions.pop()
|
vars.actions.pop()
|
||||||
remove_story_chunk(last_key + 1)
|
remove_story_chunk(last_key + 1)
|
||||||
|
@ -2555,6 +2621,7 @@ def actionretry(data):
|
||||||
vars.recentedit = False
|
vars.recentedit = False
|
||||||
vars.lua_koboldbridge.feedback = None
|
vars.lua_koboldbridge.feedback = None
|
||||||
actionsubmit("", actionmode=vars.actionmode, force_submit=True)
|
actionsubmit("", actionmode=vars.actionmode, force_submit=True)
|
||||||
|
send_debug()
|
||||||
elif(not vars.useprompt):
|
elif(not vars.useprompt):
|
||||||
emit('from_server', {'cmd': 'errmsg', 'data': "Please enable \"Always Add Prompt\" to retry with your prompt."})
|
emit('from_server', {'cmd': 'errmsg', 'data': "Please enable \"Always Add Prompt\" to retry with your prompt."})
|
||||||
|
|
||||||
|
@ -2566,6 +2633,13 @@ def actionback():
|
||||||
return
|
return
|
||||||
# Remove last index of actions and refresh game screen
|
# Remove last index of actions and refresh game screen
|
||||||
if(len(vars.genseqs) == 0 and len(vars.actions) > 0):
|
if(len(vars.genseqs) == 0 and len(vars.actions) > 0):
|
||||||
|
# We are going to move the selected text to alternative text in the actions_metadata variable so we can redo this action
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]['Alternative Text'] = [{'Text': vars.actions_metadata[len(vars.actions)-1]['Selected Text'],
|
||||||
|
'Pinned': False,
|
||||||
|
"Previous Selection": True,
|
||||||
|
"Edited": False}] + vars.actions_metadata[len(vars.actions)-1]['Alternative Text']
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]['Selected Text'] = ""
|
||||||
|
|
||||||
last_key = vars.actions.get_last_key()
|
last_key = vars.actions.get_last_key()
|
||||||
vars.actions.pop()
|
vars.actions.pop()
|
||||||
vars.recentback = True
|
vars.recentback = True
|
||||||
|
@ -2574,6 +2648,28 @@ def actionback():
|
||||||
emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."})
|
emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."})
|
||||||
else:
|
else:
|
||||||
vars.genseqs = []
|
vars.genseqs = []
|
||||||
|
send_debug()
|
||||||
|
|
||||||
|
def actionredo():
|
||||||
|
i = 0
|
||||||
|
if len(vars.actions) < len(vars.actions_metadata):
|
||||||
|
genout = [{"generated_text": item['Text']} for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Previous Selection"]==True)]
|
||||||
|
genout = genout + [{"generated_text": item['Text']} for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Pinned"]==True) and (item["Previous Selection"]==False)]
|
||||||
|
|
||||||
|
if len(genout) == 1:
|
||||||
|
vars.actions_metadata[len(vars.actions)]['Alternative Text'] = [item for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Previous Selection"]!=True)]
|
||||||
|
genresult(genout[0]['generated_text'], flash=True)
|
||||||
|
else:
|
||||||
|
# Store sequences in memory until selection is made
|
||||||
|
vars.genseqs = genout
|
||||||
|
|
||||||
|
|
||||||
|
# Send sequences to UI for selection
|
||||||
|
genout = [[item['Text'], "redo"] for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Previous Selection"]==True)]
|
||||||
|
emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True)
|
||||||
|
else:
|
||||||
|
emit('from_server', {'cmd': 'popuperror', 'data': "There's nothing to undo"}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
#
|
#
|
||||||
|
@ -2889,6 +2985,7 @@ def generate(txt, minimum, maximum, found_entries=None):
|
||||||
found_entries = set()
|
found_entries = set()
|
||||||
found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs))
|
found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs))
|
||||||
|
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, tokenizer.decode(txt), colors.END))
|
print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, tokenizer.decode(txt), colors.END))
|
||||||
|
|
||||||
# Store context in memory to use it for comparison with generated content
|
# Store context in memory to use it for comparison with generated content
|
||||||
|
@ -2951,6 +3048,7 @@ def generate(txt, minimum, maximum, found_entries=None):
|
||||||
# Deal with a single return sequence from generate()
|
# Deal with a single return sequence from generate()
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def genresult(genout, flash=True):
|
def genresult(genout, flash=True):
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
||||||
|
|
||||||
# Format output before continuing
|
# Format output before continuing
|
||||||
|
@ -2966,9 +3064,14 @@ def genresult(genout, flash=True):
|
||||||
vars.prompt = genout
|
vars.prompt = genout
|
||||||
else:
|
else:
|
||||||
vars.actions.append(genout)
|
vars.actions.append(genout)
|
||||||
|
if len(vars.actions) > len(vars.actions_metadata):
|
||||||
|
vars.actions_metadata.append({'Selected Text': genout, 'Alternative Text': []})
|
||||||
|
else:
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]['Selected Text'] = genout
|
||||||
update_story_chunk('last')
|
update_story_chunk('last')
|
||||||
if(flash):
|
if(flash):
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Send generator sequences to the UI for selection
|
# Send generator sequences to the UI for selection
|
||||||
|
@ -2978,14 +3081,34 @@ def genselect(genout):
|
||||||
for result in genout:
|
for result in genout:
|
||||||
# Apply output formatting rules to sequences
|
# Apply output formatting rules to sequences
|
||||||
result["generated_text"] = applyoutputformatting(result["generated_text"])
|
result["generated_text"] = applyoutputformatting(result["generated_text"])
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}[Result {1}]\n{2}{3}".format(colors.CYAN, i, result["generated_text"], colors.END))
|
print("{0}[Result {1}]\n{2}{3}".format(colors.CYAN, i, result["generated_text"], colors.END))
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
# Add the options to the actions metadata
|
||||||
|
# If we've already generated text for this action but haven't selected one we'll want to kill all non-pinned, non-previous selection, and non-edited options then add the new ones
|
||||||
|
if (len(vars.actions_metadata) > len(vars.actions)):
|
||||||
|
if (vars.actions_metadata[len(vars.actions)]['Selected Text'] == ""):
|
||||||
|
vars.actions_metadata[len(vars.actions)]['Alternative Text'] = [{"Text": item['Text'], "Pinned": item['Pinned'],
|
||||||
|
"Previous Selection": item["Previous Selection"],
|
||||||
|
"Edited": item["Edited"]} for item in vars.actions_metadata[len(vars.actions)]['Alternative Text']
|
||||||
|
if item['Pinned'] or item["Previous Selection"] or item["Edited"]] + [{"Text": text["generated_text"],
|
||||||
|
"Pinned": False, "Previous Selection": False, "Edited": False} for text in genout]
|
||||||
|
else:
|
||||||
|
vars.actions_metadata.append({'Selected Text': '', 'Alternative Text': [{"Text": text["generated_text"], "Pinned": False, "Previous Selection": False, "Edited": False} for text in genout]})
|
||||||
|
else:
|
||||||
|
vars.actions_metadata.append({'Selected Text': '', 'Alternative Text': [{"Text": text["generated_text"], "Pinned": False, "Previous Selection": False, "Edited": False} for text in genout]})
|
||||||
|
|
||||||
|
genout = [{"generated_text": item['Text']} for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Previous Selection"]==False) and (item["Edited"]==False)]
|
||||||
|
|
||||||
# Store sequences in memory until selection is made
|
# Store sequences in memory until selection is made
|
||||||
vars.genseqs = genout
|
vars.genseqs = genout
|
||||||
|
|
||||||
|
genout = [[item['Text'], "pinned" if item['Pinned'] else "normal"] for item in vars.actions_metadata[len(vars.actions)]['Alternative Text'] if (item["Previous Selection"]==False) and (item["Edited"]==False)]
|
||||||
|
|
||||||
# Send sequences to UI for selection
|
# Send sequences to UI for selection
|
||||||
emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True)
|
emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Send selected sequence to action log and refresh UI
|
# Send selected sequence to action log and refresh UI
|
||||||
|
@ -2996,6 +3119,9 @@ def selectsequence(n):
|
||||||
vars.lua_koboldbridge.feedback = vars.genseqs[int(n)]["generated_text"]
|
vars.lua_koboldbridge.feedback = vars.genseqs[int(n)]["generated_text"]
|
||||||
if(len(vars.lua_koboldbridge.feedback) != 0):
|
if(len(vars.lua_koboldbridge.feedback) != 0):
|
||||||
vars.actions.append(vars.lua_koboldbridge.feedback)
|
vars.actions.append(vars.lua_koboldbridge.feedback)
|
||||||
|
#We'll want to remove the option from the alternative text and put it in selected text
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]['Alternative Text'] = [item for item in vars.actions_metadata[len(vars.actions)-1]['Alternative Text'] if item['Text'] != vars.lua_koboldbridge.feedback]
|
||||||
|
vars.actions_metadata[len(vars.actions)-1]['Selected Text'] = vars.lua_koboldbridge.feedback
|
||||||
update_story_chunk('last')
|
update_story_chunk('last')
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
||||||
emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True)
|
emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True)
|
||||||
|
@ -3003,12 +3129,30 @@ def selectsequence(n):
|
||||||
|
|
||||||
if(vars.lua_koboldbridge.restart_sequence is not None):
|
if(vars.lua_koboldbridge.restart_sequence is not None):
|
||||||
actionsubmit("", actionmode=vars.actionmode, force_submit=True, disable_recentrng=True)
|
actionsubmit("", actionmode=vars.actionmode, force_submit=True, disable_recentrng=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
|
#==================================================================#
|
||||||
|
# Pin/Unpin the selected sequence
|
||||||
|
#==================================================================#
|
||||||
|
def pinsequence(n):
|
||||||
|
if n.isnumeric():
|
||||||
|
text = vars.genseqs[int(n)]['generated_text']
|
||||||
|
if text in [item['Text'] for item in vars.actions_metadata[len(vars.actions)]['Alternative Text']]:
|
||||||
|
alternatives = vars.actions_metadata[len(vars.actions)]['Alternative Text']
|
||||||
|
for i in range(len(alternatives)):
|
||||||
|
if alternatives[i]['Text'] == text:
|
||||||
|
alternatives[i]['Pinned'] = not alternatives[i]['Pinned']
|
||||||
|
break
|
||||||
|
vars.actions_metadata[len(vars.actions)]['Alternative Text'] = alternatives
|
||||||
|
send_debug()
|
||||||
|
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Send transformers-style request to ngrok/colab host
|
# Send transformers-style request to ngrok/colab host
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def sendtocolab(txt, min, max):
|
def sendtocolab(txt, min, max):
|
||||||
# Log request to console
|
# Log request to console
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Tokens:{1}, Txt:{2}{3}".format(colors.YELLOW, min-1, txt, colors.END))
|
print("{0}Tokens:{1}, Txt:{2}{3}".format(colors.YELLOW, min-1, txt, colors.END))
|
||||||
|
|
||||||
# Store context in memory to use it for comparison with generated content
|
# Store context in memory to use it for comparison with generated content
|
||||||
|
@ -3094,6 +3238,7 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None):
|
||||||
found_entries = set()
|
found_entries = set()
|
||||||
found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs))
|
found_entries = tuple(found_entries.copy() for _ in range(vars.numseqs))
|
||||||
|
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, tokenizer.decode(txt), colors.END))
|
print("{0}Min:{1}, Max:{2}, Txt:{3}{4}".format(colors.YELLOW, minimum, maximum, tokenizer.decode(txt), colors.END))
|
||||||
|
|
||||||
vars._actions = vars.actions
|
vars._actions = vars.actions
|
||||||
|
@ -3411,12 +3556,17 @@ def editsubmit(data):
|
||||||
if(vars.editln == 0):
|
if(vars.editln == 0):
|
||||||
vars.prompt = data
|
vars.prompt = data
|
||||||
else:
|
else:
|
||||||
|
vars.actions_metadata[vars.editln-1]['Alternative Text'] = vars.actions_metadata[vars.editln-1]['Alternative Text'] + [{"Text": vars.actions[vars.editln-1], "Pinned": False,
|
||||||
|
"Previous Selection": False,
|
||||||
|
"Edited": True}]
|
||||||
|
vars.actions_metadata[vars.editln-1]['Selected Text'] = data
|
||||||
vars.actions[vars.editln-1] = data
|
vars.actions[vars.editln-1] = data
|
||||||
|
|
||||||
vars.mode = "play"
|
vars.mode = "play"
|
||||||
update_story_chunk(vars.editln)
|
update_story_chunk(vars.editln)
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': vars.editln}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': vars.editln}, broadcast=True)
|
||||||
emit('from_server', {'cmd': 'editmode', 'data': 'false'})
|
emit('from_server', {'cmd': 'editmode', 'data': 'false'})
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
#
|
#
|
||||||
|
@ -3428,10 +3578,14 @@ def deleterequest():
|
||||||
# Send error message
|
# Send error message
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
del vars.actions[vars.editln-1]
|
vars.actions_metadata[vars.editln-1]['Alternative Text'] = [{"Text": vars.actions[vars.editln-1], "Pinned": False,
|
||||||
|
"Previous Selection": True, "Edited": False}] + vars.actions_metadata[vars.editln-1]['Alternative Text']
|
||||||
|
vars.actions_metadata[vars.editln-1]['Selected Text'] = ''
|
||||||
|
vars.actions[vars.editln-1] = ''
|
||||||
vars.mode = "play"
|
vars.mode = "play"
|
||||||
remove_story_chunk(vars.editln)
|
remove_story_chunk(vars.editln)
|
||||||
emit('from_server', {'cmd': 'editmode', 'data': 'false'})
|
emit('from_server', {'cmd': 'editmode', 'data': 'false'})
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
#
|
#
|
||||||
|
@ -3445,6 +3599,10 @@ def inlineedit(chunk, data):
|
||||||
vars.prompt = data
|
vars.prompt = data
|
||||||
else:
|
else:
|
||||||
if(chunk-1 in vars.actions):
|
if(chunk-1 in vars.actions):
|
||||||
|
vars.actions_metadata[chunk-1]['Alternative Text'] = vars.actions_metadata[chunk-1]['Alternative Text'] + [{"Text": vars.actions[chunk-1], "Pinned": False,
|
||||||
|
"Previous Selection": False,
|
||||||
|
"Edited": True}]
|
||||||
|
vars.actions_metadata[chunk-1]['Selected Text'] = data
|
||||||
vars.actions[chunk-1] = data
|
vars.actions[chunk-1] = data
|
||||||
else:
|
else:
|
||||||
print(f"WARNING: Attempted to edit non-existent chunk {chunk}")
|
print(f"WARNING: Attempted to edit non-existent chunk {chunk}")
|
||||||
|
@ -3453,6 +3611,7 @@ def inlineedit(chunk, data):
|
||||||
update_story_chunk(chunk)
|
update_story_chunk(chunk)
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': chunk}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': chunk}, broadcast=True)
|
||||||
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
#
|
#
|
||||||
|
@ -3468,12 +3627,17 @@ def inlinedelete(chunk):
|
||||||
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
||||||
else:
|
else:
|
||||||
if(chunk-1 in vars.actions):
|
if(chunk-1 in vars.actions):
|
||||||
del vars.actions[chunk-1]
|
vars.actions_metadata[chunk-1]['Alternative Text'] = [{"Text": vars.actions[chunk-1], "Pinned": False,
|
||||||
|
"Previous Selection": True,
|
||||||
|
"Edited": False}] + vars.actions_metadata[chunk-1]['Alternative Text']
|
||||||
|
vars.actions_metadata[chunk-1]['Selected Text'] = ''
|
||||||
|
vars.actions[chunk-1] = ''
|
||||||
else:
|
else:
|
||||||
print(f"WARNING: Attempted to delete non-existent chunk {chunk}")
|
print(f"WARNING: Attempted to delete non-existent chunk {chunk}")
|
||||||
setgamesaved(False)
|
setgamesaved(False)
|
||||||
remove_story_chunk(chunk)
|
remove_story_chunk(chunk)
|
||||||
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Toggles the game mode for memory editing and sends UI commands
|
# Toggles the game mode for memory editing and sends UI commands
|
||||||
|
@ -3822,6 +3986,7 @@ def anotesubmit(data, template=""):
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def ikrequest(txt):
|
def ikrequest(txt):
|
||||||
# Log request to console
|
# Log request to console
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Len:{1}, Txt:{2}{3}".format(colors.YELLOW, len(txt), txt, colors.END))
|
print("{0}Len:{1}, Txt:{2}{3}".format(colors.YELLOW, len(txt), txt, colors.END))
|
||||||
|
|
||||||
# Build request JSON data
|
# Build request JSON data
|
||||||
|
@ -3859,11 +4024,21 @@ def ikrequest(txt):
|
||||||
genout = vars.lua_koboldbridge.outputs[1]
|
genout = vars.lua_koboldbridge.outputs[1]
|
||||||
assert genout is str
|
assert genout is str
|
||||||
|
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
||||||
vars.actions.append(genout)
|
vars.actions.append(genout)
|
||||||
|
if len(vars.actions_metadata) < len(vars.actions):
|
||||||
|
vars.actions_metadata.append({"Selected Text": genout, "Alternative Text": []})
|
||||||
|
else:
|
||||||
|
# 2. We've selected a chunk of text that is was presented previously
|
||||||
|
alternatives = [item['Text'] for item in vars.actions_metadata[len(vars.actions)]["Alternative Text"]]
|
||||||
|
if genout in alternatives:
|
||||||
|
alternatives = [item for item in vars.actions_metadata[len(vars.actions)]["Alternative Text"] if item['Text'] != genout]
|
||||||
|
vars.actions_metadata[len(vars.actions)]["Alternative Text"] = alternatives
|
||||||
|
vars.actions_metadata[len(vars.actions)]["Selected Text"] = genout
|
||||||
update_story_chunk('last')
|
update_story_chunk('last')
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
set_aibusy(0)
|
set_aibusy(0)
|
||||||
else:
|
else:
|
||||||
# Send error message to web client
|
# Send error message to web client
|
||||||
|
@ -3882,6 +4057,7 @@ def ikrequest(txt):
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def oairequest(txt, min, max):
|
def oairequest(txt, min, max):
|
||||||
# Log request to console
|
# Log request to console
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}Len:{1}, Txt:{2}{3}".format(colors.YELLOW, len(txt), txt, colors.END))
|
print("{0}Len:{1}, Txt:{2}{3}".format(colors.YELLOW, len(txt), txt, colors.END))
|
||||||
|
|
||||||
# Store context in memory to use it for comparison with generated content
|
# Store context in memory to use it for comparison with generated content
|
||||||
|
@ -3918,11 +4094,21 @@ def oairequest(txt, min, max):
|
||||||
genout = vars.lua_koboldbridge.outputs[1]
|
genout = vars.lua_koboldbridge.outputs[1]
|
||||||
assert genout is str
|
assert genout is str
|
||||||
|
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
print("{0}{1}{2}".format(colors.CYAN, genout, colors.END))
|
||||||
vars.actions.append(genout)
|
vars.actions.append(genout)
|
||||||
|
if len(vars.actions_metadata) < len(vars.actions):
|
||||||
|
vars.actions_metadata.append({"Selected Text": genout, "Alternative Text": []})
|
||||||
|
else:
|
||||||
|
# 2. We've selected a chunk of text that is was presented previously
|
||||||
|
alternatives = [item['Text'] for item in vars.actions_metadata[len(vars.actions)]["Alternative Text"]]
|
||||||
|
if genout in alternatives:
|
||||||
|
alternatives = [item for item in vars.actions_metadata[len(vars.actions)]["Alternative Text"] if item['Text'] != genout]
|
||||||
|
vars.actions_metadata[len(vars.actions)]["Alternative Text"] = alternatives
|
||||||
|
vars.actions_metadata[len(vars.actions)]["Selected Text"] = genout
|
||||||
update_story_chunk('last')
|
update_story_chunk('last')
|
||||||
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
emit('from_server', {'cmd': 'texteffect', 'data': vars.actions.get_last_key() + 1 if len(vars.actions) else 0}, broadcast=True)
|
||||||
|
send_debug()
|
||||||
set_aibusy(0)
|
set_aibusy(0)
|
||||||
else:
|
else:
|
||||||
# Send error message to web client
|
# Send error message to web client
|
||||||
|
@ -3950,12 +4136,15 @@ def exitModes():
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Launch in-browser save prompt
|
# Launch in-browser save prompt
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def saveas(name):
|
def saveas(data):
|
||||||
|
|
||||||
|
name = data['name']
|
||||||
|
savepins = data['pins']
|
||||||
# Check if filename exists already
|
# Check if filename exists already
|
||||||
name = utils.cleanfilename(name)
|
name = utils.cleanfilename(name)
|
||||||
if(not fileops.saveexists(name) or (vars.saveow and vars.svowname == name)):
|
if(not fileops.saveexists(name) or (vars.saveow and vars.svowname == name)):
|
||||||
# All clear to save
|
# All clear to save
|
||||||
e = saveRequest(fileops.storypath(name))
|
e = saveRequest(fileops.storypath(name), savepins=savepins)
|
||||||
vars.saveow = False
|
vars.saveow = False
|
||||||
vars.svowname = ""
|
vars.svowname = ""
|
||||||
if(e is None):
|
if(e is None):
|
||||||
|
@ -4031,7 +4220,7 @@ def savetofile():
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Save the story to specified path
|
# Save the story to specified path
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
def saveRequest(savpath):
|
def saveRequest(savpath, savepins=True):
|
||||||
if(savpath):
|
if(savpath):
|
||||||
# Leave Edit/Memory mode before continuing
|
# Leave Edit/Memory mode before continuing
|
||||||
exitModes()
|
exitModes()
|
||||||
|
@ -4047,6 +4236,8 @@ def saveRequest(savpath):
|
||||||
js["authorsnote"] = vars.authornote
|
js["authorsnote"] = vars.authornote
|
||||||
js["anotetemplate"] = vars.authornotetemplate
|
js["anotetemplate"] = vars.authornotetemplate
|
||||||
js["actions"] = tuple(vars.actions.values())
|
js["actions"] = tuple(vars.actions.values())
|
||||||
|
if savepins:
|
||||||
|
js["actions_metadata"] = vars.actions_metadata
|
||||||
js["worldinfo"] = []
|
js["worldinfo"] = []
|
||||||
js["wifolders_d"] = vars.wifolders_d
|
js["wifolders_d"] = vars.wifolders_d
|
||||||
js["wifolders_l"] = vars.wifolders_l
|
js["wifolders_l"] = vars.wifolders_l
|
||||||
|
@ -4172,6 +4363,12 @@ def loadRequest(loadpath, filename=None):
|
||||||
vars.actions = structures.KoboldStoryRegister()
|
vars.actions = structures.KoboldStoryRegister()
|
||||||
actions = collections.deque(js["actions"])
|
actions = collections.deque(js["actions"])
|
||||||
|
|
||||||
|
if "actions_metadata" in js:
|
||||||
|
vars.actions_metadata = js["actions_metadata"]
|
||||||
|
else:
|
||||||
|
vars.actions_metadata = [{'Selected Text': text, 'Alternative Text': []} for text in js["actions"]]
|
||||||
|
|
||||||
|
|
||||||
if(len(vars.prompt.strip()) == 0):
|
if(len(vars.prompt.strip()) == 0):
|
||||||
while(len(actions)):
|
while(len(actions)):
|
||||||
action = actions.popleft()
|
action = actions.popleft()
|
||||||
|
@ -4588,6 +4785,7 @@ def wiimportrequest():
|
||||||
if(vars.worldinfo[-1]["folder"] is not None):
|
if(vars.worldinfo[-1]["folder"] is not None):
|
||||||
vars.wifolders_u[vars.worldinfo[-1]["folder"]].append(vars.worldinfo[-1])
|
vars.wifolders_u[vars.worldinfo[-1]["folder"]].append(vars.worldinfo[-1])
|
||||||
|
|
||||||
|
if not vars.quiet:
|
||||||
print("{0}".format(vars.worldinfo[0]))
|
print("{0}".format(vars.worldinfo[0]))
|
||||||
|
|
||||||
# Refresh game screen
|
# Refresh game screen
|
||||||
|
@ -4606,6 +4804,7 @@ def newGameRequest():
|
||||||
vars.prompt = ""
|
vars.prompt = ""
|
||||||
vars.memory = ""
|
vars.memory = ""
|
||||||
vars.actions = structures.KoboldStoryRegister()
|
vars.actions = structures.KoboldStoryRegister()
|
||||||
|
vars.actions_metadata = []
|
||||||
|
|
||||||
vars.authornote = ""
|
vars.authornote = ""
|
||||||
vars.authornotetemplate = vars.setauthornotetemplate
|
vars.authornotetemplate = vars.setauthornotetemplate
|
||||||
|
@ -4689,6 +4888,13 @@ if(vars.model in ("TPUMeshTransformerGPTJ",)):
|
||||||
},
|
},
|
||||||
).start()
|
).start()
|
||||||
|
|
||||||
|
def send_debug():
|
||||||
|
if vars.debug:
|
||||||
|
debug_info = ""
|
||||||
|
for variable in [["Action Length", len(vars.actions)], ["Actions Metadata Length", len(vars.actions_metadata)], ["Actions Metadata", vars.actions_metadata]]:
|
||||||
|
debug_info = "{}{}: {}\n".format(debug_info, variable[0], variable[1])
|
||||||
|
emit('from_server', {'cmd': 'debug_info', 'data': debug_info}, broadcast=True)
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Final startup commands to launch Flask app
|
# Final startup commands to launch Flask app
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
|
@ -4716,6 +4922,9 @@ if __name__ == "__main__":
|
||||||
webbrowser.open_new('http://localhost:5000')
|
webbrowser.open_new('http://localhost:5000')
|
||||||
print("{0}Server started!\nYou may now connect with a browser at http://127.0.0.1:5000/{1}".format(colors.GREEN, colors.END))
|
print("{0}Server started!\nYou may now connect with a browser at http://127.0.0.1:5000/{1}".format(colors.GREEN, colors.END))
|
||||||
vars.serverstarted = True
|
vars.serverstarted = True
|
||||||
|
if args.share:
|
||||||
|
socketio.run(app, port=5000, host='0.0.0.0')
|
||||||
|
else:
|
||||||
socketio.run(app, port=5000)
|
socketio.run(app, port=5000)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
name: koboldai
|
||||||
|
channels:
|
||||||
|
- pytorch
|
||||||
|
- conda-forge
|
||||||
|
- defaults
|
||||||
|
dependencies:
|
||||||
|
- colorama
|
||||||
|
- flask-socketio
|
||||||
|
- pytorch
|
||||||
|
- python=3.8.*
|
||||||
|
- cudatoolkit=11.1
|
||||||
|
- eventlet
|
||||||
|
- markdown
|
||||||
|
- bleach
|
||||||
|
- pip
|
||||||
|
- git
|
||||||
|
- pip:
|
||||||
|
- flask-cloudflared
|
||||||
|
- flask-ngrok
|
||||||
|
- lupa==1.10
|
|
@ -207,6 +207,17 @@ gensettingstf = [
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"tooltip": "Disables userscript generation modifiers."
|
"tooltip": "Disables userscript generation modifiers."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uitype": "toggle",
|
||||||
|
"unit": "bool",
|
||||||
|
"label": "Debug",
|
||||||
|
"id": "debug",
|
||||||
|
"min": 0,
|
||||||
|
"max": 1,
|
||||||
|
"step": 1,
|
||||||
|
"default": 0,
|
||||||
|
"tooltip": "Show debug info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -341,6 +352,17 @@ gensettingsik =[{
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"tooltip": "When enabled, the Memory text box in the Random Story dialog will be prefilled by default with your current story's memory instead of being empty."
|
"tooltip": "When enabled, the Memory text box in the Random Story dialog will be prefilled by default with your current story's memory instead of being empty."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uitype": "toggle",
|
||||||
|
"unit": "bool",
|
||||||
|
"label": "Debug",
|
||||||
|
"id": "debug",
|
||||||
|
"min": 0,
|
||||||
|
"max": 1,
|
||||||
|
"step": 1,
|
||||||
|
"default": 0,
|
||||||
|
"tooltip": "Show debug info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ var button_mode_label;
|
||||||
var button_send;
|
var button_send;
|
||||||
var button_actmem;
|
var button_actmem;
|
||||||
var button_actback;
|
var button_actback;
|
||||||
|
var button_actfwd;
|
||||||
var button_actretry;
|
var button_actretry;
|
||||||
var button_actwi;
|
var button_actwi;
|
||||||
var game_text;
|
var game_text;
|
||||||
|
@ -38,6 +39,7 @@ var anote_menu;
|
||||||
var anote_input;
|
var anote_input;
|
||||||
var anote_labelcur;
|
var anote_labelcur;
|
||||||
var anote_slider;
|
var anote_slider;
|
||||||
|
var debug_area;
|
||||||
var popup;
|
var popup;
|
||||||
var popup_title;
|
var popup_title;
|
||||||
var popup_content;
|
var popup_content;
|
||||||
|
@ -49,6 +51,7 @@ var aidg_accept;
|
||||||
var aidg_close;
|
var aidg_close;
|
||||||
var saveaspopup;
|
var saveaspopup;
|
||||||
var saveasinput;
|
var saveasinput;
|
||||||
|
var savepins;
|
||||||
var topic;
|
var topic;
|
||||||
var saveas_accept;
|
var saveas_accept;
|
||||||
var saveas_close;
|
var saveas_close;
|
||||||
|
@ -748,7 +751,7 @@ function enterMemoryMode() {
|
||||||
setchatnamevisibility(false);
|
setchatnamevisibility(false);
|
||||||
showMessage("Edit the memory to be sent with each request to the AI.");
|
showMessage("Edit the memory to be sent with each request to the AI.");
|
||||||
button_actmem.html("Cancel");
|
button_actmem.html("Cancel");
|
||||||
hide([button_actback, button_actretry, button_actwi]);
|
hide([button_actback, button_actfwd, button_actretry, button_actwi]);
|
||||||
// Display Author's Note field
|
// Display Author's Note field
|
||||||
anote_menu.slideDown("fast");
|
anote_menu.slideDown("fast");
|
||||||
}
|
}
|
||||||
|
@ -759,7 +762,7 @@ function exitMemoryMode() {
|
||||||
setchatnamevisibility(chatmode);
|
setchatnamevisibility(chatmode);
|
||||||
hideMessage();
|
hideMessage();
|
||||||
button_actmem.html("Memory");
|
button_actmem.html("Memory");
|
||||||
show([button_actback, button_actretry, button_actwi]);
|
show([button_actback, button_actfwd, button_actretry, button_actwi]);
|
||||||
input_text.val("");
|
input_text.val("");
|
||||||
// Hide Author's Note field
|
// Hide Author's Note field
|
||||||
anote_menu.slideUp("fast");
|
anote_menu.slideUp("fast");
|
||||||
|
@ -768,7 +771,7 @@ function exitMemoryMode() {
|
||||||
function enterWiMode() {
|
function enterWiMode() {
|
||||||
showMessage("World Info will be added to memory only when the key appears in submitted text or the last action.");
|
showMessage("World Info will be added to memory only when the key appears in submitted text or the last action.");
|
||||||
button_actwi.html("Accept");
|
button_actwi.html("Accept");
|
||||||
hide([button_actback, button_actmem, button_actretry, game_text]);
|
hide([button_actback, button_actfwd, button_actmem, button_actretry, game_text]);
|
||||||
setchatnamevisibility(false);
|
setchatnamevisibility(false);
|
||||||
show([wi_menu]);
|
show([wi_menu]);
|
||||||
disableSendBtn();
|
disableSendBtn();
|
||||||
|
@ -780,7 +783,7 @@ function exitWiMode() {
|
||||||
button_actwi.html("W Info");
|
button_actwi.html("W Info");
|
||||||
hide([wi_menu]);
|
hide([wi_menu]);
|
||||||
setchatnamevisibility(chatmode);
|
setchatnamevisibility(chatmode);
|
||||||
show([button_actback, button_actmem, button_actretry, game_text]);
|
show([button_actback, button_actfwd, button_actmem, button_actretry, game_text]);
|
||||||
enableSendBtn();
|
enableSendBtn();
|
||||||
$("#gamescreen").removeClass("wigamescreen");
|
$("#gamescreen").removeClass("wigamescreen");
|
||||||
}
|
}
|
||||||
|
@ -884,7 +887,7 @@ function hideSaveAsPopup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendSaveAsRequest() {
|
function sendSaveAsRequest() {
|
||||||
socket.send({'cmd': 'saveasrequest', 'data': saveasinput.val()});
|
socket.send({'cmd': 'saveasrequest', 'data': {"name": saveasinput.val(), "pins": savepins.val()}});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLoadPopup() {
|
function showLoadPopup() {
|
||||||
|
@ -1142,9 +1145,9 @@ function updateSPStatItems(items) {
|
||||||
function setStartState() {
|
function setStartState() {
|
||||||
enableSendBtn();
|
enableSendBtn();
|
||||||
enableButtons([button_actmem, button_actwi]);
|
enableButtons([button_actmem, button_actwi]);
|
||||||
disableButtons([button_actback, button_actretry]);
|
disableButtons([button_actback, button_actfwd, button_actretry]);
|
||||||
hide([wi_menu]);
|
hide([wi_menu]);
|
||||||
show([game_text, button_actmem, button_actwi, button_actback, button_actretry]);
|
show([game_text, button_actmem, button_actwi, button_actback, button_actfwd, button_actretry]);
|
||||||
hideMessage();
|
hideMessage();
|
||||||
hideWaitAnimation();
|
hideWaitAnimation();
|
||||||
button_actmem.html("Memory");
|
button_actmem.html("Memory");
|
||||||
|
@ -1160,10 +1163,41 @@ function parsegenseqs(seqs) {
|
||||||
seqselcontents.html("");
|
seqselcontents.html("");
|
||||||
var i;
|
var i;
|
||||||
for(i=0; i<seqs.length; i++) {
|
for(i=0; i<seqs.length; i++) {
|
||||||
seqselcontents.append("<div class=\"seqselitem\" id=\"seqsel"+i+"\" n=\""+i+"\">"+seqs[i].generated_text+"</div>");
|
//setup selection data
|
||||||
|
text_data = "<table><tr><td width=100%><div class=\"seqselitem\" id=\"seqsel"+i+"\" n=\""+i+"\">"+seqs[i][0]+"</div></td><td width=10>"
|
||||||
|
|
||||||
|
//Now do the icon (pin/redo)
|
||||||
|
|
||||||
|
if (seqs[i][1] == "redo") {
|
||||||
|
text_data = text_data + "<span style=\"color: white\" class=\"oi oi-loop-circular\" title=\"Redo\" aria-hidden=\"true\" id=\"seqselpin"+i+"\" n=\""+i+"\"></span>"
|
||||||
|
} else if (seqs[i][1] == "pinned") {
|
||||||
|
text_data = text_data + "<span style=\"color: white\" class=\"oi oi-pin\" title=\"Pin\" aria-hidden=\"true\" id=\"seqselpin"+i+"\" n=\""+i+"\"></span>"
|
||||||
|
} else {
|
||||||
|
text_data = text_data + "<span style=\"color: grey\" class=\"oi oi-pin\" title=\"Pin\" aria-hidden=\"true\" id=\"seqselpin"+i+"\" n=\""+i+"\"></span>"
|
||||||
|
}
|
||||||
|
text_data = text_data + "</td></tr></table>"
|
||||||
|
seqselcontents.append(text_data);
|
||||||
|
|
||||||
|
//setup on-click actions
|
||||||
$("#seqsel"+i).on("click", function () {
|
$("#seqsel"+i).on("click", function () {
|
||||||
socket.send({'cmd': 'seqsel', 'data': $(this).attr("n")});
|
socket.send({'cmd': 'seqsel', 'data': $(this).attr("n")});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//onclick for pin only
|
||||||
|
if (seqs[i][1] != "redo") {
|
||||||
|
$("#seqselpin"+i).on("click", function () {
|
||||||
|
socket.send({'cmd': 'seqpin', 'data': $(this).attr("n")});
|
||||||
|
if ($(this).attr("style") == "color: grey") {
|
||||||
|
console.log($(this).attr("style"));
|
||||||
|
$(this).css({"color": "white"});
|
||||||
|
console.log($(this).attr("style"));
|
||||||
|
} else {
|
||||||
|
console.log($(this).attr("style"));
|
||||||
|
$(this).css({"color": "grey"});
|
||||||
|
console.log($(this).attr("style"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$('#seqselmenu').slideDown("slow");
|
$('#seqselmenu').slideDown("slow");
|
||||||
}
|
}
|
||||||
|
@ -1741,6 +1775,7 @@ $(document).ready(function(){
|
||||||
button_send = $('#btnsend');
|
button_send = $('#btnsend');
|
||||||
button_actmem = $('#btn_actmem');
|
button_actmem = $('#btn_actmem');
|
||||||
button_actback = $('#btn_actundo');
|
button_actback = $('#btn_actundo');
|
||||||
|
button_actfwd = $('#btn_actredo');
|
||||||
button_actretry = $('#btn_actretry');
|
button_actretry = $('#btn_actretry');
|
||||||
button_actwi = $('#btn_actwi');
|
button_actwi = $('#btn_actwi');
|
||||||
game_text = $('#gametext');
|
game_text = $('#gametext');
|
||||||
|
@ -1750,6 +1785,7 @@ $(document).ready(function(){
|
||||||
settings_menu = $("#settingsmenu");
|
settings_menu = $("#settingsmenu");
|
||||||
format_menu = $('#formatmenu');
|
format_menu = $('#formatmenu');
|
||||||
anote_menu = $('#anoterowcontainer');
|
anote_menu = $('#anoterowcontainer');
|
||||||
|
debug_area = $('#debugcontainer');
|
||||||
wi_menu = $('#wimenu');
|
wi_menu = $('#wimenu');
|
||||||
anote_input = $('#anoteinput');
|
anote_input = $('#anoteinput');
|
||||||
anote_labelcur = $('#anotecur');
|
anote_labelcur = $('#anotecur');
|
||||||
|
@ -1765,6 +1801,7 @@ $(document).ready(function(){
|
||||||
aidg_close = $("#btn_aidgpopupclose");
|
aidg_close = $("#btn_aidgpopupclose");
|
||||||
saveaspopup = $("#saveascontainer");
|
saveaspopup = $("#saveascontainer");
|
||||||
saveasinput = $("#savename");
|
saveasinput = $("#savename");
|
||||||
|
savepins = $("#savepins");
|
||||||
topic = $("#topic");
|
topic = $("#topic");
|
||||||
saveas_accept = $("#btn_saveasaccept");
|
saveas_accept = $("#btn_saveasaccept");
|
||||||
saveas_close = $("#btn_saveasclose");
|
saveas_close = $("#btn_saveasclose");
|
||||||
|
@ -1913,13 +1950,13 @@ $(document).ready(function(){
|
||||||
// Enable or Disable buttons
|
// Enable or Disable buttons
|
||||||
if(msg.data == "ready") {
|
if(msg.data == "ready") {
|
||||||
enableSendBtn();
|
enableSendBtn();
|
||||||
enableButtons([button_actmem, button_actwi, button_actback, button_actretry]);
|
enableButtons([button_actmem, button_actwi, button_actback, button_actfwd, button_actretry]);
|
||||||
hideWaitAnimation();
|
hideWaitAnimation();
|
||||||
gamestate = "ready";
|
gamestate = "ready";
|
||||||
} else if(msg.data == "wait") {
|
} else if(msg.data == "wait") {
|
||||||
gamestate = "wait";
|
gamestate = "wait";
|
||||||
disableSendBtn();
|
disableSendBtn();
|
||||||
disableButtons([button_actmem, button_actwi, button_actback, button_actretry]);
|
disableButtons([button_actmem, button_actwi, button_actback, button_actfwd, button_actretry]);
|
||||||
showWaitAnimation();
|
showWaitAnimation();
|
||||||
} else if(msg.data == "start") {
|
} else if(msg.data == "start") {
|
||||||
setStartState();
|
setStartState();
|
||||||
|
@ -2251,6 +2288,14 @@ $(document).ready(function(){
|
||||||
} else if(msg.cmd == "runs_remotely") {
|
} else if(msg.cmd == "runs_remotely") {
|
||||||
remote = true;
|
remote = true;
|
||||||
hide([button_savetofile, button_import, button_importwi]);
|
hide([button_savetofile, button_import, button_importwi]);
|
||||||
|
} else if(msg.cmd == "debug_info") {
|
||||||
|
$("#debuginfo").val(msg.data);
|
||||||
|
} else if(msg.cmd == "set_debug") {
|
||||||
|
if(msg.data) {
|
||||||
|
debug_area.removeClass("hidden");
|
||||||
|
} else {
|
||||||
|
debug_area.addClass("hidden");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2330,6 +2375,12 @@ $(document).ready(function(){
|
||||||
hidegenseqs();
|
hidegenseqs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
button_actfwd.on("click", function(ev) {
|
||||||
|
hideMessage();
|
||||||
|
//hidegenseqs();
|
||||||
|
socket.send({'cmd': 'redo', 'data': ''});
|
||||||
|
});
|
||||||
|
|
||||||
button_actmem.on("click", function(ev) {
|
button_actmem.on("click", function(ev) {
|
||||||
socket.send({'cmd': 'memory', 'data': ''});
|
socket.send({'cmd': 'memory', 'data': ''});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="8" height="8" data-icon="pin" viewBox="0 0 8 8">
|
||||||
|
<path d="M1.344 0a.502.502 0 0 0 .156 1h.5v2h-1c-.55 0-1 .45-1 1h3v3l.438 1 .563-1v-3h3c0-.55-.45-1-1-1h-1v-2h.5a.5.5 0 1 0 0-1h-4a.5.5 0 0 0-.094 0 .502.502 0 0 0-.063 0z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 295 B |
|
@ -123,6 +123,7 @@
|
||||||
<button type="button" class="btn btn-primary" id="btn_actmem">Memory</button>
|
<button type="button" class="btn btn-primary" id="btn_actmem">Memory</button>
|
||||||
<button type="button" class="btn btn-primary" id="btn_actwi">W Info</button>
|
<button type="button" class="btn btn-primary" id="btn_actwi">W Info</button>
|
||||||
<button type="button" class="btn btn-primary" id="btn_actundo">Back</button>
|
<button type="button" class="btn btn-primary" id="btn_actundo">Back</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="btn_actredo">Redo</button>
|
||||||
<button type="button" class="btn btn-primary" id="btn_actretry">Retry</button>
|
<button type="button" class="btn btn-primary" id="btn_actretry">Retry</button>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" id="chatname" class="form-control hidden" placeholder="Chat name">
|
<input type="text" id="chatname" class="form-control hidden" placeholder="Chat name">
|
||||||
|
@ -185,6 +186,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hidden" id="debugcontainer">
|
||||||
|
<textarea class="form-control" placeholder="Debug Info" id="debuginfo"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" id="popupcontainer">
|
<div class="hidden" id="popupcontainer">
|
||||||
|
@ -228,7 +232,9 @@
|
||||||
<div class="popuptitletext">Enter Name For Save</div>
|
<div class="popuptitletext">Enter Name For Save</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="aidgpopupcontent">
|
<div class="aidgpopupcontent">
|
||||||
<input class="form-control" type="text" placeholder="Save Name" id="savename">
|
<input class="form-control" type="text" placeholder="Save Name" id="savename"><br>
|
||||||
|
<input type="checkbox" data-toggle="toggle" data-onstyle="success" id="savepins" checked>
|
||||||
|
<div class="box-label">Save Pin Information</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="popuperror hidden">
|
<div class="popuperror hidden">
|
||||||
<span></span>
|
<span></span>
|
||||||
|
|
Loading…
Reference in New Issue