mirror of
https://github.com/ParisNeo/lollms.git
synced 2024-12-18 20:27:58 +00:00
Upgraded
This commit is contained in:
parent
21f336bcdc
commit
60b116d4b8
@ -180,7 +180,7 @@ Events generated:
|
||||
- Creates a deep copy of the configuration (`self.config`) and assigns it to `self.cp_config`.
|
||||
- Sets the `"model_name"` property of `self.cp_config` to the selected model name.
|
||||
- Tries to create an instance of the binding class (`self.binding`) with `self.cp_config`.
|
||||
- If successful, assigns the created binding instance to `self.active_model`.
|
||||
- If successful, assigns the created binding instance to `self.model`.
|
||||
- Emits a `'select_model'` event with a success response, indicating that the model selection was successful.
|
||||
- Returns and exits the function.
|
||||
- If an exception occurs during model creation, prints the exception and emits a `'select_model'` event with a failure response, indicating that a binding needs to be selected first.
|
||||
|
2
lollms/.gitignore
vendored
Normal file
2
lollms/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
logs
|
||||
uploads
|
157
lollms/app.py
Normal file
157
lollms/app.py
Normal file
@ -0,0 +1,157 @@
|
||||
from lollms.main_config import LOLLMSConfig
|
||||
from lollms.helpers import ASCIIColors
|
||||
from lollms.paths import LollmsPaths
|
||||
from lollms.personality import PersonalityBuilder
|
||||
from lollms.binding import LLMBinding, BindingBuilder, ModelBuilder
|
||||
from lollms.config import InstallOption
|
||||
import traceback
|
||||
from lollms.terminal import MainMenu
|
||||
|
||||
class LollmsApplication:
|
||||
def __init__(self, app_name:str, config:LOLLMSConfig, lollms_paths:LollmsPaths) -> None:
|
||||
"""
|
||||
Creates a LOLLMS Application
|
||||
"""
|
||||
self.app_name = app_name
|
||||
self.config = config
|
||||
self.lollms_paths = lollms_paths
|
||||
|
||||
self.menu = MainMenu(self)
|
||||
self.mounted_personalities = []
|
||||
self.personality = None
|
||||
|
||||
if self.config.binding_name is None:
|
||||
ASCIIColors.warning(f"No binding selected")
|
||||
ASCIIColors.info("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_binding()
|
||||
|
||||
try:
|
||||
self.binding = self.load_binding()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Failed to load binding.\nReturned exception: {ex}")
|
||||
|
||||
if self.binding is not None:
|
||||
if self.config.model_name is None:
|
||||
ASCIIColors.warning(f"No model selected")
|
||||
print("Please select a valid binding")
|
||||
self.menu.select_model()
|
||||
try:
|
||||
self.model = self.load_model()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Failed to load model.\nReturned exception: {ex}")
|
||||
|
||||
self.mount_personalities()
|
||||
|
||||
|
||||
def trace_exception(self, ex):
|
||||
# Catch the exception and get the traceback as a list of strings
|
||||
traceback_lines = traceback.format_exception(type(ex), ex, ex.__traceback__)
|
||||
|
||||
# Join the traceback lines into a single string
|
||||
traceback_text = ''.join(traceback_lines)
|
||||
ASCIIColors.error(traceback_text)
|
||||
|
||||
def load_binding(self):
|
||||
try:
|
||||
binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print(f"Couldn't find binding. Please verify your configuration file at {self.configuration_path} or use the next menu to select a valid binding")
|
||||
print(f"Trying to reinstall binding")
|
||||
binding = BindingBuilder().build_binding(self.config, self.lollms_paths,installation_option=InstallOption.FORCE_INSTALL)
|
||||
return binding
|
||||
|
||||
def load_model(self):
|
||||
try:
|
||||
model = ModelBuilder(self.binding).get_model()
|
||||
for personality in self.mounted_personalities:
|
||||
if personality is not None:
|
||||
personality.model = model
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load model. Please verify your configuration file at {self.lollms_paths.personal_configuration_path} or use the next menu to select a valid model")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_model_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
model = None
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def mount_personality(self, id:int):
|
||||
try:
|
||||
self.personality = PersonalityBuilder(self.lollms_paths, self.config, self.model).build_personality(id)
|
||||
self.config.active_personality_id=len(self.config.personalities)-1
|
||||
if self.personality.model is not None:
|
||||
self.cond_tk = self.personality.model.tokenize(self.personality.personality_conditioning)
|
||||
self.n_cond_tk = len(self.cond_tk)
|
||||
ASCIIColors.success(f"Personality {self.personality.name} mounted successfully")
|
||||
else:
|
||||
ASCIIColors.success(f"Personality {self.personality.name} mounted successfully but no model is selected")
|
||||
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {self.lollms_paths.personal_configuration_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
self.trace_exception(ex)
|
||||
ASCIIColors.error(f"{self.config.get_personality_path_infos()}")
|
||||
self.personality = None
|
||||
self.mounted_personalities.append(self.personality)
|
||||
return self.personality
|
||||
|
||||
def mount_personalities(self):
|
||||
self.mounted_personalities = []
|
||||
to_remove = []
|
||||
for i in range(len(self.config["personalities"])):
|
||||
p = self.mount_personality(i)
|
||||
if p is None:
|
||||
to_remove.append(i)
|
||||
to_remove.sort(reverse=True)
|
||||
for i in to_remove:
|
||||
self.unmount_personality(i)
|
||||
|
||||
|
||||
def unmount_personality(self, id:int)->bool:
|
||||
if id<len(self.config.personalities):
|
||||
del self.config.personalities[id]
|
||||
del self.mounted_personalities[id]
|
||||
if self.config.active_personality_id>=id:
|
||||
self.config.active_personality_id-=1
|
||||
|
||||
self.config.save_config()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def select_personality(self, id:int):
|
||||
if id<len(self.config.personalities):
|
||||
self.config.active_personality_id = id
|
||||
self.personality = self.mount_personalities[id]
|
||||
self.config.save_config()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def load_personality(self):
|
||||
try:
|
||||
personality = PersonalityBuilder(self.lollms_paths, self.config, self.model).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {self.configuration_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
personality = None
|
||||
return personality
|
||||
|
||||
@staticmethod
|
||||
def reset_paths(lollms_paths:LollmsPaths):
|
||||
lollms_paths.resetPaths()
|
||||
|
||||
@staticmethod
|
||||
def reset_all_installs(lollms_paths:LollmsPaths):
|
||||
ASCIIColors.info("Removeing all configuration files to force reinstall")
|
||||
ASCIIColors.info(f"Searching files from {lollms_paths.personal_configuration_path}")
|
||||
for file_path in lollms_paths.personal_configuration_path.iterdir():
|
||||
if file_path.name!=f"{lollms_paths.tool_prefix}local_config.yaml" and file_path.suffix.lower()==".yaml":
|
||||
file_path.unlink()
|
||||
ASCIIColors.info(f"Deleted file: {file_path}")
|
@ -4,269 +4,14 @@ from lollms.personality import MSG_TYPE, PersonalityBuilder
|
||||
from lollms.main_config import LOLLMSConfig
|
||||
from lollms.helpers import ASCIIColors
|
||||
from lollms.paths import LollmsPaths
|
||||
from lollms.app import LollmsApplication
|
||||
from lollms.terminal import MainMenu
|
||||
|
||||
from pathlib import Path
|
||||
from tqdm import tqdm
|
||||
import pkg_resources
|
||||
import argparse
|
||||
import yaml
|
||||
import sys
|
||||
|
||||
class LollmsApplication:
|
||||
def __init__(self, config:LOLLMSConfig, lollms_paths:LollmsPaths) -> None:
|
||||
self.config = config
|
||||
self.lollms_paths = lollms_paths
|
||||
def load_binding(self):
|
||||
pass
|
||||
def load_model(self):
|
||||
pass
|
||||
def load_personality(self):
|
||||
pass
|
||||
|
||||
def reset_paths(lollms_paths:LollmsPaths):
|
||||
lollms_paths.resetPaths()
|
||||
|
||||
def reset_all_installs(lollms_paths:LollmsPaths):
|
||||
ASCIIColors.info("Removeing all configuration files to force reinstall")
|
||||
ASCIIColors.info(f"Searching files from {lollms_paths.personal_configuration_path}")
|
||||
for file_path in lollms_paths.personal_configuration_path.iterdir():
|
||||
if file_path.name!=f"{lollms_paths.tool_prefix}local_config.yaml" and file_path.suffix.lower()==".yaml":
|
||||
file_path.unlink()
|
||||
ASCIIColors.info(f"Deleted file: {file_path}")
|
||||
|
||||
class MainMenu:
|
||||
def __init__(self, lollms_app:LollmsApplication):
|
||||
self.binding_infs = []
|
||||
self.lollms_app = lollms_app
|
||||
|
||||
def show_logo(self):
|
||||
print(f"{ASCIIColors.color_bright_yellow}")
|
||||
print(" ___ ___ ___ ___ ___ ___ ")
|
||||
print(" /\__\ /\ \ /\__\ /\__\ /\__\ /\ \ ")
|
||||
print(" /:/ / /::\ \ /:/ / /:/ / /::| | /::\ \ ")
|
||||
print(" /:/ / /:/\:\ \ /:/ / /:/ / /:|:| | /:/\ \ \ ")
|
||||
print(" /:/ / /:/ \:\ \ /:/ / /:/ / /:/|:|__|__ _\:\~\ \ \ ")
|
||||
print(" /:/__/ /:/__/ \:\__\ /:/__/ /:/__/ /:/ |::::\__\ /\ \:\ \ \__\ ")
|
||||
print(" \:\ \ \:\ \ /:/ / \:\ \ \:\ \ \/__/~~/:/ / \:\ \:\ \/__/ ")
|
||||
print(" \:\ \ \:\ /:/ / \:\ \ \:\ \ /:/ / \:\ \:\__\ ")
|
||||
print(" \:\ \ \:\/:/ / \:\ \ \:\ \ /:/ / \:\/:/ / ")
|
||||
print(" \:\__\ \::/ / \:\__\ \:\__\ /:/ / \::/ / ")
|
||||
print(" \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ ")
|
||||
|
||||
|
||||
|
||||
|
||||
print(f"{ASCIIColors.color_reset}")
|
||||
print(f"{ASCIIColors.color_red}Version: {ASCIIColors.color_green}{pkg_resources.get_distribution('lollms').version}")
|
||||
print(f"{ASCIIColors.color_red}By : {ASCIIColors.color_green}ParisNeo")
|
||||
print(f"{ASCIIColors.color_reset}")
|
||||
|
||||
def show_commands_list(self):
|
||||
print()
|
||||
print("Commands:")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} menu: shows main menu")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} help: shows this info")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} reset: resets the context")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} <empty prompt>: forces the model to continue generating")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} context_infos: current context size and space left before cropping")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} start_log: starts logging the discussion to a text file")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} stop_log: stops logging the discussion to a text file")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} send_file: uploads a file to the AI")
|
||||
print(f" {ASCIIColors.color_red}└{ASCIIColors.color_reset} exit: exists the console")
|
||||
|
||||
if self.lollms_app.personality.help !="":
|
||||
print(f"Personality help:")
|
||||
print(f"{self.lollms_app.personality.help}")
|
||||
|
||||
|
||||
|
||||
def show_menu(self, options):
|
||||
print("Menu:")
|
||||
for index, option in enumerate(options):
|
||||
print(f"{ASCIIColors.color_green}{index + 1} -{ASCIIColors.color_reset} {option}")
|
||||
choice = input("Enter your choice: ")
|
||||
return int(choice) if choice.isdigit() else -1
|
||||
|
||||
def select_binding(self):
|
||||
bindings_list = []
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current binding: {ASCIIColors.color_reset}{self.lollms_app.config['binding_name']}")
|
||||
for p in self.lollms_app.lollms_paths.bindings_zoo_path.iterdir():
|
||||
if p.is_dir() and not p.stem.startswith("."):
|
||||
with open(p/"binding_card.yaml", "r") as f:
|
||||
card = yaml.safe_load(f)
|
||||
with open(p/"models.yaml", "r") as f:
|
||||
models = yaml.safe_load(f)
|
||||
is_installed = (self.lollms_app.lollms_paths.personal_configuration_path/f"binding_{p.name}.yaml").exists()
|
||||
entry=f"{ASCIIColors.color_green if is_installed else ''}{'*' if self.lollms_app.config['binding_name']==card['name'] else ''} {card['name']} (by {card['author']})"
|
||||
bindings_list.append(entry)
|
||||
entry={
|
||||
"name":p.name,
|
||||
"card":card,
|
||||
"models":models,
|
||||
"installed": is_installed
|
||||
}
|
||||
self.binding_infs.append(entry)
|
||||
bindings_list += ["Back"]
|
||||
choice = self.show_menu(bindings_list)
|
||||
if 1 <= choice <= len(bindings_list)-1:
|
||||
print(f"You selected binding: {ASCIIColors.color_green}{self.binding_infs[choice - 1]['name']}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config['binding_name']=self.binding_infs[choice - 1]['name']
|
||||
self.lollms_app.load_binding()
|
||||
self.lollms_app.config['model_name']=None
|
||||
self.lollms_app.config.save_config()
|
||||
elif choice <= len(bindings_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def select_model(self):
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current binding: {ASCIIColors.color_reset}{self.lollms_app.config['binding_name']}")
|
||||
print(f"{ASCIIColors.color_green}Current model: {ASCIIColors.color_reset}{self.lollms_app.config['model_name']}")
|
||||
|
||||
models_dir:Path = (self.lollms_app.lollms_paths.personal_models_path/self.lollms_app.config['binding_name'])
|
||||
models_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
models_list = [v for v in self.lollms_app.binding.list_models(self.lollms_app.config)] + ["Install model", "Change binding", "Back"]
|
||||
choice = self.show_menu(models_list)
|
||||
if 1 <= choice <= len(models_list)-3:
|
||||
print(f"You selected model: {ASCIIColors.color_green}{models_list[choice - 1]}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config['model_name']=models_list[choice - 1]
|
||||
self.lollms_app.config.save_config()
|
||||
self.lollms_app.load_model()
|
||||
elif choice <= len(models_list)-2:
|
||||
self.install_model()
|
||||
elif choice <= len(models_list)-1:
|
||||
self.select_binding()
|
||||
self.select_model()
|
||||
elif choice <= len(models_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def install_model(self):
|
||||
|
||||
models_list = ["Install model from internet","Install model from local file","Back"]
|
||||
choice = self.show_menu(models_list)
|
||||
if 1 <= choice <= len(models_list)-2:
|
||||
url = input("Give a URL to the model to be downloaded :")
|
||||
def progress_callback(blocks, block_size, total_size):
|
||||
tqdm_bar.total=total_size
|
||||
tqdm_bar.update(block_size)
|
||||
|
||||
# Usage example
|
||||
with tqdm(total=100, unit="%", desc="Download Progress", ncols=80) as tqdm_bar:
|
||||
self.lollms_app.config.download_model(url,self.lollms_app.binding, progress_callback)
|
||||
self.select_model()
|
||||
elif choice <= len(models_list)-1:
|
||||
path = Path(input("Give a path to the model to be used on your PC:"))
|
||||
if path.exists():
|
||||
self.lollms_app.config.reference_model(path)
|
||||
self.select_model()
|
||||
elif choice <= len(models_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def select_personality(self):
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current personality: {ASCIIColors.color_reset}{self.lollms_app.config['personalities'][self.lollms_app.config['active_personality_id']]}")
|
||||
personality_languages = [p.stem for p in self.lollms_app.lollms_paths.personalities_zoo_path.iterdir() if p.is_dir()] + ["Back"]
|
||||
print("Select language")
|
||||
choice = self.show_menu(personality_languages)
|
||||
if 1 <= choice <= len(personality_languages)-1:
|
||||
language = personality_languages[choice - 1]
|
||||
print(f"You selected language: {ASCIIColors.color_green}{language}{ASCIIColors.color_reset}")
|
||||
personality_categories = [p.stem for p in (self.lollms_app.lollms_paths.personalities_zoo_path/language).iterdir() if p.is_dir()]+["Back"]
|
||||
print("Select category")
|
||||
choice = self.show_menu(personality_categories)
|
||||
if 1 <= choice <= len(personality_categories)-1:
|
||||
category = personality_categories[choice - 1]
|
||||
print(f"You selected category: {ASCIIColors.color_green}{category}{ASCIIColors.color_reset}")
|
||||
personality_names = [p.stem for p in (self.lollms_app.lollms_paths.personalities_zoo_path/language/category).iterdir() if p.is_dir()]+["Back"]
|
||||
print("Select personality")
|
||||
choice = self.show_menu(personality_names)
|
||||
if 1 <= choice <= len(personality_names)-1:
|
||||
name = personality_names[choice - 1]
|
||||
print(f"You selected personality: {ASCIIColors.color_green}{name}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config["personalities"]=[f"{language}/{category}/{name}"]
|
||||
self.lollms_app.load_personality()
|
||||
self.lollms_app.config.save_config()
|
||||
print("Personality saved successfully!")
|
||||
elif 1 <= choice <= len(personality_names):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
elif 1 <= choice <= len(personality_categories):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
elif 1 <= choice <= len(personality_languages):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def reinstall_binding(self):
|
||||
lollms_app = self.lollms_app
|
||||
try:
|
||||
lollms_app.binding = BindingBuilder().build_binding(lollms_app.config, lollms_app.lollms_paths,InstallOption.FORCE_INSTALL)
|
||||
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")
|
||||
self.select_binding()
|
||||
|
||||
def reinstall_personality(self):
|
||||
lollms_app = self.lollms_app
|
||||
try:
|
||||
lollms_app.personality = PersonalityBuilder(lollms_app.lollms_paths, lollms_app.config, lollms_app.model, installation_option=InstallOption.FORCE_INSTALL).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {lollms_app.configuration_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{lollms_app.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.select_model()
|
||||
|
||||
def main_menu(self):
|
||||
while True:
|
||||
print("\nMain Menu:")
|
||||
print(f"{ASCIIColors.color_green}1 -{ASCIIColors.color_reset} Select Binding")
|
||||
print(f"{ASCIIColors.color_green}2 -{ASCIIColors.color_reset} Select Model")
|
||||
print(f"{ASCIIColors.color_green}3 -{ASCIIColors.color_reset} Select Personality")
|
||||
print(f"{ASCIIColors.color_green}4 -{ASCIIColors.color_reset} Reinstall current Binding")
|
||||
print(f"{ASCIIColors.color_green}5 -{ASCIIColors.color_reset} Reinstall current Personality")
|
||||
print(f"{ASCIIColors.color_green}6 -{ASCIIColors.color_reset} Reset all installs")
|
||||
print(f"{ASCIIColors.color_green}7 -{ASCIIColors.color_reset} Reset paths")
|
||||
print(f"{ASCIIColors.color_green}0 -{ASCIIColors.color_reset} Back to app")
|
||||
print(f"{ASCIIColors.color_green}-1 -{ASCIIColors.color_reset} Help")
|
||||
print(f"{ASCIIColors.color_green}-2 -{ASCIIColors.color_reset} Exit app")
|
||||
choice = input("Enter your choice: ").strip()
|
||||
if choice == "1":
|
||||
self.select_binding()
|
||||
elif choice == "2":
|
||||
self.select_model()
|
||||
elif choice == "3":
|
||||
self.select_personality()
|
||||
elif choice == "4":
|
||||
self.reinstall_binding()
|
||||
elif choice == "5":
|
||||
self.reinstall_personality()
|
||||
elif choice == "6":
|
||||
reset_all_installs()
|
||||
elif choice == "6":
|
||||
reset_paths()
|
||||
|
||||
elif choice == "0":
|
||||
print("Back to main app...")
|
||||
break
|
||||
elif choice == "-1":
|
||||
self.show_commands_list()
|
||||
elif choice == "-2":
|
||||
print("Bye")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("Invalid choice! Try again.")
|
||||
|
||||
class Conversation(LollmsApplication):
|
||||
def __init__(
|
||||
self,
|
||||
@ -277,42 +22,20 @@ class Conversation(LollmsApplication):
|
||||
show_model_infos:bool=True,
|
||||
show_welcome_message:bool=True
|
||||
):
|
||||
|
||||
# Fore it to be a path
|
||||
self.configuration_path = configuration_path
|
||||
self.is_logging = False
|
||||
self.log_file_path = ""
|
||||
|
||||
self.bot_says = ""
|
||||
|
||||
# get paths
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=False, tool_prefix="lollms_server_")
|
||||
|
||||
# Configuration loading part
|
||||
config = LOLLMSConfig.autoload(lollms_paths, configuration_path)
|
||||
|
||||
super().__init__(config, lollms_paths=lollms_paths)
|
||||
|
||||
# Build menu
|
||||
self.menu = MainMenu(self)
|
||||
|
||||
|
||||
# load binding
|
||||
self.load_binding()
|
||||
|
||||
if self.config.model_name is None:
|
||||
self.menu.select_model()
|
||||
|
||||
# Load model
|
||||
self.load_model()
|
||||
# cfg.binding_name = llm_binding.binding_folder_name
|
||||
# cfg.model_name = model_name
|
||||
|
||||
# Load personality
|
||||
try:
|
||||
self.load_personality()
|
||||
except Exception as ex:
|
||||
print(f"No personality selected. Please select one from the zoo. {ex}")
|
||||
self.menu.select_personality()
|
||||
super().__init__("lollms-console",config, lollms_paths)
|
||||
|
||||
if show_logo:
|
||||
self.menu.show_logo()
|
||||
@ -321,18 +44,21 @@ class Conversation(LollmsApplication):
|
||||
|
||||
if show_personality_infos:
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}-----------------------------------------------------------------")
|
||||
print(f"{ASCIIColors.color_green}Current personality : {ASCIIColors.color_reset}{self.personality}")
|
||||
print(f"{ASCIIColors.color_green}Version : {ASCIIColors.color_reset}{self.personality.version}")
|
||||
print(f"{ASCIIColors.color_green}Author : {ASCIIColors.color_reset}{self.personality.author}")
|
||||
print(f"{ASCIIColors.color_green}Description : {ASCIIColors.color_reset}{self.personality.personality_description}")
|
||||
print(f"{ASCIIColors.color_green}-----------------------------------------------------------------")
|
||||
print()
|
||||
|
||||
if show_model_infos:
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}-----------------------------------------------------------------")
|
||||
print(f"{ASCIIColors.color_green}Current binding : {ASCIIColors.color_reset}{self.config['binding_name']}")
|
||||
print(f"{ASCIIColors.color_green}Current model : {ASCIIColors.color_reset}{self.config['model_name']}")
|
||||
print(f"{ASCIIColors.color_green}Personal data path : {ASCIIColors.color_reset}{self.lollms_paths.personal_path}")
|
||||
|
||||
print(f"{ASCIIColors.color_green}-----------------------------------------------------------------")
|
||||
print()
|
||||
|
||||
|
||||
@ -398,45 +124,6 @@ Participating personalities:
|
||||
|
||||
|
||||
|
||||
def load_binding(self):
|
||||
if self.config.binding_name is None:
|
||||
print(f"No bounding selected")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_binding()
|
||||
# cfg.download_model(url)
|
||||
else:
|
||||
try:
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print(f"Couldn't find binding. Please verify your configuration file at {self.configuration_path} or use the next menu to select a valid binding")
|
||||
print(f"Trying to reinstall binding")
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths,installation_option=InstallOption.FORCE_INSTALL)
|
||||
self.menu.select_binding()
|
||||
|
||||
def load_model(self):
|
||||
try:
|
||||
self.model = ModelBuilder(self.binding).get_model()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load model. Please verify your configuration file at {self.configuration_path} or use the next menu to select a valid model")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_model_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_model()
|
||||
|
||||
|
||||
def load_personality(self):
|
||||
try:
|
||||
self.personality = PersonalityBuilder(self.lollms_paths, self.config, self.model).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {self.configuration_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_model()
|
||||
self.cond_tk = self.personality.model.tokenize(self.personality.personality_conditioning)
|
||||
self.n_cond_tk = len(self.cond_tk)
|
||||
|
||||
def reset_context(self):
|
||||
if self.personality.include_welcome_message_in_disucssion:
|
||||
full_discussion = (
|
||||
@ -605,7 +292,7 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.reset_installs:
|
||||
reset_all_installs()
|
||||
LollmsApplication.reset_all_installs()
|
||||
|
||||
if args.reset_personal_path:
|
||||
LollmsPaths.reset_configs()
|
||||
|
40
lollms/extension.py
Normal file
40
lollms/extension.py
Normal file
@ -0,0 +1,40 @@
|
||||
# File : extension.py
|
||||
# Author : ParisNeo
|
||||
# Description :
|
||||
# This is the main class to be imported by the extension
|
||||
# it gives your code access to the model, the callback functions, the model conditionning etc
|
||||
from lollms.helpers import ASCIIColors
|
||||
from lollms.config import BaseConfig
|
||||
from enum import Enum
|
||||
|
||||
|
||||
__author__ = "parisneo"
|
||||
__github__ = "https://github.com/ParisNeo/lollms-webui"
|
||||
__copyright__ = "Copyright 2023, "
|
||||
__license__ = "Apache 2.0"
|
||||
|
||||
|
||||
class EXTENSION_TYPE(Enum):
|
||||
EXTENSION_TYPE_STAND_ALONE = 0 # An extension that has access to the current personality and model but has an independant
|
||||
|
||||
|
||||
class Extension():
|
||||
def __init__(self, metadata_file_path:str, app) -> None:
|
||||
self.app = app
|
||||
self.metadata_file_path = metadata_file_path
|
||||
self.config = BaseConfig(file_path=metadata_file_path)
|
||||
self.config.load_config()
|
||||
|
||||
def install(self):
|
||||
"""
|
||||
Installation procedure (to be implemented)
|
||||
"""
|
||||
ASCIIColors.blue("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
||||
ASCIIColors.red(f"Installing {self.binding_folder_name}")
|
||||
ASCIIColors.blue("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
||||
|
||||
def get_ui():
|
||||
"""
|
||||
Get user interface of the extension
|
||||
"""
|
||||
return "<p>This is a ui extension template</p>"
|
@ -74,6 +74,15 @@ class LollmsPaths:
|
||||
self.personal_log_path.mkdir(parents=True, exist_ok=True)
|
||||
self.personal_uploads_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if not self.bindings_zoo_path.exists():
|
||||
# Clone the repository to the target path
|
||||
ASCIIColors.info("No bindings found in your personal space.\nCloning the personalities zoo")
|
||||
subprocess.run(["git", "clone", bindings_zoo_repo, self.bindings_zoo_path])
|
||||
else:
|
||||
# Pull the repository if it already exists
|
||||
ASCIIColors.info("Bindings zoo found in your personal space.\nPulling last personalities zoo")
|
||||
subprocess.run(["git", "-C", self.bindings_zoo_path, "pull"])
|
||||
|
||||
if not self.personalities_zoo_path.exists():
|
||||
# Clone the repository to the target path
|
||||
ASCIIColors.info("No personalities found in your personal space.\nCloning the personalities zoo")
|
||||
@ -83,15 +92,6 @@ class LollmsPaths:
|
||||
ASCIIColors.info("Personalities zoo found in your personal space.\nPulling last personalities zoo")
|
||||
subprocess.run(["git", "-C", self.personalities_zoo_path, "pull"])
|
||||
|
||||
if not self.bindings_zoo_path.exists():
|
||||
# Clone the repository to the target path
|
||||
ASCIIColors.info("No personalities found in your personal space.\nCloning the personalities zoo")
|
||||
subprocess.run(["git", "clone", bindings_zoo_repo, self.bindings_zoo_path])
|
||||
else:
|
||||
# Pull the repository if it already exists
|
||||
ASCIIColors.info("Personalities zoo found in your personal space.\nPulling last personalities zoo")
|
||||
subprocess.run(["git", "-C", self.bindings_zoo_path, "pull"])
|
||||
|
||||
|
||||
def copy_default_config(self):
|
||||
local_config_path = self.personal_configuration_path / f"{self.tool_prefix}local_config.yaml"
|
||||
|
@ -1072,13 +1072,19 @@ class PersonalityBuilder:
|
||||
self.installation_option = installation_option
|
||||
|
||||
|
||||
def build_personality(self):
|
||||
if self.config["active_personality_id"]>=len(self.config["personalities"]):
|
||||
ASCIIColors.warning("Personality ID was out of range. Resetting to 0.")
|
||||
self.config["active_personality_id"]=0
|
||||
if len(self.config["personalities"][self.config["active_personality_id"]].split("/"))==3:
|
||||
def build_personality(self, id:int=None):
|
||||
if id is None:
|
||||
id = self.config["active_personality_id"]
|
||||
if self.config["active_personality_id"]>=len(self.config["personalities"]):
|
||||
ASCIIColors.warning("Personality ID was out of range. Resetting to 0.")
|
||||
self.config["active_personality_id"]=0
|
||||
id = 0
|
||||
else:
|
||||
if id>len(self.config["personalities"]):
|
||||
id = len(self.config["personalities"])-1
|
||||
if len(self.config["personalities"][id].split("/"))==3:
|
||||
self.personality = AIPersonality(
|
||||
self.lollms_paths.personalities_zoo_path / self.config["personalities"][self.config["active_personality_id"]],
|
||||
self.lollms_paths.personalities_zoo_path / self.config["personalities"][id],
|
||||
self.lollms_paths,
|
||||
self.config,
|
||||
self.model,
|
||||
@ -1086,7 +1092,7 @@ class PersonalityBuilder:
|
||||
)
|
||||
else:
|
||||
self.personality = AIPersonality(
|
||||
self.config["personalities"][self.config["active_personality_id"]],
|
||||
self.config["personalities"][id],
|
||||
self.lollms_paths,
|
||||
self.config,
|
||||
self.model,
|
||||
|
128
lollms/server.py
128
lollms/server.py
@ -11,6 +11,7 @@ from lollms.helpers import ASCIIColors
|
||||
from lollms.console import MainMenu
|
||||
from lollms.paths import LollmsPaths
|
||||
from lollms.console import MainMenu
|
||||
from lollms.app import LollmsApplication
|
||||
from typing import List, Tuple
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
@ -28,39 +29,24 @@ def reset_all_installs(lollms_paths:LollmsPaths):
|
||||
ASCIIColors.info(f"Deleted file: {file_path}")
|
||||
|
||||
|
||||
class LoLLMsServer:
|
||||
class LoLLMsServer(LollmsApplication):
|
||||
def __init__(self):
|
||||
|
||||
|
||||
host = "localhost"
|
||||
port = "9601"
|
||||
self.clients = {}
|
||||
self.current_binding = None
|
||||
self.active_model = None
|
||||
self.model = None
|
||||
self.personalities = []
|
||||
self.answer = ['']
|
||||
self.is_ready = True
|
||||
|
||||
|
||||
self.lollms_paths = LollmsPaths.find_paths(force_local=False, tool_prefix="lollms_server_")
|
||||
self.menu = MainMenu(self)
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--host', '-hst', default=host, help='Host name')
|
||||
parser.add_argument('--port', '-prt', default=port, help='Port number')
|
||||
|
||||
parser.add_argument('--config', '-cfg', default=None, help='Path to the configuration file')
|
||||
parser.add_argument('--bindings_path', '-bp', default=str(self.lollms_paths.bindings_zoo_path),
|
||||
help='The path to the Bindings folder')
|
||||
parser.add_argument('--personalities_path', '-pp',
|
||||
default=str(self.lollms_paths.personalities_zoo_path),
|
||||
help='The path to the personalities folder')
|
||||
parser.add_argument('--models_path', '-mp', default=str(self.lollms_paths.personal_models_path),
|
||||
help='The path to the models folder')
|
||||
|
||||
parser.add_argument('--binding_name', '-b', default=None,
|
||||
help='Binding to be used by default')
|
||||
parser.add_argument('--model_name', '-m', default=None,
|
||||
help='Model name')
|
||||
parser.add_argument('--personality_full_name', '-p', default="personality",
|
||||
help='Personality path relative to the personalities folder (language/category/name)')
|
||||
|
||||
parser.add_argument('--reset_personal_path', action='store_true', help='Reset the personal path')
|
||||
parser.add_argument('--reset_config', action='store_true', help='Reset the configurations')
|
||||
@ -70,7 +56,7 @@ class LoLLMsServer:
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.reset_installs:
|
||||
reset_all_installs()
|
||||
self.reset_all_installs()
|
||||
|
||||
if args.reset_personal_path:
|
||||
LollmsPaths.reset_configs()
|
||||
@ -83,50 +69,15 @@ class LoLLMsServer:
|
||||
ASCIIColors.success("LOLLMS configuration reset successfully")
|
||||
except:
|
||||
ASCIIColors.success("Couldn't reset LOLLMS configuration")
|
||||
else:
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=False, tool_prefix="lollms_server_")
|
||||
|
||||
# Configuration loading part
|
||||
self.config = LOLLMSConfig.autoload(self.lollms_paths, args.config)
|
||||
config = LOLLMSConfig.autoload(lollms_paths, None)
|
||||
|
||||
|
||||
if args.binding_name:
|
||||
self.config.binding_name = args.binding_name
|
||||
|
||||
if args.model_name:
|
||||
self.config.model_name = args.model_name
|
||||
|
||||
# Recover bindings path
|
||||
self.personalities_path = Path(args.personalities_path)
|
||||
self.bindings_path = Path(args.bindings_path)
|
||||
self.models_path = Path(args.models_path)
|
||||
if self.config.binding_name is None:
|
||||
self.menu.select_binding()
|
||||
else:
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
if self.config.model_name is None:
|
||||
self.menu.select_model()
|
||||
else:
|
||||
try:
|
||||
self.active_model = self.binding.build_model()
|
||||
except Exception as ex:
|
||||
print(f"{ASCIIColors.color_red}Couldn't load model Please select a valid model{ASCIIColors.color_reset}")
|
||||
print(f"{ASCIIColors.color_red}{ex}{ASCIIColors.color_reset}")
|
||||
self.menu.select_model()
|
||||
|
||||
for p in self.config.personalities:
|
||||
personality = AIPersonality(
|
||||
self.config.lollms_paths.personalities_zoo_path/p,
|
||||
self.lollms_paths,
|
||||
self.config,
|
||||
self.active_model
|
||||
)
|
||||
self.personalities.append(personality)
|
||||
|
||||
if self.config.active_personality_id>len(self.personalities):
|
||||
self.config.active_personality_id = 0
|
||||
self.active_personality = self.personalities[self.config.active_personality_id]
|
||||
super().__init__("lollms-server", config, lollms_paths)
|
||||
|
||||
self.menu.show_logo()
|
||||
|
||||
self.app = Flask("LoLLMsServer")
|
||||
#self.app.config['SECRET_KEY'] = 'lollmssecret'
|
||||
CORS(self.app) # Enable CORS for all routes
|
||||
@ -144,45 +95,6 @@ class LoLLMsServer:
|
||||
self.run(args.host, args.port)
|
||||
|
||||
|
||||
def load_binding(self):
|
||||
if self.config.binding_name is None:
|
||||
print(f"No bounding selected")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_binding()
|
||||
# cfg.download_model(url)
|
||||
else:
|
||||
try:
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print(f"Couldn't find binding. Please verify your configuration file at {self.config.file_path} or use the next menu to select a valid binding")
|
||||
print(f"Trying to reinstall binding")
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths, InstallOption.FORCE_INSTALL)
|
||||
self.menu.select_binding()
|
||||
|
||||
def load_model(self):
|
||||
try:
|
||||
self.active_model = ModelBuilder(self.binding).get_model()
|
||||
ASCIIColors.success("Model loaded successfully")
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load model.")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_model_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_model()
|
||||
|
||||
def load_personality(self):
|
||||
try:
|
||||
self.personality = PersonalityBuilder(self.lollms_paths, self.config, self.model).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality.")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_model()
|
||||
self.cond_tk = self.personality.model.tokenize(self.personality.personality_conditioning)
|
||||
self.n_cond_tk = len(self.cond_tk)
|
||||
|
||||
def initialize_routes(self):
|
||||
@self.socketio.on('connect')
|
||||
def handle_connect():
|
||||
@ -369,7 +281,7 @@ class LoLLMsServer:
|
||||
self.cp_config = copy.deepcopy(self.config)
|
||||
self.cp_config["model_name"] = data['model_name']
|
||||
try:
|
||||
self.active_model = self.binding.build_model()
|
||||
self.model = self.binding.build_model()
|
||||
emit('select_model', {'success':True, 'model_name': model_name}, room=request.sid)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
@ -383,7 +295,7 @@ class LoLLMsServer:
|
||||
personality_path,
|
||||
self.lollms_paths,
|
||||
self.config,
|
||||
self.active_model
|
||||
self.model
|
||||
)
|
||||
self.personalities.append(personality)
|
||||
self.config["personalities"].append(personality_path)
|
||||
@ -413,13 +325,13 @@ class LoLLMsServer:
|
||||
@self.socketio.on('tokenize')
|
||||
def tokenize(data):
|
||||
prompt = data['prompt']
|
||||
tk = self.active_model.tokenize(prompt)
|
||||
tk = self.model.tokenize(prompt)
|
||||
emit("tokenized", {"tokens":tk})
|
||||
|
||||
@self.socketio.on('detokenize')
|
||||
def detokenize(data):
|
||||
prompt = data['prompt']
|
||||
txt = self.active_model.detokenize(prompt)
|
||||
txt = self.model.detokenize(prompt)
|
||||
emit("detokenized", {"text":txt})
|
||||
|
||||
@self.socketio.on('cancel_generation')
|
||||
@ -442,7 +354,7 @@ class LoLLMsServer:
|
||||
return
|
||||
def generate_text():
|
||||
self.is_ready = False
|
||||
model = self.active_model
|
||||
model = self.model
|
||||
self.clients[client_id]["is_generating"]=True
|
||||
self.clients[client_id]["requested_stop"]=False
|
||||
prompt = data['prompt']
|
||||
@ -462,7 +374,7 @@ class LoLLMsServer:
|
||||
self.answer = {"full_text":""}
|
||||
def callback(text, message_type: MSG_TYPE):
|
||||
if message_type == MSG_TYPE.MSG_TYPE_CHUNK:
|
||||
ASCIIColors.success(f"generated:{len(self.answer['full_text'])} words", end='\r')
|
||||
ASCIIColors.success(f"generated:{len(self.answer['full_text'].split())} words", end='\r')
|
||||
self.answer["full_text"] = self.answer["full_text"] + text
|
||||
self.socketio.emit('text_chunk', {'chunk': text, 'type':MSG_TYPE.MSG_TYPE_CHUNK.value}, room=client_id)
|
||||
self.socketio.sleep(0)
|
||||
@ -479,8 +391,10 @@ class LoLLMsServer:
|
||||
fd = model.detokenize(tk[-min(self.config.ctx_size-n_predicts,n_tokens):])
|
||||
|
||||
try:
|
||||
ASCIIColors.print("warm up", ASCIIColors.color_bright_cyan)
|
||||
generated_text = model.generate(fd, n_predict=n_predicts, callback=callback,
|
||||
ASCIIColors.print("warming up", ASCIIColors.color_bright_cyan)
|
||||
generated_text = model.generate(fd,
|
||||
n_predict=n_predicts,
|
||||
callback=callback,
|
||||
temperature = parameters["temperature"],
|
||||
top_k = parameters["top_k"],
|
||||
top_p = parameters["top_p"],
|
||||
@ -588,7 +502,7 @@ class LoLLMsServer:
|
||||
|
||||
def run(self, host="localhost", port="9601"):
|
||||
print(f"{ASCIIColors.color_red}Current binding (model) : {ASCIIColors.color_reset}{self.binding}")
|
||||
print(f"{ASCIIColors.color_red}Current personality : {ASCIIColors.color_reset}{self.active_personality}")
|
||||
print(f"{ASCIIColors.color_red}Current personality : {ASCIIColors.color_reset}{self.config.personalities[self.config.active_personality_id]}")
|
||||
ASCIIColors.info(f"Serving on address: http://{host}:{port}")
|
||||
|
||||
self.socketio.run(self.app, host=host, port=port)
|
||||
|
@ -9,17 +9,11 @@ import argparse
|
||||
from tqdm import tqdm
|
||||
from lollms.personality import PersonalityBuilder
|
||||
from lollms.console import MainMenu
|
||||
|
||||
def reset_all_installs(lollms_paths:LollmsPaths):
|
||||
ASCIIColors.info("Removeing all configuration files to force reinstall")
|
||||
ASCIIColors.info(f"Searching files from {lollms_paths.personal_configuration_path}")
|
||||
for file_path in lollms_paths.personal_configuration_path.iterdir():
|
||||
if file_path.name!=f"{lollms_paths.tool_prefix}local_config.yaml" and file_path.suffix.lower()==".yaml":
|
||||
file_path.unlink()
|
||||
ASCIIColors.info(f"Deleted file: {file_path}")
|
||||
from lollms.app import LollmsApplication
|
||||
|
||||
|
||||
class Settings:
|
||||
|
||||
class Settings(LollmsApplication):
|
||||
def __init__(
|
||||
self,
|
||||
configuration_path:str|Path=None,
|
||||
@ -29,46 +23,16 @@ class Settings:
|
||||
show_model_infos:bool=True,
|
||||
show_welcome_message:bool=True
|
||||
):
|
||||
|
||||
# Fore it to be a path
|
||||
self.is_logging = False
|
||||
self.log_file_path = ""
|
||||
|
||||
self.bot_says = ""
|
||||
|
||||
# get paths
|
||||
self.lollms_paths = LollmsPaths.find_paths(force_local=False, tool_prefix="lollms_server_")
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=False, tool_prefix="lollms_server_")
|
||||
ASCIIColors.yellow("------ Lollms Paths ------")
|
||||
ASCIIColors.info(self.lollms_paths)
|
||||
ASCIIColors.info(lollms_paths)
|
||||
ASCIIColors.yellow("------ ------------ ------")
|
||||
# Load maoin configuration
|
||||
config = LOLLMSConfig.autoload(lollms_paths)
|
||||
|
||||
# Build menu
|
||||
self.menu = MainMenu(self)
|
||||
|
||||
# Change configuration
|
||||
original = self.lollms_paths.default_cfg_path
|
||||
if configuration_path is None:
|
||||
local = self.lollms_paths.personal_configuration_path / f"{self.lollms_paths.tool_prefix}local_config.yaml"
|
||||
else:
|
||||
local = Path(configuration_path)
|
||||
|
||||
if not local.exists():
|
||||
shutil.copy(original, local)
|
||||
self.cfg_path = local
|
||||
|
||||
self.config = LOLLMSConfig(self.cfg_path, self.lollms_paths)
|
||||
# load binding
|
||||
if self.config.binding_name is not None:
|
||||
self.load_binding()
|
||||
# Load model
|
||||
if self.config.model_name is not None:
|
||||
self.load_model()
|
||||
|
||||
# Load personality
|
||||
try:
|
||||
self.load_personality()
|
||||
except Exception as ex:
|
||||
print(f"No personality selected. Please select one from the zoo. {ex}")
|
||||
self.menu.select_personality()
|
||||
super().__init__("lollms-settings", config, lollms_paths)
|
||||
|
||||
if show_logo:
|
||||
self.menu.show_logo()
|
||||
@ -145,43 +109,6 @@ Participating personalities:
|
||||
self.is_logging = False
|
||||
|
||||
|
||||
|
||||
def load_binding(self):
|
||||
if self.config.binding_name is None:
|
||||
print(f"No bounding selected")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_binding()
|
||||
# cfg.download_model(url)
|
||||
else:
|
||||
try:
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print(f"Couldn't find binding. Please verify your configuration file at {self.cfg_path} or use the next menu to select a valid binding")
|
||||
print(f"Trying to reinstall binding")
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths,installation_option=InstallOption.FORCE_INSTALL)
|
||||
self.menu.select_binding()
|
||||
|
||||
def load_model(self):
|
||||
try:
|
||||
self.model = ModelBuilder(self.binding).get_model()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load model. Please verify your configuration file at {self.cfg_path} or use the next menu to select a valid model")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_model_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.menu.select_model()
|
||||
|
||||
|
||||
def load_personality(self):
|
||||
try:
|
||||
self.personality = PersonalityBuilder(self.lollms_paths, self.config, self.model).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {self.cfg_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{self.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
|
||||
def reset_context(self):
|
||||
if self.personality.include_welcome_message_in_disucssion:
|
||||
full_discussion = (
|
||||
@ -248,7 +175,7 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.reset_installs:
|
||||
reset_all_installs()
|
||||
LollmsApplication.reset_all_installs()
|
||||
|
||||
if args.reset_personal_path:
|
||||
LollmsPaths.reset_configs()
|
||||
|
332
lollms/terminal.py
Normal file
332
lollms/terminal.py
Normal file
@ -0,0 +1,332 @@
|
||||
|
||||
from lollms.helpers import ASCIIColors
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from lollms.app import LollmsApplication
|
||||
|
||||
from lollms.binding import BindingBuilder
|
||||
from lollms.config import InstallOption
|
||||
from lollms.personality import PersonalityBuilder
|
||||
|
||||
from tqdm import tqdm
|
||||
import pkg_resources
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
import sys
|
||||
|
||||
class MainMenu:
|
||||
def __init__(self, lollms_app:'LollmsApplication'):
|
||||
self.binding_infs = []
|
||||
self.lollms_app = lollms_app
|
||||
|
||||
def show_logo(self):
|
||||
print(f"{ASCIIColors.color_bright_yellow}")
|
||||
print(" ___ ___ ___ ___ ___ ___ ")
|
||||
print(" /\__\ /\ \ /\__\ /\__\ /\__\ /\ \ ")
|
||||
print(" /:/ / /::\ \ /:/ / /:/ / /::| | /::\ \ ")
|
||||
print(" /:/ / /:/\:\ \ /:/ / /:/ / /:|:| | /:/\ \ \ ")
|
||||
print(" /:/ / /:/ \:\ \ /:/ / /:/ / /:/|:|__|__ _\:\~\ \ \ ")
|
||||
print(" /:/__/ /:/__/ \:\__\ /:/__/ /:/__/ /:/ |::::\__\ /\ \:\ \ \__\ ")
|
||||
print(" \:\ \ \:\ \ /:/ / \:\ \ \:\ \ \/__/~~/:/ / \:\ \:\ \/__/ ")
|
||||
print(" \:\ \ \:\ /:/ / \:\ \ \:\ \ /:/ / \:\ \:\__\ ")
|
||||
print(" \:\ \ \:\/:/ / \:\ \ \:\ \ /:/ / \:\/:/ / ")
|
||||
print(" \:\__\ \::/ / \:\__\ \:\__\ /:/ / \::/ / ")
|
||||
print(" \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ ")
|
||||
|
||||
|
||||
|
||||
|
||||
print(f"{ASCIIColors.color_reset}")
|
||||
print(f"{ASCIIColors.color_red}Version: {ASCIIColors.color_green}{pkg_resources.get_distribution('lollms').version}")
|
||||
print(f"{ASCIIColors.color_red}By : {ASCIIColors.color_green}ParisNeo")
|
||||
print(f"{ASCIIColors.color_reset}")
|
||||
|
||||
def show_commands_list(self):
|
||||
print()
|
||||
print("Commands:")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} menu: shows main menu")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} help: shows this info")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} reset: resets the context")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} <empty prompt>: forces the model to continue generating")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} context_infos: current context size and space left before cropping")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} start_log: starts logging the discussion to a text file")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} stop_log: stops logging the discussion to a text file")
|
||||
print(f" {ASCIIColors.color_red}├{ASCIIColors.color_reset} send_file: uploads a file to the AI")
|
||||
print(f" {ASCIIColors.color_red}└{ASCIIColors.color_reset} exit: exists the console")
|
||||
|
||||
if self.lollms_app.personality:
|
||||
if self.lollms_app.personality.help !="":
|
||||
print(f"Personality help:")
|
||||
print(f"{self.lollms_app.personality.help}")
|
||||
|
||||
|
||||
|
||||
def show_menu(self, options, title="Menu:", selection:int=None):
|
||||
ASCIIColors.yellow(title)
|
||||
for index, option in enumerate(options):
|
||||
if selection is not None and index==selection:
|
||||
print(f"{ASCIIColors.color_green}{index + 1} - {option}{ASCIIColors.color_reset}")
|
||||
else:
|
||||
print(f"{ASCIIColors.color_green}{index + 1} -{ASCIIColors.color_reset} {option}")
|
||||
choice = input("Enter your choice: ")
|
||||
return int(choice) if choice.isdigit() else -1
|
||||
|
||||
def select_binding(self):
|
||||
bindings_list = []
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current binding: {ASCIIColors.color_reset}{self.lollms_app.config['binding_name']}")
|
||||
for p in self.lollms_app.lollms_paths.bindings_zoo_path.iterdir():
|
||||
if p.is_dir() and not p.stem.startswith("."):
|
||||
with open(p/"binding_card.yaml", "r") as f:
|
||||
card = yaml.safe_load(f)
|
||||
with open(p/"models.yaml", "r") as f:
|
||||
models = yaml.safe_load(f)
|
||||
is_installed = (self.lollms_app.lollms_paths.personal_configuration_path/f"binding_{p.name}.yaml").exists()
|
||||
entry=f"{ASCIIColors.color_green if is_installed else ''}{'*' if self.lollms_app.config['binding_name']==card['name'] else ''} {card['name']} (by {card['author']})"
|
||||
bindings_list.append(entry)
|
||||
entry={
|
||||
"name":p.name,
|
||||
"card":card,
|
||||
"models":models,
|
||||
"installed": is_installed
|
||||
}
|
||||
self.binding_infs.append(entry)
|
||||
bindings_list += ["Back"]
|
||||
choice = self.show_menu(bindings_list)
|
||||
if 1 <= choice <= len(bindings_list)-1:
|
||||
print(f"You selected binding: {ASCIIColors.color_green}{self.binding_infs[choice - 1]['name']}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config['binding_name']=self.binding_infs[choice - 1]['name']
|
||||
self.lollms_app.load_binding()
|
||||
self.lollms_app.config['model_name']=None
|
||||
self.lollms_app.config.save_config()
|
||||
elif choice <= len(bindings_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def select_model(self):
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current binding: {ASCIIColors.color_reset}{self.lollms_app.config['binding_name']}")
|
||||
print(f"{ASCIIColors.color_green}Current model: {ASCIIColors.color_reset}{self.lollms_app.config['model_name']}")
|
||||
|
||||
models_dir:Path = (self.lollms_app.lollms_paths.personal_models_path/self.lollms_app.config['binding_name'])
|
||||
models_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
models_list = [v for v in self.lollms_app.binding.list_models(self.lollms_app.config)] + ["Install model", "Change binding", "Back"]
|
||||
choice = self.show_menu(models_list)
|
||||
if 1 <= choice <= len(models_list)-3:
|
||||
print(f"You selected model: {ASCIIColors.color_green}{models_list[choice - 1]}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config['model_name']=models_list[choice - 1]
|
||||
self.lollms_app.config.save_config()
|
||||
self.lollms_app.load_model()
|
||||
elif choice <= len(models_list)-2:
|
||||
self.install_model()
|
||||
elif choice <= len(models_list)-1:
|
||||
self.select_binding()
|
||||
self.select_model()
|
||||
elif choice <= len(models_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def install_model(self):
|
||||
|
||||
models_list = ["Install model from internet","Install model from local file","Back"]
|
||||
choice = self.show_menu(models_list)
|
||||
if 1 <= choice <= len(models_list)-2:
|
||||
url = input("Give a URL to the model to be downloaded :")
|
||||
def progress_callback(blocks, block_size, total_size):
|
||||
tqdm_bar.total=total_size
|
||||
tqdm_bar.update(block_size)
|
||||
|
||||
# Usage example
|
||||
with tqdm(total=100, unit="%", desc="Download Progress", ncols=80) as tqdm_bar:
|
||||
self.lollms_app.config.download_model(url,self.lollms_app.binding, progress_callback)
|
||||
self.select_model()
|
||||
elif choice <= len(models_list)-1:
|
||||
path = Path(input("Give a path to the model to be used on your PC:"))
|
||||
if path.exists():
|
||||
self.lollms_app.config.reference_model(path)
|
||||
self.select_model()
|
||||
elif choice <= len(models_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def mount_personality(self):
|
||||
print()
|
||||
ASCIIColors.red(f"Mounted personalities:")
|
||||
for i,personality in enumerate(self.lollms_app.config['personalities']):
|
||||
if i==self.lollms_app.config['active_personality_id']:
|
||||
ASCIIColors.green(personality)
|
||||
else:
|
||||
ASCIIColors.yellow(personality)
|
||||
personality_languages = [p.stem for p in self.lollms_app.lollms_paths.personalities_zoo_path.iterdir() if p.is_dir() and not p.name.startswith(".")] + ["Back"]
|
||||
print("Select language")
|
||||
choice = self.show_menu(personality_languages)
|
||||
if 1 <= choice <= len(personality_languages)-1:
|
||||
language = personality_languages[choice - 1]
|
||||
print(f"You selected language: {ASCIIColors.color_green}{language}{ASCIIColors.color_reset}")
|
||||
personality_categories = [p.stem for p in (self.lollms_app.lollms_paths.personalities_zoo_path/language).iterdir() if p.is_dir() and not p.name.startswith(".")]+["Back"]
|
||||
print("Select category")
|
||||
choice = self.show_menu(personality_categories)
|
||||
if 1 <= choice <= len(personality_categories)-1:
|
||||
category = personality_categories[choice - 1]
|
||||
print(f"You selected category: {ASCIIColors.color_green}{category}{ASCIIColors.color_reset}")
|
||||
personality_names = [p.stem for p in (self.lollms_app.lollms_paths.personalities_zoo_path/language/category).iterdir() if p.is_dir() and not p.name.startswith(".")]+["Back"]
|
||||
print("Select personality")
|
||||
choice = self.show_menu(personality_names)
|
||||
if 1 <= choice <= len(personality_names)-1:
|
||||
name = personality_names[choice - 1]
|
||||
print(f"You selected personality: {ASCIIColors.color_green}{name}{ASCIIColors.color_reset}")
|
||||
self.lollms_app.config["personalities"].append(f"{language}/{category}/{name}")
|
||||
self.lollms_app.mount_personality(len(self.lollms_app.config["personalities"])-1)
|
||||
self.lollms_app.config.save_config()
|
||||
print("Personality mounted successfully!")
|
||||
elif 1 <= choice <= len(personality_names):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
elif 1 <= choice <= len(personality_categories):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
elif 1 <= choice <= len(personality_languages):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
def vew_mounted_personalities(self):
|
||||
ASCIIColors.info("Here is the list of mounted personalities")
|
||||
entries = self.lollms_app.config['personalities']
|
||||
for id, entry in enumerate(entries):
|
||||
if id != self.lollms_app.config.active_personality_id:
|
||||
ASCIIColors.yellow(f"{id+1} - {entry}")
|
||||
else:
|
||||
ASCIIColors.green(f"{id+1} - {entry}")
|
||||
self.show_menu(["Back"])
|
||||
|
||||
|
||||
def unmount_personality(self):
|
||||
ASCIIColors.info("Select personality to unmount")
|
||||
entries = self.lollms_app.config['personalities']+["Back"]
|
||||
try:
|
||||
choice = int(self.show_menu(entries, self.lollms_app.config['active_personality_id']))-1
|
||||
if choice<len(entries)-1:
|
||||
self.lollms_app.unmount_personality(choice)
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't uhnmount personality.\nGot this exception:{ex}")
|
||||
|
||||
def select_personality(self):
|
||||
ASCIIColors.info("Select personality to activate")
|
||||
entries = self.lollms_app.config['personalities']+["Back"]
|
||||
try:
|
||||
choice = int(self.show_menu(entries, self.lollms_app.config['active_personality_id']))-1
|
||||
if choice<len(entries)-1:
|
||||
self.lollms_app.select_personality(choice)
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't set personality.\nGot this exception:{ex}")
|
||||
|
||||
def reinstall_binding(self):
|
||||
lollms_app = self.lollms_app
|
||||
bindings_list = []
|
||||
print()
|
||||
print(f"{ASCIIColors.color_green}Current binding: {ASCIIColors.color_reset}{self.lollms_app.config['binding_name']}")
|
||||
for p in self.lollms_app.lollms_paths.bindings_zoo_path.iterdir():
|
||||
if p.is_dir() and not p.stem.startswith("."):
|
||||
with open(p/"binding_card.yaml", "r") as f:
|
||||
card = yaml.safe_load(f)
|
||||
with open(p/"models.yaml", "r") as f:
|
||||
models = yaml.safe_load(f)
|
||||
is_installed = (self.lollms_app.lollms_paths.personal_configuration_path/f"binding_{p.name}.yaml").exists()
|
||||
entry=f"{ASCIIColors.color_green if is_installed else ''}{'*' if self.lollms_app.config['binding_name']==card['name'] else ''} {card['name']} (by {card['author']})"
|
||||
bindings_list.append(entry)
|
||||
entry={
|
||||
"name":p.name,
|
||||
"card":card,
|
||||
"models":models,
|
||||
"installed": is_installed
|
||||
}
|
||||
self.binding_infs.append(entry)
|
||||
bindings_list += ["Back"]
|
||||
choice = self.show_menu(bindings_list)
|
||||
if 1 <= choice <= len(bindings_list)-1:
|
||||
print(f"You selected binding: {ASCIIColors.color_green}{self.binding_infs[choice - 1]['name']}{ASCIIColors.color_reset}")
|
||||
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)
|
||||
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")
|
||||
self.select_binding()
|
||||
|
||||
self.lollms_app.config['model_name']=None
|
||||
self.lollms_app.config.save_config()
|
||||
elif choice <= len(bindings_list):
|
||||
return
|
||||
else:
|
||||
print("Invalid choice!")
|
||||
|
||||
|
||||
|
||||
def reinstall_personality(self):
|
||||
lollms_app = self.lollms_app
|
||||
try:
|
||||
lollms_app.personality = PersonalityBuilder(lollms_app.lollms_paths, lollms_app.config, lollms_app.model, installation_option=InstallOption.FORCE_INSTALL).build_personality()
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't load personality. Please verify your configuration file at {lollms_app.configuration_path} or use the next menu to select a valid personality")
|
||||
ASCIIColors.error(f"Binding returned this exception : {ex}")
|
||||
ASCIIColors.error(f"{lollms_app.config.get_personality_path_infos()}")
|
||||
print("Please select a valid model or install a new one from a url")
|
||||
self.select_model()
|
||||
|
||||
def main_menu(self):
|
||||
while True:
|
||||
print("\nMain Menu:")
|
||||
print(f"{ASCIIColors.color_green}1 -{ASCIIColors.color_reset} Select Binding")
|
||||
print(f"{ASCIIColors.color_green}2 -{ASCIIColors.color_reset} Select Model")
|
||||
print(f"{ASCIIColors.color_green}3 -{ASCIIColors.color_reset} View mounted Personalities")
|
||||
print(f"{ASCIIColors.color_green}4 -{ASCIIColors.color_reset} Mount Personality")
|
||||
print(f"{ASCIIColors.color_green}5 -{ASCIIColors.color_reset} Unmount Personality")
|
||||
print(f"{ASCIIColors.color_green}6 -{ASCIIColors.color_reset} Select Personality")
|
||||
print(f"{ASCIIColors.color_green}7 -{ASCIIColors.color_reset} Reinstall Binding")
|
||||
print(f"{ASCIIColors.color_green}8 -{ASCIIColors.color_reset} Reinstall current Personality")
|
||||
print(f"{ASCIIColors.color_green}9 -{ASCIIColors.color_reset} Reset all installs")
|
||||
print(f"{ASCIIColors.color_green}10 -{ASCIIColors.color_reset} Reset paths")
|
||||
print(f"{ASCIIColors.color_green}11 -{ASCIIColors.color_reset} Back to app")
|
||||
print(f"{ASCIIColors.color_green}12 -{ASCIIColors.color_reset} Help")
|
||||
print(f"{ASCIIColors.color_green}13 -{ASCIIColors.color_reset} Exit app")
|
||||
choice = input("Enter your choice: ").strip()
|
||||
if choice == "1":
|
||||
self.select_binding()
|
||||
elif choice == "2":
|
||||
self.select_model()
|
||||
elif choice == "3":
|
||||
self.vew_mounted_personalities()
|
||||
elif choice == "4":
|
||||
self.mount_personality()
|
||||
elif choice == "5":
|
||||
self.unmount_personality()
|
||||
elif choice == "6":
|
||||
self.select_personality()
|
||||
elif choice == "7":
|
||||
self.reinstall_binding()
|
||||
elif choice == "8":
|
||||
self.reinstall_personality()
|
||||
elif choice == "9":
|
||||
self.lollms_app.reset_all_installs()
|
||||
elif choice == "10":
|
||||
self.lollms_app.reset_paths()
|
||||
|
||||
elif choice == "11":
|
||||
print("Back to main app...")
|
||||
break
|
||||
elif choice == "12":
|
||||
self.show_commands_list()
|
||||
elif choice == "13":
|
||||
print("Bye")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("Invalid choice! Try again.")
|
||||
|
Loading…
Reference in New Issue
Block a user