mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-19 20:37:51 +00:00
commit
f8c685ff18
@ -12,9 +12,9 @@ from api.db import DiscussionsDB
|
||||
from api.helpers import compare_lists
|
||||
from pathlib import Path
|
||||
import importlib
|
||||
from lollms import AIPersonality, MSG_TYPE
|
||||
from lollms.binding import BindingConfig
|
||||
from lollms.paths import lollms_path, lollms_personal_configuration_path, lollms_personal_path, lollms_personal_models_path, lollms_bindings_zoo_path, lollms_personalities_zoo_path, lollms_default_cfg_path
|
||||
from lollms.personality import AIPersonality, MSG_TYPE
|
||||
from lollms.binding import LOLLMSConfig
|
||||
from lollms.paths import LollmsPaths
|
||||
import multiprocessing as mp
|
||||
import threading
|
||||
import time
|
||||
@ -83,8 +83,9 @@ def parse_requirements_file(requirements_path):
|
||||
|
||||
|
||||
class ModelProcess:
|
||||
def __init__(self, config:BindingConfig=None):
|
||||
def __init__(self, lollms_paths:LollmsPaths, config:LOLLMSConfig=None):
|
||||
self.config = config
|
||||
self.lollms_paths = lollms_paths
|
||||
self.generate_queue = mp.Queue()
|
||||
self.generation_queue = mp.Queue()
|
||||
self.cancel_queue = mp.Queue(maxsize=1)
|
||||
@ -92,8 +93,6 @@ class ModelProcess:
|
||||
self.set_config_queue = mp.Queue(maxsize=1)
|
||||
self.set_config_result_queue = mp.Queue(maxsize=1)
|
||||
|
||||
self.models_path = lollms_personal_models_path
|
||||
|
||||
self.process = None
|
||||
# Create synchronization objects
|
||||
self.start_signal = mp.Event()
|
||||
@ -139,7 +138,7 @@ class ModelProcess:
|
||||
print(f"Loading binding {binding_name} install ON")
|
||||
else:
|
||||
print(f"Loading binding : {binding_name} install is off")
|
||||
binding_path = lollms_path/"bindings_zoo"/binding_name
|
||||
binding_path = self.lollms_paths.bindings_zoo_path/binding_name
|
||||
if install:
|
||||
# first find out if there is a requirements.txt file
|
||||
install_file_name="install.py"
|
||||
@ -223,7 +222,7 @@ class ModelProcess:
|
||||
self.binding = self.load_binding(self.config["binding_name"], install=True)
|
||||
print("Binding loaded successfully")
|
||||
try:
|
||||
model_file = self.config.models_path/self.config["binding_name"]/self.config["model_name"]
|
||||
model_file = self.lollms_paths.personal_models_path/self.config["binding_name"]/self.config["model_name"]
|
||||
print(f"Loading model : {model_file}")
|
||||
self.model = self.binding(self.config)
|
||||
self.model_ready.value = 1
|
||||
@ -253,14 +252,15 @@ class ModelProcess:
|
||||
for personality in self.config['personalities']:
|
||||
try:
|
||||
print(f" {personality}")
|
||||
personality_path = lollms_personalities_zoo_path/f"{personality}"
|
||||
personality = AIPersonality(personality_path, run_scripts=False)
|
||||
personality_path = self.lollms_paths.personalities_zoo_path/f"{personality}"
|
||||
print(f"Loading from {personality_path}")
|
||||
personality = AIPersonality(self.lollms_paths, personality_path, run_scripts=False)
|
||||
mounted_personalities.append(personality)
|
||||
except Exception as ex:
|
||||
print(f"Personality file not found or is corrupted ({personality_path}).\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.")
|
||||
if self.config["debug"]:
|
||||
print(ex)
|
||||
personality = AIPersonality()
|
||||
personality = AIPersonality(self.lollms_paths)
|
||||
|
||||
print(f" ************ Personalities mounted (Main process) ***************************")
|
||||
|
||||
@ -274,14 +274,14 @@ class ModelProcess:
|
||||
for personality in self.config['personalities']:
|
||||
try:
|
||||
print(f" {personality}")
|
||||
personality_path = lollms_path/f"personalities_zoo/{personality}"
|
||||
personality = AIPersonality(personality_path, run_scripts=True)
|
||||
personality_path = self.lollms_paths.personalities_zoo_path/f"{personality}"
|
||||
personality = AIPersonality(self.lollms_paths, personality_path, run_scripts=True)
|
||||
self.mounted_personalities.append(personality)
|
||||
except Exception as ex:
|
||||
print(f"Personality file not found or is corrupted ({personality_path}).\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.")
|
||||
if self.config["debug"]:
|
||||
print(ex)
|
||||
personality = AIPersonality()
|
||||
personality = AIPersonality(self.lollms_paths)
|
||||
failed_personalities.append(personality_path)
|
||||
self._set_config_result['errors'].append(f"couldn't build personalities:{ex}")
|
||||
|
||||
@ -462,10 +462,12 @@ class ModelProcess:
|
||||
|
||||
|
||||
class LoLLMsAPPI():
|
||||
def __init__(self, config:BindingConfig, socketio, config_file_path:str) -> None:
|
||||
def __init__(self, config:LOLLMSConfig, socketio, config_file_path:str, lollms_paths: LollmsPaths) -> None:
|
||||
self.lollms_paths = lollms_paths
|
||||
|
||||
self.socketio = socketio
|
||||
#Create and launch the process
|
||||
self.process = ModelProcess(config)
|
||||
self.process = ModelProcess(self.lollms_paths, config)
|
||||
self.config = config
|
||||
self.binding = self.process.rebuild_binding(self.config)
|
||||
self.mounted_personalities = self.process.rebuild_personalities()
|
||||
@ -482,9 +484,12 @@ class LoLLMsAPPI():
|
||||
self._message_id = 0
|
||||
|
||||
self.db_path = config["db_path"]
|
||||
|
||||
# Create database object
|
||||
self.db = DiscussionsDB(self.db_path)
|
||||
if Path(self.db_path).is_absolute():
|
||||
# Create database object
|
||||
self.db = DiscussionsDB(self.db_path)
|
||||
else:
|
||||
# Create database object
|
||||
self.db = DiscussionsDB(self.lollms_paths.personal_path/"databases"/self.db_path)
|
||||
|
||||
# If the database is empty, populate it with tables
|
||||
self.db.populate()
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
import sqlite3
|
||||
|
||||
from pathlib import Path
|
||||
__author__ = "parisneo"
|
||||
__github__ = "https://github.com/ParisNeo/lollms-webui"
|
||||
__copyright__ = "Copyright 2023, "
|
||||
@ -13,7 +13,8 @@ class DiscussionsDB:
|
||||
MSG_TYPE_CONDITIONNING = 1
|
||||
|
||||
def __init__(self, db_path="database.db"):
|
||||
self.db_path = db_path
|
||||
self.db_path = Path(db_path)
|
||||
self.db_path .parent.mkdir(exist_ok=True, parents= True)
|
||||
|
||||
def populate(self):
|
||||
"""
|
||||
|
78
app.py
78
app.py
@ -24,9 +24,9 @@ import sys
|
||||
from tqdm import tqdm
|
||||
import subprocess
|
||||
import signal
|
||||
from lollms import AIPersonality, lollms_path, MSG_TYPE
|
||||
from lollms.console import ASCIIColors
|
||||
from lollms.paths import lollms_default_cfg_path, lollms_bindings_zoo_path, lollms_personalities_zoo_path, lollms_personal_path, lollms_personal_configuration_path, lollms_personal_models_path
|
||||
from lollms.personality import AIPersonality, MSG_TYPE
|
||||
from lollms.helpers import ASCIIColors, BaseConfig
|
||||
from lollms.paths import LollmsPaths
|
||||
from api.db import DiscussionsDB, Discussion
|
||||
from api.helpers import compare_lists
|
||||
from flask import (
|
||||
@ -48,7 +48,7 @@ import requests
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
import logging
|
||||
import psutil
|
||||
from lollms.binding import BindingConfig
|
||||
from lollms.binding import LOLLMSConfig
|
||||
|
||||
log = logging.getLogger('werkzeug')
|
||||
log.setLevel(logging.ERROR)
|
||||
@ -71,8 +71,8 @@ import markdown
|
||||
|
||||
|
||||
class LoLLMsWebUI(LoLLMsAPPI):
|
||||
def __init__(self, _app, _socketio, config:BindingConfig, config_file_path) -> None:
|
||||
super().__init__(config, _socketio, config_file_path)
|
||||
def __init__(self, _app, _socketio, config:LOLLMSConfig, config_file_path:Path|str, lollms_paths:LollmsPaths) -> None:
|
||||
super().__init__(config, _socketio, config_file_path, lollms_paths)
|
||||
|
||||
self.app = _app
|
||||
self.cancel_gen = False
|
||||
@ -87,6 +87,12 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
# =========================================================================================
|
||||
# Endpoints
|
||||
# =========================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
self.add_endpoint("/switch_personal_path", "switch_personal_path", self.switch_personal_path, methods=["POST"])
|
||||
|
||||
self.add_endpoint("/add_reference_to_local_model", "add_reference_to_local_model", self.add_reference_to_local_model, methods=["POST"])
|
||||
|
||||
self.add_endpoint("/send_file", "send_file", self.send_file, methods=["POST"])
|
||||
@ -295,7 +301,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
return jsonify({"personality":self.personality.as_dict()})
|
||||
|
||||
def get_all_personalities(self):
|
||||
personalities_folder = lollms_personalities_zoo_path
|
||||
personalities_folder = self.lollms_paths.personalities_zoo_path
|
||||
personalities = {}
|
||||
for language_folder in personalities_folder.iterdir():
|
||||
lang = language_folder.stem
|
||||
@ -438,7 +444,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
else:
|
||||
self.config["active_personality_id"] = 0
|
||||
self.config["personalities"][self.config["active_personality_id"]] = f"{self.personality_language}/{self.personality_category}/{self.personality_name}"
|
||||
personality_fn = lollms_personalities_zoo_path/self.config["personalities"][self.config["active_personality_id"]]
|
||||
personality_fn = self.lollms_paths.personalities_zoo_path/self.config["personalities"][self.config["active_personality_id"]]
|
||||
self.personality.load_personality(personality_fn)
|
||||
else:
|
||||
self.config["personalities"].append(f"{self.personality_language}/{self.personality_category}/{self.personality_name}")
|
||||
@ -503,7 +509,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
current_drive = Path.cwd().anchor
|
||||
drive_disk_usage = psutil.disk_usage(current_drive)
|
||||
try:
|
||||
models_folder_disk_usage = psutil.disk_usage(lollms_personal_models_path/f'{self.config["binding_name"]}')
|
||||
models_folder_disk_usage = psutil.disk_usage(self.lollms_paths.personal_models_path/f'{self.config["binding_name"]}')
|
||||
return jsonify({
|
||||
"total_space":drive_disk_usage.total,
|
||||
"available_space":drive_disk_usage.free,
|
||||
@ -521,7 +527,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
})
|
||||
|
||||
def list_bindings(self):
|
||||
bindings_dir = lollms_bindings_zoo_path # replace with the actual path to the models folder
|
||||
bindings_dir = self.lollms_paths.bindings_zoo_path # replace with the actual path to the models folder
|
||||
bindings=[]
|
||||
for f in bindings_dir.iterdir():
|
||||
card = f/"binding_card.yaml"
|
||||
@ -530,7 +536,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
bnd = load_config(card)
|
||||
bnd["folder"]=f.stem
|
||||
icon_path = Path(f"bindings/{f.name}/logo.png")
|
||||
if Path(lollms_bindings_zoo_path/f"{f.name}/logo.png").exists():
|
||||
if Path(self.lollms_paths.bindings_zoo_path/f"{f.name}/logo.png").exists():
|
||||
bnd["icon"]=str(icon_path)
|
||||
|
||||
bindings.append(bnd)
|
||||
@ -548,18 +554,18 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
|
||||
|
||||
def list_personalities_languages(self):
|
||||
personalities_languages_dir = lollms_personalities_zoo_path # replace with the actual path to the models folder
|
||||
personalities_languages_dir = self.lollms_paths.personalities_zoo_path # replace with the actual path to the models folder
|
||||
personalities_languages = [f.stem for f in personalities_languages_dir.iterdir() if f.is_dir()]
|
||||
return jsonify(personalities_languages)
|
||||
|
||||
def list_personalities_categories(self):
|
||||
personalities_categories_dir = lollms_personalities_zoo_path/f'{self.personality_language}' # replace with the actual path to the models folder
|
||||
personalities_categories_dir = self.lollms_paths.personalities_zoo_path/f'{self.personality_language}' # replace with the actual path to the models folder
|
||||
personalities_categories = [f.stem for f in personalities_categories_dir.iterdir() if f.is_dir()]
|
||||
return jsonify(personalities_categories)
|
||||
|
||||
def list_personalities(self):
|
||||
try:
|
||||
personalities_dir = lollms_personalities_zoo_path/f'{self.personality_language}/{self.personality_category}' # replace with the actual path to the models folder
|
||||
personalities_dir = self.lollms_paths.personalities_zoo_path/f'{self.personality_language}/{self.personality_category}' # replace with the actual path to the models folder
|
||||
personalities = [f.stem for f in personalities_dir.iterdir() if f.is_dir()]
|
||||
except Exception as ex:
|
||||
personalities=[]
|
||||
@ -627,19 +633,19 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_bindings(self, filename):
|
||||
path = str(lollms_bindings_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
path = str(self.lollms_paths.bindings_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
|
||||
fn = filename.split("/")[-1]
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_personalities(self, filename):
|
||||
path = str(lollms_personalities_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
path = str(self.lollms_paths.personalities_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
|
||||
fn = filename.split("/")[-1]
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_outputs(self, filename):
|
||||
root_dir = lollms_personal_path / "outputs"
|
||||
root_dir = self.lollms_paths.personal_path / "outputs"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
path = str(root_dir/"/".join(filename.split("/")[:-1]))
|
||||
|
||||
@ -655,7 +661,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_data(self, filename):
|
||||
root_dir = lollms_personal_path / "data"
|
||||
root_dir = self.lollms_paths.personal_path / "data"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
path = str(root_dir/"/".join(filename.split("/")[:-1]))
|
||||
|
||||
@ -663,7 +669,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_uploads(self, filename):
|
||||
root_dir = lollms_personal_path / "uploads"
|
||||
root_dir = self.lollms_paths.personal_path / "uploads"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
path = str(root_dir+"/".join(filename.split("/")[:-1]))
|
||||
@ -689,6 +695,22 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
self.process.cancel_generation()
|
||||
return jsonify({"status": True})
|
||||
|
||||
|
||||
def switch_personal_path(self):
|
||||
data = request.get_json()
|
||||
path = data["path"]
|
||||
global_paths_cfg = Path("./global_paths_cfg.yaml")
|
||||
if global_paths_cfg.exists():
|
||||
try:
|
||||
cfg = BaseConfig()
|
||||
cfg.load_config(global_paths_cfg)
|
||||
cfg.lollms_personal_path = path
|
||||
cfg.save_config(global_paths_cfg)
|
||||
return jsonify({"status": True})
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
return jsonify({"status": False, 'error':f"Couldn't switch path: {ex}"})
|
||||
|
||||
def add_reference_to_local_model(self):
|
||||
data = request.get_json()
|
||||
path = data["path"]
|
||||
@ -719,7 +741,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
name = data['name']
|
||||
|
||||
package_path = f"{language}/{category}/{name}"
|
||||
package_full_path = lollms_path/"personalities_zoo"/package_path
|
||||
package_full_path = self.lollms_paths.lollms_path/"personalities_zoo"/package_path
|
||||
config_file = package_full_path / "config.yaml"
|
||||
if config_file.exists():
|
||||
self.config["personalities"].append(package_path)
|
||||
@ -984,7 +1006,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
path = f'{server}{filename}'
|
||||
else:
|
||||
path = f'{server}/{filename}'
|
||||
local_path = lollms_personal_models_path/f'{self.config["binding_name"]}/{filename}'
|
||||
local_path = lollms_paths.personal_models_path/f'{self.config["binding_name"]}/{filename}'
|
||||
is_installed = local_path.exists() or model_type.lower()=="api"
|
||||
models.append({
|
||||
'title': filename,
|
||||
@ -1085,6 +1107,10 @@ def sync_cfg(default_config, config):
|
||||
return config, added_entries, removed_entries
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=True)
|
||||
db_folder = lollms_paths.personal_path/"databases"
|
||||
db_folder.mkdir(parents=True, exist_ok=True)
|
||||
parser = argparse.ArgumentParser(description="Start the chatbot Flask app.")
|
||||
parser.add_argument(
|
||||
"-c", "--config", type=str, default="local_config", help="Sets the configuration file to be used."
|
||||
@ -1159,12 +1185,12 @@ if __name__ == "__main__":
|
||||
|
||||
if args.config!="local_config":
|
||||
args.config = "local_config"
|
||||
if not lollms_personal_configuration_path/f"local_config.yaml".exists():
|
||||
if not lollms_paths.personal_configuration_path/f"local_config.yaml".exists():
|
||||
print("No local configuration file found. Building from scratch")
|
||||
shutil.copy(default_config, lollms_personal_configuration_path/f"local_config.yaml")
|
||||
shutil.copy(default_config, lollms_paths.personal_configuration_path/f"local_config.yaml")
|
||||
|
||||
config_file_path = lollms_personal_configuration_path/f"local_config.yaml"
|
||||
config = BindingConfig(config_file_path)
|
||||
config_file_path = lollms_paths.personal_configuration_path/f"local_config.yaml"
|
||||
config = LOLLMSConfig(config_file_path)
|
||||
|
||||
|
||||
if "version" not in config or int(config["version"])<int(default_config["version"]):
|
||||
@ -1181,7 +1207,7 @@ if __name__ == "__main__":
|
||||
|
||||
# executor = ThreadPoolExecutor(max_workers=1)
|
||||
# app.config['executor'] = executor
|
||||
bot = LoLLMsWebUI(app, socketio, config, config_file_path)
|
||||
bot = LoLLMsWebUI(app, socketio, config, config_file_path, lollms_paths)
|
||||
|
||||
# chong Define custom WebSocketHandler with error handling
|
||||
class CustomWebSocketHandler(WebSocketHandler):
|
||||
|
@ -28,4 +28,4 @@ user_name: user
|
||||
|
||||
# UI parameters
|
||||
debug: False
|
||||
db_path: databases/database.db
|
||||
db_path: database.db
|
2
global_paths_cfg.yaml
Normal file
2
global_paths_cfg.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
lollms_path: c:\Users\aloui\Documents\ai\GPT4ALL-ui\GPT4All\env\lib\site-packages\lollms
|
||||
lollms_personal_path: C:\Users\aloui\Documents\lollms
|
@ -1,4 +0,0 @@
|
||||
Here you can drop your models depending on the selected binding
|
||||
Currently, supported bindings are:
|
||||
- llamacpp
|
||||
- gpt-j
|
Loading…
Reference in New Issue
Block a user