diff --git a/lollms/app.py b/lollms/app.py index f9ba2e4..1445806 100644 --- a/lollms/app.py +++ b/lollms/app.py @@ -5,12 +5,11 @@ from lollms.binding import LLMBinding, BindingBuilder, ModelBuilder from lollms.extension import LOLLMSExtension, ExtensionBuilder from lollms.config import InstallOption from lollms.helpers import NotificationType -from lollms.helpers import trace_exception +from lollms.helpers import ASCIIColors, trace_exception, NotificationType, NotificationDisplayType from lollms.terminal import MainMenu from lollms.utilities import PromptReshaper from safe_store import TextVectorizer, VectorizationMethod, VisualizationMethod from typing import Callable -from ascii_colors import ASCIIColors from pathlib import Path from datetime import datetime from functools import partial @@ -30,7 +29,6 @@ class LollmsApplication: try_select_binding=False, try_select_model=False, callback=None, - notification_callback:Callable=None ) -> None: """ Creates a LOLLMS Application @@ -44,7 +42,6 @@ class LollmsApplication: self.personality = None self.mounted_extensions = [] - self.notification_callback = notification_callback self.binding = None self.model:LLMBinding = None self.long_term_memory = None @@ -228,7 +225,68 @@ class LollmsApplication: generated_text = self.personality.model.generate(full_discussion, n_predict=n_predict, callback=callback) return generated_text - def notify(self, content, notification_type:NotificationType=NotificationType.NOTIF_SUCCESS, duration=4, client_id=None, verbose= True): + + + + def InfoMessage(self, content, duration:int=4, client_id=None, verbose:bool=True): + self.notify( + content, + notification_type=NotificationType.NOTIF_SUCCESS, + duration=duration, + client_id=client_id, + display_type=NotificationDisplayType.MESSAGE_BOX, + verbose=verbose + ) + + def info(self, content, duration:int=4, client_id=None, verbose:bool=True): + self.notify( + content, + notification_type=NotificationType.NOTIF_SUCCESS, + duration=duration, + client_id=client_id, + display_type=NotificationDisplayType.TOAST, + verbose=verbose + ) + + def warning(self, content, duration:int=4, client_id=None, verbose:bool=True): + self.notify( + content, + notification_type=NotificationType.NOTIF_WARNING, + duration=duration, + client_id=client_id, + display_type=NotificationDisplayType.TOAST, + verbose=verbose + ) + + def success(self, content, duration:int=4, client_id=None, verbose:bool=True): + self.notify( + content, + notification_type=NotificationType.NOTIF_SUCCESS, + duration=duration, + client_id=client_id, + display_type=NotificationDisplayType.TOAST, + verbose=verbose + ) + + def error(self, content, duration:int=4, client_id=None): + self.notify( + content, + notification_type=NotificationType.NOTIF_ERROR, + duration=duration, + client_id=client_id, + display_type=NotificationDisplayType.TOAST + ) + + + def notify( + self, + content, + notification_type:NotificationType=NotificationType.NOTIF_SUCCESS, + duration:int=4, + client_id=None, + display_type:NotificationDisplayType=NotificationDisplayType.TOAST, + verbose=True + ): if verbose: if notification_type==NotificationType.NOTIF_SUCCESS: ASCIIColors.success(content) @@ -239,25 +297,20 @@ class LollmsApplication: else: ASCIIColors.red(content) - if self.notification_callback: - return self.notification_callback(content, notification_type, duration, client_id) def load_binding(self): try: - binding = BindingBuilder().build_binding(self.config, self.lollms_paths, notification_callback=self.notify) + binding = BindingBuilder().build_binding(self.config, self.lollms_paths, app=self) return binding except Exception as ex: - self.notify("Couldn't load binding", False) - self.notify("Trying to reinstall binding") - print(ex) - print(f"Couldn't find binding. Please verify your configuration file at {self.lollms_paths.personal_configuration_path}/local_configs.yaml or use the next menu to select a valid binding") - print(f"Trying to reinstall binding") + self.error("Couldn't load binding") + self.info("Trying to reinstall binding") + trace_exception(ex) try: - binding = BindingBuilder().build_binding(self.config, self.lollms_paths,installation_option=InstallOption.FORCE_INSTALL) + binding = BindingBuilder().build_binding(self.config, self.lollms_paths,installation_option=InstallOption.FORCE_INSTALL, app=self) except Exception as ex: - self.notify("Couldn't reinstall binding", False) - ASCIIColors.error("Couldn't reinstall binding") + self.error("Couldn't reinstall binding") trace_exception(ex) return None diff --git a/lollms/apps/server/__init__.py b/lollms/apps/server/__init__.py index de42598..0987c69 100644 --- a/lollms/apps/server/__init__.py +++ b/lollms/apps/server/__init__.py @@ -215,7 +215,7 @@ class LoLLMsServer(LollmsApplication): for per in self.mounted_personalities: per.model = None gc.collect() - self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths) + self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths, app=self) self.model = self.binding.build_model() for per in self.mounted_personalities: per.model = self.model diff --git a/lollms/apps/settings/__init__.py b/lollms/apps/settings/__init__.py index 32486af..0869543 100644 --- a/lollms/apps/settings/__init__.py +++ b/lollms/apps/settings/__init__.py @@ -226,13 +226,13 @@ def main(): if args.install_binding: settings_app.config.binding_name= args.install_binding - settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL) + settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL, app=settings_app) settings_app.config.save_config() if args.install_model: if not settings_app.binding: - settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL) + settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL, app=settings_app) def progress_callback(blocks, block_size, total_size): tqdm_bar.total=total_size @@ -249,7 +249,7 @@ def main(): if args.select_model: settings_app.config.model_name = args.select_model if not settings_app.binding: - settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL) + settings_app.binding = BindingBuilder().build_binding(settings_app.config, settings_app.lollms_paths,InstallOption.FORCE_INSTALL, app=settings_app) settings_app.model = settings_app.binding.build_model() settings_app.config.save_config() diff --git a/lollms/binding.py b/lollms/binding.py index 8e1672f..49227f5 100644 --- a/lollms/binding.py +++ b/lollms/binding.py @@ -21,7 +21,7 @@ import importlib import subprocess from lollms.config import TypedConfig, InstallOption from lollms.main_config import LOLLMSConfig -from lollms.helpers import NotificationType +from lollms.helpers import NotificationType, NotificationDisplayType import urllib import inspect from enum import Enum @@ -57,7 +57,7 @@ class LLMBinding: supported_file_extensions='*.bin', binding_type:BindingType=BindingType.TEXT_ONLY, models_dir_names:list=None, - notification_callback:Callable=None + app:Callable=None ) -> None: self.binding_type = binding_type @@ -80,7 +80,46 @@ class LLMBinding: self.supported_file_extensions = supported_file_extensions self.seed = config["seed"] - self.notification_callback = notification_callback + + if app is not None: + self.error:Callable = app.error + self.info:Callable = app.info + self.success:Callable = app.success + self.warning:Callable = app.warning + self.notify:Callable = app.notify + self.InfoMessage:Callable = app.InfoMessage + else: + def InfoMessage(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.white(content) + + def info(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.info(content) + + def warning(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.warning(content) + + def success(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.success(content) + + def error(content, duration:int=4, client_id=None): + ASCIIColors.error(content) + + def notify( + content, + notification_type:NotificationType=NotificationType.NOTIF_SUCCESS, + duration:int=4, + client_id=None, + display_type:NotificationDisplayType=NotificationDisplayType.TOAST, + verbose=True + ): + ASCIIColors.white(content) + + self.error:Callable = error + self.info:Callable = info + self.success:Callable = success + self.warning:Callable = warning + self.notify:Callable = notify + self.InfoMessage:Callable = InfoMessage self.configuration_file_path = lollms_paths.personal_configuration_path/"bindings"/self.binding_folder_name/f"config.yaml" self.configuration_file_path.parent.mkdir(parents=True, exist_ok=True) @@ -104,21 +143,6 @@ class LLMBinding: for models_folder in self.models_folders: models_folder.mkdir(parents=True, exist_ok=True) - def notify(self, content:str, notification_type:NotificationType=NotificationType.NOTIF_SUCCESS, duration=4, verbose=True): - if verbose: - if notification_type==NotificationType.NOTIF_SUCCESS: - ASCIIColors.success(content) - elif notification_type==NotificationType.NOTIF_INFO: - ASCIIColors.info(content) - elif notification_type==NotificationType.NOTIF_WARNING: - ASCIIColors.warning(content) - else: - ASCIIColors.red(content) - - if self.notification_callback: - self.notification_callback(content, notification_type, duration) - - def settings_updated(self): """ To be implemented by the bindings @@ -521,7 +545,7 @@ class BindingBuilder: config: LOLLMSConfig, lollms_paths:LollmsPaths, installation_option:InstallOption=InstallOption.INSTALL_IF_NECESSARY, - notification_callback:Callable=None + app=None )->LLMBinding: binding:LLMBinding = self.getBinding(config, lollms_paths, installation_option) @@ -529,7 +553,7 @@ class BindingBuilder: config, lollms_paths=lollms_paths, installation_option = installation_option, - notification_callback=notification_callback + app=app ) def getBinding( diff --git a/lollms/personality.py b/lollms/personality.py index 8a73c6d..d0014bd 100644 --- a/lollms/personality.py +++ b/lollms/personality.py @@ -13,6 +13,8 @@ from lollms.main_config import LOLLMSConfig from lollms.paths import LollmsPaths from lollms.binding import LLMBinding, BindingType from lollms.utilities import PromptReshaper, PackageManager +from lollms.helpers import NotificationType, NotificationDisplayType + import pkg_resources from pathlib import Path from PIL import Image @@ -97,9 +99,45 @@ class AIPersonality: self.callback = callback self.app = app if app is not None: - self.notify = app.notify + self.error:Callable = app.error + self.info:Callable = app.info + self.success:Callable = app.success + self.warning:Callable = app.warning + self.notify:Callable = app.notify + self.InfoMessage:Callable = app.InfoMessage else: - self.notify = None + def InfoMessage(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.white(content) + + def info(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.info(content) + + def warning(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.warning(content) + + def success(content, duration:int=4, client_id=None, verbose:bool=True): + ASCIIColors.success(content) + + def error(content, duration:int=4, client_id=None): + ASCIIColors.error(content) + + def notify( + content, + notification_type:NotificationType=NotificationType.NOTIF_SUCCESS, + duration:int=4, + client_id=None, + display_type:NotificationDisplayType=NotificationDisplayType.TOAST, + verbose=True + ): + ASCIIColors.white(content) + + self.error:Callable = error + self.info:Callable = info + self.success:Callable = success + self.warning:Callable = warning + self.notify:Callable = notify + self.InfoMessage:Callable = InfoMessage + self.text_files = [] self.image_files = [] self.images_descriptions = [] @@ -1631,10 +1669,10 @@ class APScript(StateMachine): return True def remove_file(self, path): - if path in self.text_files: - self.text_files.remove(path) - elif path in self.image_files: - self.image_files.remove(path) + if path in self.personality.text_files: + self.personality.text_files.remove(path) + elif path in self.personality.image_files: + self.personality.image_files.remove(path) def load_config_file(self, path, default_config=None): diff --git a/lollms/terminal.py b/lollms/terminal.py index e625917..5a055d3 100644 --- a/lollms/terminal.py +++ b/lollms/terminal.py @@ -425,7 +425,7 @@ class MainMenu(Menu): self.lollms_app.config['binding_name']=self.binding_infs[choice - 1]['name'] try: - lollms_app.binding = BindingBuilder().build_binding(lollms_app.config, lollms_app.lollms_paths,InstallOption.FORCE_INSTALL) + lollms_app.binding = BindingBuilder().build_binding(lollms_app.config, lollms_app.lollms_paths,InstallOption.FORCE_INSTALL, app=self) except Exception as ex: print(ex) print(f"Couldn't find binding. Please verify your configuration file at {lollms_app.config.file_path} or use the next menu to select a valid binding") diff --git a/setup.py b/setup.py index a936ccc..752ef4b 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def get_all_files(path): setuptools.setup( name="lollms", - version="6.7.0", + version="6.8.0", author="Saifeddine ALOUI", author_email="aloui.saifeddine@gmail.com", description="A python library for AI personality definition",