diff --git a/lollms/app.py b/lollms/app.py index e8fb47d..f91c1ce 100644 --- a/lollms/app.py +++ b/lollms/app.py @@ -723,6 +723,150 @@ class LollmsApplication(LoLLMsCom): trace_exception(ex) + def rebuild_personalities(self, reload_all=False): + if reload_all: + self.mounted_personalities = [] + + loaded = self.mounted_personalities + loaded_names = [ + f"{p.category}/{p.personality_folder_name}" for p in loaded if p is not None + ] + mounted_personalities = [] + ASCIIColors.success(f" ╔══════════════════════════════════════════════════╗ ") + ASCIIColors.success(f" ║ Building mounted Personalities ║ ") + ASCIIColors.success(f" ╚══════════════════════════════════════════════════╝ ") + to_remove = [] + for i, personality in enumerate(self.config["personalities"]): + if i == self.config["active_personality_id"]: + ASCIIColors.red("*", end="") + ASCIIColors.green(f" {personality}") + else: + ASCIIColors.yellow(f" {personality}") + if personality in loaded_names: + mounted_personalities.append(loaded[loaded_names.index(personality)]) + else: + personality_path = f"{personality}" + try: + personality = AIPersonality( + personality_path, + self.lollms_paths, + self.config, + model=self.model, + app=self, + selected_language=self.config.current_language, + run_scripts=True, + ) + + mounted_personalities.append(personality) + if self.config.auto_read and len(personality.audio_samples) > 0: + try: + from lollms.services.tts.xtts.lollms_xtts import \ + LollmsXTTS + + if self.tts is None: + voice = self.config.xtts_current_voice + if voice != "main_voice": + voices_folder = self.lollms_paths.custom_voices_path + else: + voices_folder = ( + Path(__file__).parent.parent.parent + / "services/xtts/voices" + ) + + self.tts = LollmsXTTS( + self, + voices_folders=[ + voices_folder, + Path(__file__).parent.parent.parent + / "services/xtts/voices", + ], + freq=self.config.xtts_freq, + ) + + except Exception as ex: + trace_exception(ex) + self.warning( + f"Personality {personality.name} request using custom voice but couldn't load XTTS" + ) + except Exception as ex: + trace_exception(ex) + ASCIIColors.error( + f"Personality file not found or is corrupted ({personality_path}).\nReturned the following exception:{ex}\nPlease verify that the personality you have selected exists or select another personality. Some updates may lead to change in personality name or category, so check the personality selection in settings to be sure." + ) + ASCIIColors.info("Trying to force reinstall") + if self.config["debug"]: + print(ex) + try: + personality = AIPersonality( + personality_path, + self.lollms_paths, + self.config, + self.model, + app=self, + run_scripts=True, + selected_language=self.config.current_language, + installation_option=InstallOption.FORCE_INSTALL, + ) + mounted_personalities.append(personality) + if personality.processor: + personality.processor.mounted() + except Exception as ex: + ASCIIColors.error( + f"Couldn't load personality at {personality_path}" + ) + trace_exception(ex) + ASCIIColors.info(f"Unmounting personality") + to_remove.append(i) + personality = AIPersonality( + None, + self.lollms_paths, + self.config, + self.model, + app=self, + run_scripts=True, + installation_option=InstallOption.FORCE_INSTALL, + ) + mounted_personalities.append(personality) + if personality.processor: + personality.processor.mounted() + + ASCIIColors.info("Reverted to default personality") + if self.config["active_personality_id"] >= 0 and self.config[ + "active_personality_id" + ] < len(self.config["personalities"]): + ASCIIColors.success( + f'selected model : {self.config["personalities"][self.config["active_personality_id"]]}' + ) + else: + ASCIIColors.warning( + "An error was encountered while trying to mount personality" + ) + ASCIIColors.multicolor( + texts=[ + f" ╔══════════════════════════════════════════════════╗\n", + f" ║"," Done ","║\n", + f" ╚══════════════════════════════════════════════════╝\n", + ], + colors=[ + ASCIIColors.color_bright_cyan, + ASCIIColors.color_bright_cyan,ASCIIColors.color_bright_green,ASCIIColors.color_bright_cyan, + ASCIIColors.color_bright_cyan, + ] + ) + # Sort the indices in descending order to ensure correct removal + to_remove.sort(reverse=True) + + # Remove elements from the list based on the indices + for index in to_remove: + if 0 <= index < len(mounted_personalities): + mounted_personalities.pop(index) + self.config["personalities"].pop(index) + ASCIIColors.info(f"removed personality {personality_path}") + + if self.config["active_personality_id"] >= len(self.config["personalities"]): + self.config["active_personality_id"] = 0 + + return mounted_personalities def process_data( self, diff --git a/lollms/server/endpoints/lollms_configuration_infos.py b/lollms/server/endpoints/lollms_configuration_infos.py index 280ceb1..b877bdf 100644 --- a/lollms/server/endpoints/lollms_configuration_infos.py +++ b/lollms/server/endpoints/lollms_configuration_infos.py @@ -190,6 +190,8 @@ async def apply_settings(request: Request): lollmsElfServer.config.config[key] = config.get(key, lollmsElfServer.config.config[key]) ASCIIColors.success("OK") + if lollmsElfServer.config.binding_name != lollmsElfServer.binding.binding_folder_name: + lollmsElfServer.binding = BindingBuilder().build_binding(lollmsElfServer.config, lollmsElfServer.lollms_paths, InstallOption.INSTALL_IF_NECESSARY, lollmsCom=lollmsElfServer) lollmsElfServer.rebuild_personalities() lollmsElfServer.verify_servers() if lollmsElfServer.config.auto_save: