diff --git a/aiserver.py b/aiserver.py index c14ac730..77e31b63 100644 --- a/aiserver.py +++ b/aiserver.py @@ -4436,11 +4436,11 @@ def get_message(msg): emit('from_server', {'cmd': 'wiexpandfolder', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifoldercollapsecontent'): setgamesaved(False) - koboldai_vars.wifolders_d[msg['data']]['collapsed'] = True + koboldai_vars.wifolders_d[str(msg['data'])]['collapsed'] = True emit('from_server', {'cmd': 'wifoldercollapsecontent', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifolderexpandcontent'): setgamesaved(False) - koboldai_vars.wifolders_d[msg['data']]['collapsed'] = False + koboldai_vars.wifolders_d[str(msg['data'])]['collapsed'] = False emit('from_server', {'cmd': 'wifolderexpandcontent', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiupdate'): setgamesaved(False) @@ -4452,12 +4452,12 @@ def get_message(msg): emit('from_server', {'cmd': 'wiupdate', 'num': msg['num'], 'data': {field: koboldai_vars.worldinfo[num][field] for field in fields}}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifolderupdate'): setgamesaved(False) - uid = str(msg['uid']) + str_uid = str(msg['uid']) fields = ("name", "collapsed") for field in fields: if(field in msg['data'] and type(msg['data'][field]) is (str if field != "collapsed" else bool)): - koboldai_vars.wifolders_d[uid][field] = msg['data'][field] - emit('from_server', {'cmd': 'wifolderupdate', 'uid': msg['uid'], 'data': {field: koboldai_vars.wifolders_d[uid][field] for field in fields}}, broadcast=True, room="UI_1") + koboldai_vars.wifolders_d[str_uid][field] = msg['data'][field] + emit('from_server', {'cmd': 'wifolderupdate', 'uid': msg['uid'], 'data': {field: koboldai_vars.wifolders_d[str_uid][field] for field in fields}}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiselon'): setgamesaved(False) koboldai_vars.worldinfo[msg['data']]["selective"] = True @@ -6798,7 +6798,8 @@ def togglewimode(): # #==================================================================# def addwiitem(folder_uid=None): - assert folder_uid is None or folder_uid in koboldai_vars.wifolders_d + str_folder_uid = str(folder_uid) if folder_uid is not None else None + assert str_folder_uid is None or str_folder_uid in koboldai_vars.wifolders_d ob = {"key": "", "keysecondary": "", "content": "", "comment": "", "folder": folder_uid, "num": len(koboldai_vars.worldinfo), "init": False, "selective": False, "constant": False} koboldai_vars.worldinfo.append(ob) while(True): @@ -6806,9 +6807,9 @@ def addwiitem(folder_uid=None): if(uid not in koboldai_vars.worldinfo_u): break koboldai_vars.worldinfo_u[uid] = koboldai_vars.worldinfo[-1] - koboldai_vars.worldinfo[-1]["uid"] = uid - if(folder_uid is not None): - koboldai_vars.wifolders_u[folder_uid].append(koboldai_vars.worldinfo[-1]) + koboldai_vars.worldinfo[-1]["uid"] = int(uid) + if(str_folder_uid is not None): + koboldai_vars.wifolders_u[str_folder_uid].append(koboldai_vars.worldinfo[-1]) emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True, room="UI_1") #==================================================================# @@ -6821,10 +6822,10 @@ def addwifolder(): break ob = {"name": "", "collapsed": False} koboldai_vars.wifolders_d[uid] = ob - koboldai_vars.wifolders_l.append(uid) + koboldai_vars.wifolders_l.append(int(uid)) koboldai_vars.wifolders_u[uid] = [] - emit('from_server', {'cmd': 'addwifolder', 'uid': uid, 'data': ob}, broadcast=True, room="UI_1") - addwiitem(folder_uid=uid) + emit('from_server', {'cmd': 'addwifolder', 'uid': int(uid), 'data': ob}, broadcast=True, room="UI_1") + addwiitem(folder_uid=int(uid)) #==================================================================# # Move the WI entry with UID src so that it immediately precedes @@ -6928,14 +6929,14 @@ def stablesortwi(): #==================================================================# def commitwi(ar): for ob in ar: - ob["uid"] = str(ob["uid"]) - koboldai_vars.worldinfo_u[ob["uid"]]["key"] = ob["key"] - koboldai_vars.worldinfo_u[ob["uid"]]["keysecondary"] = ob["keysecondary"] - koboldai_vars.worldinfo_u[ob["uid"]]["content"] = ob["content"] - koboldai_vars.worldinfo_u[ob["uid"]]["comment"] = ob.get("comment", "") - koboldai_vars.worldinfo_u[ob["uid"]]["folder"] = ob.get("folder", None) - koboldai_vars.worldinfo_u[ob["uid"]]["selective"] = ob["selective"] - koboldai_vars.worldinfo_u[ob["uid"]]["constant"] = ob.get("constant", False) + str_uid = str(ob["uid"]) + koboldai_vars.worldinfo_u[str_uid]["key"] = ob["key"] + koboldai_vars.worldinfo_u[str_uid]["keysecondary"] = ob["keysecondary"] + koboldai_vars.worldinfo_u[str_uid]["content"] = ob["content"] + koboldai_vars.worldinfo_u[str_uid]["comment"] = ob.get("comment", "") + koboldai_vars.worldinfo_u[str_uid]["folder"] = ob.get("folder", None) + koboldai_vars.worldinfo_u[str_uid]["selective"] = ob["selective"] + koboldai_vars.worldinfo_u[str_uid]["constant"] = ob.get("constant", False) stablesortwi() koboldai_vars.worldinfo_i = [wi for wi in koboldai_vars.worldinfo if wi["init"]] koboldai_vars.sync_worldinfo_v1_to_v2() @@ -6945,20 +6946,22 @@ def commitwi(ar): # #==================================================================# def deletewi(uid): - if(uid in koboldai_vars.worldinfo_u): + if(str(uid) in koboldai_vars.worldinfo_u): setgamesaved(False) # Store UID of deletion request koboldai_vars.deletewi = uid if(koboldai_vars.deletewi is not None): - if(koboldai_vars.worldinfo_u[koboldai_vars.deletewi]["folder"] is not None): - for i, e in enumerate(koboldai_vars.wifolders_u[koboldai_vars.worldinfo_u[koboldai_vars.deletewi]["folder"]]): - if(e is koboldai_vars.worldinfo_u[koboldai_vars.deletewi]): - koboldai_vars.wifolders_u[koboldai_vars.worldinfo_u[koboldai_vars.deletewi]["folder"]].pop(i) + str_uid = str(uid) + if(koboldai_vars.worldinfo_u[str_uid]["folder"] is not None): + str_folder_uid = str(koboldai_vars.worldinfo_u[str_uid]["folder"]) + for i, e in enumerate(koboldai_vars.wifolders_u[str_folder_uid]): + if(e is koboldai_vars.worldinfo_u[str_uid]): + koboldai_vars.wifolders_u[str_folder_uid].pop(i) for i, e in enumerate(koboldai_vars.worldinfo): - if(e is koboldai_vars.worldinfo_u[koboldai_vars.deletewi]): + if(e is koboldai_vars.worldinfo_u[str_uid]): del koboldai_vars.worldinfo[i] break - del koboldai_vars.worldinfo_u[koboldai_vars.deletewi] + del koboldai_vars.worldinfo_u[str_uid] # Send the new WI array structure sendwi() # And reset deletewi @@ -6968,9 +6971,9 @@ def deletewi(uid): # #==================================================================# def deletewifolder(uid): - uid = str(uid) - del koboldai_vars.wifolders_u[uid] - del koboldai_vars.wifolders_d[uid] + str_uid = str(uid) + del koboldai_vars.wifolders_u[str_uid] + del koboldai_vars.wifolders_d[str_uid] del koboldai_vars.wifolders_l[koboldai_vars.wifolders_l.index(uid)] setgamesaved(False) # Delete uninitialized entries in the folder we're going to delete @@ -7480,7 +7483,7 @@ def loadJSON(json_text_or_dict, from_file=None): ignore = koboldai_vars.calc_ai_text() def load_story_v1(js, from_file=None): - logger.debug("Loading V1 Story") + logger.info("Loading V1 Story") logger.debug("Called from {}".format(inspect.stack()[1].function)) loadpath = js['v1_loadpath'] if 'v1_loadpath' in js else koboldai_vars.savedir filename = js['v1_filename'] if 'v1_filename' in js else 'untitled.json' @@ -7509,7 +7512,7 @@ def load_story_v1(js, from_file=None): koboldai_vars.worldinfo = [] koboldai_vars.worldinfo_i = [] koboldai_vars.worldinfo_u = {} - koboldai_vars.wifolders_d = {int(k): v for k, v in js.get("wifolders_d", {}).items()} + koboldai_vars.wifolders_d = {k: v for k, v in js.get("wifolders_d", {}).items()} koboldai_vars.wifolders_l = js.get("wifolders_l", []) koboldai_vars.wifolders_u = {uid: [] for uid in koboldai_vars.wifolders_d} koboldai_vars.lastact = "" @@ -7569,8 +7572,9 @@ def load_story_v1(js, from_file=None): folder = "root" else: if 'wifolders_d' in js: - if wi['folder'] in js['wifolders_d']: - folder = js['wifolders_d'][wi['folder']]['name'] + str_folder_uid = str(wi['folder']) + if str_folder_uid in js['wifolders_d']: + folder = js['wifolders_d'][str_folder_uid]['name'] else: folder = "root" else: @@ -7609,7 +7613,7 @@ def load_story_v1(js, from_file=None): def load_story_v2(js, from_file=None): - logger.debug("Loading V2 Story") + logger.info("Loading V2 Story") logger.debug("Called from {}".format(inspect.stack()[1].function)) leave_room(session['story']) session['story'] = js['story_name'] @@ -7620,7 +7624,8 @@ def load_story_v2(js, from_file=None): if from_file is not None and os.path.basename(from_file) != "story.json": #Save the file so we get a new V2 format, then move the save file into the proper directory koboldai_vars.save_story() - shutil.move(from_file, koboldai_vars.save_paths.story.replace("story.json", "v2_file.json")) + #We're no longer moving the original file. It'll stay in place. + #shutil.move(from_file, koboldai_vars.save_paths.story.replace("story.json", "v2_file.json")) diff --git a/commandline.bat b/commandline.bat index d25da157..5372a9a3 100644 --- a/commandline.bat +++ b/commandline.bat @@ -1,6 +1,10 @@ @echo off cd /D %~dp0 + +:Isolation SET CONDA_SHLVL= +SET PYTHONNOUSERSITE=1 +SET PYTHONPATH= TITLE CMD for KoboldAI Runtime SET /P M= None: # Upon loading a file, makes directories that are required for certain @@ -1202,12 +1202,12 @@ class system_settings(settings): local_only_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'lua_koboldcore', 'regex_sl', 'acregex_ai', 'acregex_ui', 'comregex_ai', 'comregex_ui', 'sp', '_horde_pid', 'inference_config', 'image_pipeline', - 'summarizer', 'summary_tokenizer', 'tts_model'] + 'summarizer', 'summary_tokenizer', 'tts_model', 'rng_states'] no_save_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'lua_koboldcore', 'sp', 'sp_length', '_horde_pid', 'horde_share', 'aibusy', 'serverstarted', 'inference_config', 'image_pipeline', 'summarizer', 'summary_tokenizer', 'use_colab_tpu', 'noai', 'disable_set_aibusy', 'cloudflare_link', 'tts_model', - 'generating_image', 'bit_8_available', 'host', 'hascuda', 'usegpu'] + 'generating_image', 'bit_8_available', 'host', 'hascuda', 'usegpu', 'rng_states'] settings_name = "system" def __init__(self, socketio, koboldai_var): self._socketio = socketio @@ -1263,6 +1263,7 @@ class system_settings(settings): self.disable_output_formatting = False self.full_determinism = False # Whether or not full determinism is enabled self.seed_specified = False # Whether or not the current RNG seed was specified by the user (in their settings file) + self.rng_states = {} # creates an empty dictionary to store the random number generator (RNG) states for a given seed, which is used to restore the RNG state later on 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))] @@ -2259,6 +2260,8 @@ 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") def delete_folder(self, folder): + if folder == "root": + raise Exception("removing the root folder is not supported") keys = [key for key in self.world_info] for key in keys: if self.world_info[key]['folder'] == folder: @@ -2272,7 +2275,7 @@ class KoboldWorldInfo(object): def add_item_to_folder(self, uid, folder, before=None): if uid in self.world_info: - #fiirst we need to remove the item from whatever folder it's in + #first we need to remove the item from whatever folder it's in for temp in self.world_info_folder: if uid in self.world_info_folder[temp]: self.world_info_folder[temp].remove(uid) @@ -2357,7 +2360,8 @@ class KoboldWorldInfo(object): raise if folder not in self.world_info_folder: self.world_info_folder[folder] = [] - self.world_info_folder[folder].append(uid) + if uid not in self.world_info_folder[folder]: + self.world_info_folder[folder].append(uid) self.story_settings.gamesaved = False if sync: self.sync_world_info_to_old_format() @@ -2442,8 +2446,11 @@ class KoboldWorldInfo(object): self._socketio.emit("world_info_entry", self.world_info[uid], broadcast=True, room="UI_2") def delete(self, uid): + if self.world_info[uid]['folder'] == "root": + raise Exception("removing the root folder is not supported") + del self.world_info[uid] - + try: os.remove(os.path.join(self._koboldai_vars.save_paths.wi_images, str(uid))) except FileNotFoundError: @@ -2463,6 +2470,8 @@ class KoboldWorldInfo(object): ignore = self._koboldai_vars.calc_ai_text() def rename_folder(self, old_folder, folder): + if old_folder == "root": + raise Exception("renaming the root folder is not supported") self.story_settings.gamesaved = False if folder in self.world_info_folder: i=0 @@ -2536,14 +2545,10 @@ class KoboldWorldInfo(object): file.write(base64.b64decode(image_b64)) data["entries"] = {k: self.upgrade_entry(v) for k,v in data["entries"].items()} - - if folder is None: - self.world_info_folder = data['folders'] #Add the item start_time = time.time() for uid, item in data['entries'].items(): - self.add_item(item['title'] if 'title' in item else item['key'][0], item['key'] if 'key' in item else [], item['keysecondary'] if 'keysecondary' in item else [], @@ -2555,10 +2560,9 @@ class KoboldWorldInfo(object): use_wpp=item['use_wpp'] if 'use_wpp' in item else False, wpp=item['wpp'] if 'wpp' in item else {'name': "", 'type': "", 'format': "W++", 'attributes': {}}, object_type=item.get("object_type"), + v1_uid=item.get("v1_uid"), recalc=False, sync=False) - if folder is None: - #self.world_info = {int(x): data['entries'][x] for x in data['entries']} - self.world_info_folder = data['folders'] + logger.debug("Load World Info took {}s".format(time.time()-start_time)) try: start_time = time.time() @@ -2577,50 +2581,52 @@ class KoboldWorldInfo(object): for folder in self.world_info_folder: folder_entries[folder] = i i-=1 - - + + #self.wifolders_l = [] # List of World Info folder UIDs + self.story_settings.wifolders_l = [folder_entries[x] for x in folder_entries if x != "root"] + #self.worldinfo_i = [] # List of World Info key/value objects sans uninitialized entries self.story_settings.worldinfo_i = [{ - "comment": self.world_info[x]['comment'], - "constant": self.world_info[x]['constant'], - "content": self.world_info[x]['content'], - "folder": folder_entries[self.world_info[x]['folder']], - "init": True, "key": ",".join(self.world_info[x]['key']), "keysecondary": ",".join(self.world_info[x]['keysecondary']), + "content": self.world_info[x]['content'], + "comment": self.world_info[x]['comment'], + "folder": folder_entries[self.world_info[x]['folder']] if self.world_info[x]['folder'] != "root" else None, "num": x, + "init": True, "selective": len(self.world_info[x]['keysecondary'])>0, + "constant": self.world_info[x]['constant'], "uid": self.world_info[x]['uid'] if 'v1_uid' not in self.world_info[x] or self.world_info[x]['v1_uid'] is None else self.world_info[x]['v1_uid'] } for x in self.world_info] - + #self.worldinfo = [] # List of World Info key/value objects self.story_settings.worldinfo = [x for x in self.story_settings.worldinfo_i] #We have to have an uninitialized blank entry for every folder or the old method craps out for folder in folder_entries: self.story_settings.worldinfo.append({ - "comment": "", - "constant": False, - "content": "", - "folder": folder_entries[folder], - "init": False, "key": "", "keysecondary": "", + "content": "", + "comment": "", + "folder": folder_entries[folder] if folder != "root" else None, "num": (0 if len(self.world_info) == 0 else max(self.world_info))+(folder_entries[folder]*-1), + "init": False, "selective": False, + "constant": False, "uid": folder_entries[folder] }) + mapping = {uid: index for index, uid in enumerate(self.story_settings.wifolders_l)} + self.story_settings.worldinfo.sort(key=lambda x: mapping[x["folder"]] if x["folder"] is not None else float("inf")) + #self.wifolders_d = {} # Dictionary of World Info folder UID-info pairs - self.story_settings.wifolders_d = {folder_entries[x]: {'collapsed': False, 'name': x} for x in folder_entries} + self.story_settings.wifolders_d = {str(folder_entries[x]): {'name': x, 'collapsed': False} for x in folder_entries if x != "root"} #self.worldinfo_u = {} # Dictionary of World Info UID - key/value pairs - self.story_settings.worldinfo_u = {x['uid']: x for x in self.story_settings.worldinfo} - - #self.wifolders_l = [] # List of World Info folder UIDs - self.story_settings.wifolders_l = [folder_entries[x] for x in folder_entries] + self.story_settings.worldinfo_u = {str(y["uid"]): y for x in folder_entries for y in self.story_settings.worldinfo if y["folder"] == (folder_entries[x] if x != "root" else None)} #self.wifolders_u = {} # Dictionary of pairs of folder UID - list of WI UID - self.story_settings.wifolders_u = {folder_entries[x]: [y for y in self.story_settings.worldinfo if y['folder'] == x] for x in folder_entries} + self.story_settings.wifolders_u = {str(folder_entries[x]): [y for y in self.story_settings.worldinfo if y['folder'] == folder_entries[x]] for x in folder_entries if x != "root"} def reset_used_in_game(self): for key in self.world_info: diff --git a/play.bat b/play.bat index c3d96045..76261a37 100644 --- a/play.bat +++ b/play.bat @@ -1,6 +1,10 @@ @echo off cd /D %~dp0 + +:Isolation SET CONDA_SHLVL= +SET PYTHONNOUSERSITE=1 +SET PYTHONPATH= rmdir /S /Q flask_session diff --git a/update-koboldai.bat b/update-koboldai.bat index 728b9f74..6956c789 100644 --- a/update-koboldai.bat +++ b/update-koboldai.bat @@ -1,6 +1,10 @@ @echo off cd /d %~dp0 + +:Isolation SET CONDA_SHLVL= +SET PYTHONNOUSERSITE=1 +SET PYTHONPATH= TITLE KoboldAI - Updater SET /P M=