mirror of
https://github.com/ParisNeo/lollms.git
synced 2025-01-20 03:36:30 +00:00
enhanced endpoints and added events
This commit is contained in:
parent
9d8db7a0da
commit
8d122ba614
234
lollms/server/endpoints/lollms_binding_files_server.py
Normal file
234
lollms/server/endpoints/lollms_binding_files_server.py
Normal file
@ -0,0 +1,234 @@
|
||||
"""
|
||||
project: lollms
|
||||
file: lollms_binding_files_server.py
|
||||
author: ParisNeo
|
||||
description:
|
||||
This module contains a set of FastAPI routes that provide information about the Lord of Large Language and Multimodal Systems (LoLLMs) Web UI
|
||||
application. These routes are specific to serving files
|
||||
|
||||
"""
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
import pkg_resources
|
||||
from lollms.server.elf_server import LOLLMSElfServer
|
||||
from fastapi.responses import FileResponse
|
||||
from lollms.binding import BindingBuilder, InstallOption
|
||||
from ascii_colors import ASCIIColors
|
||||
from lollms.utilities import load_config, trace_exception, gc
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import os
|
||||
|
||||
router = APIRouter()
|
||||
lollmsElfServer = LOLLMSElfServer.get_instance()
|
||||
|
||||
|
||||
# ----------------------------------- Personal files -----------------------------------------
|
||||
@router.get("/user_infos/{path:path}")
|
||||
async def serve_user_infos(path: str):
|
||||
"""
|
||||
Serve user information file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested file.
|
||||
"""
|
||||
file_path = lollmsElfServer.lollms_paths.personal_user_infos_path / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
# ----------------------------------- Lollms zoos -----------------------------------------
|
||||
|
||||
|
||||
@router.get("/bindings/{path:path}")
|
||||
async def serve_bindings(path: str):
|
||||
"""
|
||||
Serve personalities file.
|
||||
|
||||
Args:
|
||||
path (str): The path of the bindings file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested bindings file.
|
||||
"""
|
||||
file_path = lollmsElfServer.lollms_paths.bindings_zoo_path / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
@router.get("/personalities/{path:path}")
|
||||
async def serve_personalities(path: str):
|
||||
"""
|
||||
Serve personalities file.
|
||||
|
||||
Args:
|
||||
path (str): The path of the personalities file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested personalities file.
|
||||
"""
|
||||
if "custom_personalities" in path:
|
||||
file_path = lollmsElfServer.lollms_paths.custom_personalities_path / "/".join(str(path).split("/")[1:])
|
||||
else:
|
||||
file_path = lollmsElfServer.lollms_paths.personalities_zoo_path / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
@router.get("/extensions/{path:path}")
|
||||
async def serve_extensions(path: str):
|
||||
"""
|
||||
Serve personalities file.
|
||||
|
||||
Args:
|
||||
path (str): The path of the extensions file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested extensions file.
|
||||
"""
|
||||
file_path = lollmsElfServer.lollms_paths.extensions_zoo_path / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
# ----------------------------------- Services -----------------------------------------
|
||||
|
||||
@router.get("/audio/{path:path}")
|
||||
async def serve_audio(path: str):
|
||||
"""
|
||||
Serve audio file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the audio file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested audio file.
|
||||
"""
|
||||
root_dir = lollmsElfServer.lollms_paths.personal_outputs_path
|
||||
file_path = os.path.join(root_dir, 'audio_out/') / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
|
||||
@router.get("/images/{path:path}")
|
||||
async def serve_images(path: str):
|
||||
"""
|
||||
Serve image file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the image file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested image file.
|
||||
"""
|
||||
root_dir = Path(os.getcwd())/ "images/"
|
||||
file_path = root_dir / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
|
||||
# ----------------------------------- User content -----------------------------------------
|
||||
|
||||
@router.get("/outputs/{path:path}")
|
||||
async def serve_outputs(path: str):
|
||||
"""
|
||||
Serve image file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the output file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested output file.
|
||||
"""
|
||||
root_dir = lollmsElfServer.lollms_paths.personal_path / "outputs"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
file_path = root_dir / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
|
||||
|
||||
@router.get("/data/{path:path}")
|
||||
async def serve_data(path: str):
|
||||
"""
|
||||
Serve image file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the data file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested data file.
|
||||
"""
|
||||
root_dir = lollmsElfServer.lollms_paths.personal_path / "data"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
file_path = root_dir / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
|
||||
|
||||
|
||||
@router.get("/help/{path:path}")
|
||||
async def serve_help(path: str):
|
||||
"""
|
||||
Serve image file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the data file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested data file.
|
||||
"""
|
||||
root_dir = Path(os.getcwd())
|
||||
file_path = root_dir/'help/' / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
||||
|
||||
|
||||
|
||||
@router.get("/uploads/{path:path}")
|
||||
async def serve_uploads(path: str):
|
||||
"""
|
||||
Serve image file.
|
||||
|
||||
Args:
|
||||
filename (str): The name of the uploads file to serve.
|
||||
|
||||
Returns:
|
||||
FileResponse: The file response containing the requested uploads file.
|
||||
"""
|
||||
root_dir = lollmsElfServer.lollms_paths.personal_path / "uploads"
|
||||
root_dir.mkdir(exist_ok=True, parents=True)
|
||||
file_path = root_dir / path
|
||||
|
||||
if not Path(file_path).exists():
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
return FileResponse(str(file_path))
|
133
lollms/server/endpoints/lollms_configuration_infos.py
Normal file
133
lollms/server/endpoints/lollms_configuration_infos.py
Normal file
@ -0,0 +1,133 @@
|
||||
"""
|
||||
project: lollms
|
||||
file: lollms_configuration_infos.py
|
||||
author: ParisNeo
|
||||
description:
|
||||
This module contains a set of FastAPI routes that provide information about the Lord of Large Language and Multimodal Systems (LoLLMs) Web UI
|
||||
application. These routes are specific to configurations
|
||||
|
||||
"""
|
||||
from fastapi import APIRouter, Request
|
||||
from pydantic import BaseModel
|
||||
import pkg_resources
|
||||
from lollms.server.elf_server import LOLLMSElfServer
|
||||
from lollms.binding import BindingBuilder, InstallOption
|
||||
from ascii_colors import ASCIIColors
|
||||
from lollms.utilities import load_config, trace_exception, gc
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import json
|
||||
|
||||
class SettingsInfos(BaseModel):
|
||||
setting_name:str
|
||||
setting_value:str
|
||||
|
||||
router = APIRouter()
|
||||
lollmsElfServer = LOLLMSElfServer.get_instance()
|
||||
|
||||
|
||||
# ----------------------------------- Settings -----------------------------------------
|
||||
@router.get("/update_setting")
|
||||
def update_setting(data:SettingsInfos):
|
||||
setting_name = data.setting_name
|
||||
|
||||
ASCIIColors.info(f"Requested updating of setting {data.setting_name} to {data['setting_value']}")
|
||||
if setting_name== "temperature":
|
||||
lollmsElfServer.config["temperature"]=float(data['setting_value'])
|
||||
elif setting_name== "n_predict":
|
||||
lollmsElfServer.config["n_predict"]=int(data['setting_value'])
|
||||
elif setting_name== "top_k":
|
||||
lollmsElfServer.config["top_k"]=int(data['setting_value'])
|
||||
elif setting_name== "top_p":
|
||||
lollmsElfServer.config["top_p"]=float(data['setting_value'])
|
||||
|
||||
elif setting_name== "repeat_penalty":
|
||||
lollmsElfServer.config["repeat_penalty"]=float(data['setting_value'])
|
||||
elif setting_name== "repeat_last_n":
|
||||
lollmsElfServer.config["repeat_last_n"]=int(data['setting_value'])
|
||||
|
||||
elif setting_name== "n_threads":
|
||||
lollmsElfServer.config["n_threads"]=int(data['setting_value'])
|
||||
elif setting_name== "ctx_size":
|
||||
lollmsElfServer.config["ctx_size"]=int(data['setting_value'])
|
||||
|
||||
elif setting_name== "personality_folder":
|
||||
lollmsElfServer.personality_name=data['setting_value']
|
||||
if len(lollmsElfServer.config["personalities"])>0:
|
||||
if lollmsElfServer.config["active_personality_id"]<len(lollmsElfServer.config["personalities"]):
|
||||
lollmsElfServer.config["personalities"][lollmsElfServer.config["active_personality_id"]] = f"{lollmsElfServer.personality_category}/{lollmsElfServer.personality_name}"
|
||||
else:
|
||||
lollmsElfServer.config["active_personality_id"] = 0
|
||||
lollmsElfServer.config["personalities"][lollmsElfServer.config["active_personality_id"]] = f"{lollmsElfServer.personality_category}/{lollmsElfServer.personality_name}"
|
||||
|
||||
if lollmsElfServer.personality_category!="custom_personalities":
|
||||
personality_fn = lollmsElfServer.lollms_paths.personalities_zoo_path/lollmsElfServer.config["personalities"][lollmsElfServer.config["active_personality_id"]]
|
||||
else:
|
||||
personality_fn = lollmsElfServer.lollms_paths.personal_personalities_path/lollmsElfServer.config["personalities"][lollmsElfServer.config["active_personality_id"]].split("/")[-1]
|
||||
lollmsElfServer.personality.load_personality(personality_fn)
|
||||
else:
|
||||
lollmsElfServer.config["personalities"].append(f"{lollmsElfServer.personality_category}/{lollmsElfServer.personality_name}")
|
||||
elif setting_name== "override_personality_model_parameters":
|
||||
lollmsElfServer.config["override_personality_model_parameters"]=bool(data['setting_value'])
|
||||
|
||||
elif setting_name== "binding_name":
|
||||
if lollmsElfServer.config['binding_name']!= data['setting_value']:
|
||||
print(f"New binding selected : {data['setting_value']}")
|
||||
lollmsElfServer.config["binding_name"]=data['setting_value']
|
||||
try:
|
||||
if lollmsElfServer.binding:
|
||||
lollmsElfServer.binding.destroy_model()
|
||||
lollmsElfServer.binding = None
|
||||
lollmsElfServer.model = None
|
||||
for per in lollmsElfServer.mounted_personalities:
|
||||
per.model = None
|
||||
gc.collect()
|
||||
lollmsElfServer.binding = BindingBuilder().build_binding(lollmsElfServer.config, lollmsElfServer.lollms_paths, InstallOption.INSTALL_IF_NECESSARY, lollmsCom=lollmsElfServer)
|
||||
lollmsElfServer.model = None
|
||||
lollmsElfServer.config.save_config()
|
||||
ASCIIColors.green("Binding loaded successfully")
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't build binding: [{ex}]")
|
||||
trace_exception(ex)
|
||||
return {"status":False, 'error':str(ex)}
|
||||
else:
|
||||
if lollmsElfServer.config["debug"]:
|
||||
print(f"Configuration {data.setting_name} set to {data['setting_value']}")
|
||||
return {'setting_name': data.setting_name, "status":True}
|
||||
|
||||
|
||||
elif setting_name == "model_name":
|
||||
ASCIIColors.yellow(f"Changing model to: {data['setting_value']}")
|
||||
lollmsElfServer.config["model_name"]=data['setting_value']
|
||||
lollmsElfServer.config.save_config()
|
||||
try:
|
||||
lollmsElfServer.model = None
|
||||
for per in lollmsElfServer.mounted_personalities:
|
||||
if per is not None:
|
||||
per.model = None
|
||||
lollmsElfServer.model = lollmsElfServer.binding.build_model()
|
||||
if lollmsElfServer.model is not None:
|
||||
ASCIIColors.yellow("New model OK")
|
||||
for per in lollmsElfServer.mounted_personalities:
|
||||
per.model = lollmsElfServer.model
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
lollmsElfServer.InfoMessage(f"It looks like you we couldn't load the model.\nHere is the error message:\n{ex}")
|
||||
|
||||
|
||||
else:
|
||||
if data.setting_name in lollmsElfServer.config.config.keys():
|
||||
lollmsElfServer.config[data.setting_name] = data['setting_value']
|
||||
else:
|
||||
if lollmsElfServer.config["debug"]:
|
||||
print(f"Configuration {data.setting_name} couldn't be set to {data['setting_value']}")
|
||||
return {'setting_name': data.setting_name, "status":False}
|
||||
|
||||
if lollmsElfServer.config["debug"]:
|
||||
print(f"Configuration {data.setting_name} set to {data['setting_value']}")
|
||||
|
||||
ASCIIColors.success(f"Configuration {data.setting_name} updated")
|
||||
if lollmsElfServer.config.auto_save:
|
||||
lollmsElfServer.config.save_config()
|
||||
# Tell that the setting was changed
|
||||
return {'setting_name': data.setting_name, "status":True}
|
@ -11,6 +11,8 @@ from fastapi import APIRouter, Request
|
||||
from pydantic import BaseModel
|
||||
import pkg_resources
|
||||
from lollms.server.elf_server import LOLLMSElfServer
|
||||
from lollms.extension import ExtensionBuilder, InstallOption
|
||||
from lollms.utilities import gc
|
||||
from ascii_colors import ASCIIColors
|
||||
from lollms.utilities import load_config, trace_exception
|
||||
from pathlib import Path
|
||||
@ -18,8 +20,252 @@ from typing import List
|
||||
import psutil
|
||||
import yaml
|
||||
|
||||
# --------------------- Parameter Classes -------------------------------
|
||||
class ExtensionInstallInfos(BaseModel):
|
||||
name:str
|
||||
class ExtensionMountingInfos(BaseModel):
|
||||
category:str
|
||||
folder:str
|
||||
language:str
|
||||
|
||||
# --------------------- Route -------------------------------
|
||||
|
||||
router = APIRouter()
|
||||
lollmsElfServer = LOLLMSElfServer.get_instance()
|
||||
|
||||
# --------------------- Listing -------------------------------
|
||||
@router.get("/list_extensions_categories")
|
||||
def list_extensions_categories():
|
||||
extensions_categories_dir = lollmsElfServer.lollms_paths.extensions_zoo_path # replace with the actual path to the models folder
|
||||
extensions_categories = [f.stem for f in extensions_categories_dir.iterdir() if f.is_dir() and not f.name.startswith(".")]
|
||||
return extensions_categories
|
||||
|
||||
@router.get("/list_extensions")
|
||||
def list_extensions():
|
||||
return lollmsElfServer.config.extensions
|
||||
|
||||
|
||||
@router.get("/get_all_extensions")
|
||||
def get_all_extensions():
|
||||
ASCIIColors.yellow("Getting all extensions")
|
||||
extensions_folder = lollmsElfServer.lollms_paths.extensions_zoo_path
|
||||
extensions = {}
|
||||
|
||||
for category_folder in extensions_folder.iterdir():
|
||||
cat = category_folder.stem
|
||||
if category_folder.is_dir() and not category_folder.stem.startswith('.'):
|
||||
extensions[category_folder.name] = []
|
||||
for extensions_folder in category_folder.iterdir():
|
||||
ext = extensions_folder.stem
|
||||
if extensions_folder.is_dir() and not extensions_folder.stem.startswith('.'):
|
||||
extension_info = {"folder":extensions_folder.stem}
|
||||
config_path = extensions_folder / 'config.yaml'
|
||||
if not config_path.exists():
|
||||
continue
|
||||
try:
|
||||
with open(config_path) as config_file:
|
||||
config_data = yaml.load(config_file, Loader=yaml.FullLoader)
|
||||
extension_info['name'] = config_data.get('name',"No Name")
|
||||
extension_info['author'] = config_data.get('author', 'ParisNeo')
|
||||
extension_info['based_on'] = config_data.get('based_on',"")
|
||||
extension_info['description'] = config_data.get('description',"")
|
||||
extension_info['version'] = config_data.get('version', '1.0.0')
|
||||
extension_info['installed'] = (lollmsElfServer.lollms_paths.personal_configuration_path/f"personality_{extensions_folder.stem}.yaml").exists()
|
||||
extension_info['help'] = config_data.get('help', '')
|
||||
|
||||
real_assets_path = extensions_folder/ 'assets'
|
||||
assets_path = Path("extensions") / cat / ext / 'assets'
|
||||
gif_logo_path = assets_path / 'logo.gif'
|
||||
webp_logo_path = assets_path / 'logo.webp'
|
||||
png_logo_path = assets_path / 'logo.png'
|
||||
jpg_logo_path = assets_path / 'logo.jpg'
|
||||
jpeg_logo_path = assets_path / 'logo.jpeg'
|
||||
svg_logo_path = assets_path / 'logo.svg'
|
||||
bmp_logo_path = assets_path / 'logo.bmp'
|
||||
|
||||
gif_logo_path_ = real_assets_path / 'logo.gif'
|
||||
webp_logo_path_ = real_assets_path / 'logo.webp'
|
||||
png_logo_path_ = real_assets_path / 'logo.png'
|
||||
jpg_logo_path_ = real_assets_path / 'logo.jpg'
|
||||
jpeg_logo_path_ = real_assets_path / 'logo.jpeg'
|
||||
svg_logo_path_ = real_assets_path / 'logo.svg'
|
||||
bmp_logo_path_ = real_assets_path / 'logo.bmp'
|
||||
|
||||
extension_info['has_logo'] = png_logo_path.is_file() or gif_logo_path.is_file()
|
||||
|
||||
if gif_logo_path_.exists():
|
||||
extension_info['avatar'] = str(gif_logo_path).replace("\\","/")
|
||||
elif webp_logo_path_.exists():
|
||||
extension_info['avatar'] = str(webp_logo_path).replace("\\","/")
|
||||
elif png_logo_path_.exists():
|
||||
extension_info['avatar'] = str(png_logo_path).replace("\\","/")
|
||||
elif jpg_logo_path_.exists():
|
||||
extension_info['avatar'] = str(jpg_logo_path).replace("\\","/")
|
||||
elif jpeg_logo_path_.exists():
|
||||
extension_info['avatar'] = str(jpeg_logo_path).replace("\\","/")
|
||||
elif svg_logo_path_.exists():
|
||||
extension_info['avatar'] = str(svg_logo_path).replace("\\","/")
|
||||
elif bmp_logo_path_.exists():
|
||||
extension_info['avatar'] = str(bmp_logo_path).replace("\\","/")
|
||||
else:
|
||||
extension_info['avatar'] = ""
|
||||
|
||||
extensions[category_folder.name].append(extension_info)
|
||||
except Exception as ex:
|
||||
ASCIIColors.warning(f"Couldn't load personality from {extensions_folder} [{ex}]")
|
||||
trace_exception(ex)
|
||||
return extensions
|
||||
|
||||
|
||||
|
||||
# --------------------- Installing -------------------------------
|
||||
@router.post("/install_extension")
|
||||
def install_extension(data: ExtensionInstallInfos):
|
||||
if not data.name:
|
||||
try:
|
||||
data.name=lollmsElfServer.config.extensions[-1]
|
||||
except Exception as ex:
|
||||
lollmsElfServer.error(ex)
|
||||
return
|
||||
try:
|
||||
extension_path = lollmsElfServer.lollms_paths.extensions_zoo_path / data.name
|
||||
ASCIIColors.info(f"- Reinstalling extension {data.name}...")
|
||||
try:
|
||||
lollmsElfServer.mounted_extensions.append(ExtensionBuilder().build_extension(extension_path,lollmsElfServer.lollms_paths, lollmsElfServer, InstallOption.FORCE_INSTALL))
|
||||
return {"status":True}
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Extension file not found or is corrupted ({data.name}).\nReturned the following exception:{ex}\nPlease verify that the personality you have selected exists or select another personality. Some updates may lead to change in personality name or category, so check the personality selection in settings to be sure.")
|
||||
trace_exception(ex)
|
||||
ASCIIColors.info("Trying to force reinstall")
|
||||
return {"status":False, 'error':str(e)}
|
||||
|
||||
except Exception as e:
|
||||
return {"status":False, 'error':str(e)}
|
||||
|
||||
@router.post("/reinstall_extension")
|
||||
def reinstall_extension(data: ExtensionInstallInfos):
|
||||
if not data.name:
|
||||
try:
|
||||
data.name=lollmsElfServer.config.extensions[-1]
|
||||
except Exception as ex:
|
||||
lollmsElfServer.error(ex)
|
||||
return
|
||||
try:
|
||||
extension_path = lollmsElfServer.lollms_paths.extensions_zoo_path / data.name
|
||||
ASCIIColors.info(f"- Reinstalling extension {data.name}...")
|
||||
ASCIIColors.info("Unmounting extension")
|
||||
if data.name in lollmsElfServer.config.extensions:
|
||||
idx = lollmsElfServer.config.extensions.index(data.name)
|
||||
print(f"index = {idx}")
|
||||
if len(lollmsElfServer.mount_extensions)>idx:
|
||||
del lollmsElfServer.mounted_extensions[idx]
|
||||
gc.collect()
|
||||
try:
|
||||
lollmsElfServer.mounted_extensions.append(ExtensionBuilder().build_extension(extension_path,lollmsElfServer.lollms_paths, lollmsElfServer, InstallOption.FORCE_INSTALL))
|
||||
return {"status":True}
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Extension file not found or is corrupted ({data.name}).\nReturned the following exception:{ex}\nPlease verify that the personality you have selected exists or select another personality. Some updates may lead to change in personality name or category, so check the personality selection in settings to be sure.")
|
||||
trace_exception(ex)
|
||||
ASCIIColors.info("Trying to force reinstall")
|
||||
return {"status":False, 'error':str(e)}
|
||||
|
||||
except Exception as e:
|
||||
return {"status":False, 'error':str(e)}
|
||||
|
||||
|
||||
# --------------------- Mounting -------------------------------
|
||||
|
||||
|
||||
@router.post("/mount_extension")
|
||||
def mount_extension(data:ExtensionMountingInfos):
|
||||
print("- Mounting extension")
|
||||
category = data.category
|
||||
name = data.folder
|
||||
|
||||
package_path = f"{category}/{name}"
|
||||
package_full_path = lollmsElfServer.lollms_paths.extensions_zoo_path/package_path
|
||||
config_file = package_full_path / "config.yaml"
|
||||
if config_file.exists():
|
||||
lollmsElfServer.config["extensions"].append(package_path)
|
||||
lollmsElfServer.mounted_extensions = lollmsElfServer.rebuild_extensions()
|
||||
ASCIIColors.success("ok")
|
||||
if lollmsElfServer.config.auto_save:
|
||||
ASCIIColors.info("Saving configuration")
|
||||
lollmsElfServer.config.save_config()
|
||||
ASCIIColors.success(f"Extension {name} mounted successfully")
|
||||
return {"status": True,
|
||||
"extensions":lollmsElfServer.config["extensions"],
|
||||
}
|
||||
else:
|
||||
pth = str(config_file).replace('\\','/')
|
||||
ASCIIColors.error(f"nok : Extension not found @ {pth}")
|
||||
return {"status": False, "error":f"Extension not found @ {pth}"}
|
||||
|
||||
|
||||
@router.post("/remount_extension")
|
||||
def remount_extension(data:ExtensionMountingInfos):
|
||||
print("- Remounting extension")
|
||||
category = data.category
|
||||
name = data.folder
|
||||
|
||||
package_path = f"{category}/{name}"
|
||||
package_full_path = lollmsElfServer.lollms_paths.extensions_zoo_path/package_path
|
||||
config_file = package_full_path / "config.yaml"
|
||||
if config_file.exists():
|
||||
ASCIIColors.info(f"Unmounting personality {package_path}")
|
||||
index = lollmsElfServer.config["extensions"].index(f"{category}/{name}")
|
||||
lollmsElfServer.config["extensions"].remove(f"{category}/{name}")
|
||||
if len(lollmsElfServer.config["extensions"])>0:
|
||||
lollmsElfServer.mounted_personalities = lollmsElfServer.rebuild_extensions()
|
||||
else:
|
||||
lollmsElfServer.personalities = ["generic/lollms"]
|
||||
lollmsElfServer.mounted_personalities = lollmsElfServer.rebuild_extensions()
|
||||
|
||||
|
||||
ASCIIColors.info(f"Mounting personality {package_path}")
|
||||
lollmsElfServer.config["personalities"].append(package_path)
|
||||
lollmsElfServer.mounted_personalities = lollmsElfServer.rebuild_extensions()
|
||||
ASCIIColors.success("ok")
|
||||
if lollmsElfServer.config["active_personality_id"]<0:
|
||||
return {"status": False,
|
||||
"personalities":lollmsElfServer.config["personalities"],
|
||||
"active_personality_id":lollmsElfServer.config["active_personality_id"]
|
||||
}
|
||||
else:
|
||||
return {"status": True,
|
||||
"personalities":lollmsElfServer.config["personalities"],
|
||||
"active_personality_id":lollmsElfServer.config["active_personality_id"]
|
||||
}
|
||||
else:
|
||||
pth = str(config_file).replace('\\','/')
|
||||
ASCIIColors.error(f"nok : Personality not found @ {pth}")
|
||||
ASCIIColors.yellow(f"Available personalities: {[p.name for p in lollmsElfServer.mounted_personalities]}")
|
||||
return {"status": False, "error":f"Personality not found @ {pth}"}
|
||||
|
||||
@router.post("/unmount_extension")
|
||||
def unmount_extension(data:ExtensionMountingInfos):
|
||||
print("- Unmounting extension ...")
|
||||
category = data.category
|
||||
name = data.folder
|
||||
language = data.get('language',None)
|
||||
try:
|
||||
personality_id = f"{category}/{name}" if language is None else f"{category}/{name}:{language}"
|
||||
index = lollmsElfServer.config["personalities"].index(personality_id)
|
||||
lollmsElfServer.config["extensions"].remove(personality_id)
|
||||
lollmsElfServer.mounted_extensions = lollmsElfServer.rebuild_extensions()
|
||||
ASCIIColors.success("ok")
|
||||
if lollmsElfServer.config.auto_save:
|
||||
ASCIIColors.info("Saving configuration")
|
||||
lollmsElfServer.config.save_config()
|
||||
return {
|
||||
"status": True,
|
||||
"extensions":lollmsElfServer.config["extensions"]
|
||||
}
|
||||
except:
|
||||
if language:
|
||||
ASCIIColors.error(f"nok : Personality not found @ {category}/{name}:{language}")
|
||||
else:
|
||||
ASCIIColors.error(f"nok : Personality not found @ {category}/{name}")
|
||||
|
||||
ASCIIColors.yellow(f"Available personalities: {[p.name for p in lollmsElfServer.mounted_personalities]}")
|
||||
return {"status": False, "error":"Couldn't unmount personality"}
|
||||
|
@ -473,4 +473,11 @@ def post_to_personality(data):
|
||||
return lollmsElfServer.personality.processor.handle_request(data)
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
|
||||
@router.get("/post_to_personality")
|
||||
def get_current_personality_files_list():
|
||||
if lollmsElfServer.personality is None:
|
||||
return {"state":False, "error":"No personality selected"}
|
||||
return {"state":True, "files":[{"name":Path(f).name, "size":Path(f).stat().st_size} for f in lollmsElfServer.personality.text_files]+[{"name":Path(f).name, "size":Path(f).stat().st_size} for f in lollmsElfServer.personality.image_files]}
|
||||
|
||||
|
212
lollms/server/events/lollms_generation_events.py
Normal file
212
lollms/server/events/lollms_generation_events.py
Normal file
@ -0,0 +1,212 @@
|
||||
"""
|
||||
project: lollms
|
||||
file: lollms_binding_files_server.py
|
||||
author: ParisNeo
|
||||
description:
|
||||
This module contains a set of FastAPI routes that provide information about the Lord of Large Language and Multimodal Systems (LoLLMs) Web UI
|
||||
application. These routes are specific to serving files
|
||||
|
||||
"""
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
import pkg_resources
|
||||
from lollms.server.elf_server import LOLLMSElfServer
|
||||
from fastapi.responses import FileResponse
|
||||
from lollms.binding import BindingBuilder, InstallOption
|
||||
from ascii_colors import ASCIIColors
|
||||
from lollms.personality import MSG_TYPE, AIPersonality
|
||||
from lollms.utilities import load_config, trace_exception, gc
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import socketio
|
||||
import os
|
||||
|
||||
router = APIRouter()
|
||||
lollmsElfServer = LOLLMSElfServer.get_instance()
|
||||
|
||||
|
||||
# ----------------------------------- events -----------------------------------------
|
||||
def add_events(sio:socketio):
|
||||
@sio.on('cancel_generation')
|
||||
def cancel_generation(sid, environ):
|
||||
client_id = sid
|
||||
lollmsElfServer.cancel_gen = True
|
||||
#kill thread
|
||||
ASCIIColors.error(f'Client {sid} requested cancelling generation')
|
||||
terminate_thread(lollmsElfServer.connections[client_id]['generation_thread'])
|
||||
ASCIIColors.error(f'Client {sid} canceled generation')
|
||||
lollmsElfServer.busy=False
|
||||
|
||||
|
||||
@sio.on('cancel_text_generation')
|
||||
def cancel_text_generation(sid, environ):
|
||||
client_id = sid
|
||||
lollmsElfServer.connections[client_id]["requested_stop"]=True
|
||||
print(f"Client {client_id} requested canceling generation")
|
||||
lollmsElfServer.socketio.emit("generation_canceled", {"message":"Generation is canceled."}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
lollmsElfServer.busy = False
|
||||
|
||||
|
||||
# A copy of the original lollms-server generation code needed for playground
|
||||
@sio.on('generate_text')
|
||||
def handle_generate_text(sid, environ, data):
|
||||
client_id = sid
|
||||
lollmsElfServer.cancel_gen = False
|
||||
ASCIIColors.info(f"Text generation requested by client: {client_id}")
|
||||
if lollmsElfServer.busy:
|
||||
lollmsElfServer.socketio.emit("busy", {"message":"I am busy. Come back later."}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
ASCIIColors.warning(f"OOps request {client_id} refused!! Server busy")
|
||||
return
|
||||
def generate_text():
|
||||
lollmsElfServer.busy = True
|
||||
try:
|
||||
model = lollmsElfServer.model
|
||||
lollmsElfServer.connections[client_id]["is_generating"]=True
|
||||
lollmsElfServer.connections[client_id]["requested_stop"]=False
|
||||
prompt = data['prompt']
|
||||
tokenized = model.tokenize(prompt)
|
||||
personality_id = data.get('personality', -1)
|
||||
|
||||
n_crop = data.get('n_crop', len(tokenized))
|
||||
if n_crop!=-1:
|
||||
prompt = model.detokenize(tokenized[-n_crop:])
|
||||
|
||||
n_predicts = data["n_predicts"]
|
||||
parameters = data.get("parameters",{
|
||||
"temperature":lollmsElfServer.config["temperature"],
|
||||
"top_k":lollmsElfServer.config["top_k"],
|
||||
"top_p":lollmsElfServer.config["top_p"],
|
||||
"repeat_penalty":lollmsElfServer.config["repeat_penalty"],
|
||||
"repeat_last_n":lollmsElfServer.config["repeat_last_n"],
|
||||
"seed":lollmsElfServer.config["seed"]
|
||||
})
|
||||
|
||||
if personality_id==-1:
|
||||
# Raw text generation
|
||||
lollmsElfServer.answer = {"full_text":""}
|
||||
def callback(text, message_type: MSG_TYPE, metadata:dict={}):
|
||||
if message_type == MSG_TYPE.MSG_TYPE_CHUNK:
|
||||
ASCIIColors.success(f"generated:{len(lollmsElfServer.answer['full_text'].split())} words", end='\r')
|
||||
if text is not None:
|
||||
lollmsElfServer.answer["full_text"] = lollmsElfServer.answer["full_text"] + text
|
||||
lollmsElfServer.socketio.emit('text_chunk', {'chunk': text, 'type':MSG_TYPE.MSG_TYPE_CHUNK.value}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
if client_id in lollmsElfServer.connections:# Client disconnected
|
||||
if lollmsElfServer.connections[client_id]["requested_stop"]:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
tk = model.tokenize(prompt)
|
||||
n_tokens = len(tk)
|
||||
fd = model.detokenize(tk[-min(lollmsElfServer.config.ctx_size-n_predicts,n_tokens):])
|
||||
|
||||
try:
|
||||
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"],
|
||||
repeat_penalty = parameters["repeat_penalty"],
|
||||
repeat_last_n = parameters["repeat_last_n"],
|
||||
seed = parameters["seed"],
|
||||
)
|
||||
ASCIIColors.success(f"\ndone")
|
||||
|
||||
if client_id in lollmsElfServer.connections:
|
||||
if not lollmsElfServer.connections[client_id]["requested_stop"]:
|
||||
# Emit the generated text to the client
|
||||
lollmsElfServer.socketio.emit('text_generated', {'text': generated_text}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
except Exception as ex:
|
||||
lollmsElfServer.socketio.emit('generation_error', {'error': str(ex)}, room=client_id)
|
||||
ASCIIColors.error(f"\ndone")
|
||||
lollmsElfServer.busy = False
|
||||
else:
|
||||
try:
|
||||
personality: AIPersonality = lollmsElfServer.personalities[personality_id]
|
||||
ump = lollmsElfServer.config.discussion_prompt_separator +lollmsElfServer.config.user_name.strip() if lollmsElfServer.config.use_user_name_in_discussions else lollmsElfServer.personality.user_message_prefix
|
||||
personality.model = model
|
||||
cond_tk = personality.model.tokenize(personality.personality_conditioning)
|
||||
n_cond_tk = len(cond_tk)
|
||||
# Placeholder code for text generation
|
||||
# Replace this with your actual text generation logic
|
||||
print(f"Text generation requested by client: {client_id}")
|
||||
|
||||
lollmsElfServer.answer["full_text"] = ''
|
||||
full_discussion_blocks = lollmsElfServer.connections[client_id]["full_discussion_blocks"]
|
||||
|
||||
if prompt != '':
|
||||
if personality.processor is not None and personality.processor_cfg["process_model_input"]:
|
||||
preprocessed_prompt = personality.processor.process_model_input(prompt)
|
||||
else:
|
||||
preprocessed_prompt = prompt
|
||||
|
||||
if personality.processor is not None and personality.processor_cfg["custom_workflow"]:
|
||||
full_discussion_blocks.append(ump)
|
||||
full_discussion_blocks.append(preprocessed_prompt)
|
||||
|
||||
else:
|
||||
|
||||
full_discussion_blocks.append(ump)
|
||||
full_discussion_blocks.append(preprocessed_prompt)
|
||||
full_discussion_blocks.append(personality.link_text)
|
||||
full_discussion_blocks.append(personality.ai_message_prefix)
|
||||
|
||||
full_discussion = personality.personality_conditioning + ''.join(full_discussion_blocks)
|
||||
|
||||
def callback(text, message_type: MSG_TYPE, metadata:dict={}):
|
||||
if message_type == MSG_TYPE.MSG_TYPE_CHUNK:
|
||||
lollmsElfServer.answer["full_text"] = lollmsElfServer.answer["full_text"] + text
|
||||
lollmsElfServer.socketio.emit('text_chunk', {'chunk': text}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
try:
|
||||
if lollmsElfServer.connections[client_id]["requested_stop"]:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
except: # If the client is disconnected then we stop talking to it
|
||||
return False
|
||||
|
||||
tk = personality.model.tokenize(full_discussion)
|
||||
n_tokens = len(tk)
|
||||
fd = personality.model.detokenize(tk[-min(lollmsElfServer.config.ctx_size-n_cond_tk-personality.model_n_predicts,n_tokens):])
|
||||
|
||||
if personality.processor is not None and personality.processor_cfg["custom_workflow"]:
|
||||
ASCIIColors.info("processing...")
|
||||
generated_text = personality.processor.run_workflow(prompt, previous_discussion_text=personality.personality_conditioning+fd, callback=callback)
|
||||
else:
|
||||
ASCIIColors.info("generating...")
|
||||
generated_text = personality.model.generate(
|
||||
personality.personality_conditioning+fd,
|
||||
n_predict=personality.model_n_predicts,
|
||||
callback=callback)
|
||||
|
||||
if personality.processor is not None and personality.processor_cfg["process_model_output"]:
|
||||
generated_text = personality.processor.process_model_output(generated_text)
|
||||
|
||||
full_discussion_blocks.append(generated_text.strip())
|
||||
ASCIIColors.success("\ndone")
|
||||
|
||||
# Emit the generated text to the client
|
||||
lollmsElfServer.socketio.emit('text_generated', {'text': generated_text}, room=client_id)
|
||||
lollmsElfServer.socketio.sleep(0)
|
||||
except Exception as ex:
|
||||
lollmsElfServer.socketio.emit('generation_error', {'error': str(ex)}, room=client_id)
|
||||
ASCIIColors.error(f"\ndone")
|
||||
lollmsElfServer.busy = False
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
lollmsElfServer.socketio.emit('generation_error', {'error': str(ex)}, room=client_id)
|
||||
lollmsElfServer.busy = False
|
||||
|
||||
# Start the text generation task in a separate thread
|
||||
task = lollmsElfServer.socketio.start_background_task(target=generate_text)
|
@ -42,17 +42,24 @@ if __name__ == "__main__":
|
||||
config.port=args.port
|
||||
|
||||
LOLLMSElfServer.build_instance(config=config, lollms_paths=lollms_paths, socketio=sio)
|
||||
from lollms.server.endpoints.lollms_binding_files_server import router as lollms_binding_files_server_router
|
||||
from lollms.server.endpoints.lollms_infos import router as lollms_infos_router
|
||||
from lollms.server.endpoints.lollms_hardware_infos import router as lollms_hardware_infos_router
|
||||
from lollms.server.endpoints.lollms_binding_infos import router as lollms_binding_infos_router
|
||||
from lollms.server.endpoints.lollms_models_infos import router as lollms_models_infos_router
|
||||
from lollms.server.endpoints.lollms_personalities_infos import router as lollms_personalities_infos_router
|
||||
from lollms.server.endpoints.lollms_extensions_infos import router as lollms_extensions_infos_router
|
||||
|
||||
from lollms.server.endpoints.lollms_configuration_infos import router as lollms_configuration_infos_router
|
||||
|
||||
|
||||
|
||||
from lollms.server.endpoints.lollms_generator import router as lollms_generator_router
|
||||
|
||||
|
||||
from lollms.server.events.lollms_generation_events import add_events as lollms_generation_events_add
|
||||
|
||||
app.include_router(lollms_binding_files_server_router)
|
||||
app.include_router(lollms_infos_router)
|
||||
app.include_router(lollms_hardware_infos_router)
|
||||
app.include_router(lollms_binding_infos_router)
|
||||
@ -62,6 +69,12 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
app.include_router(lollms_generator_router)
|
||||
|
||||
app.include_router(lollms_configuration_infos_router)
|
||||
|
||||
|
||||
|
||||
lollms_generation_events_add(sio)
|
||||
app = ASGIApp(socketio_server=sio, other_asgi_app=app)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user