enhanced endpoints and added events

This commit is contained in:
Saifeddine ALOUI 2024-01-07 03:14:20 +01:00
parent 9d8db7a0da
commit 8d122ba614
6 changed files with 846 additions and 1 deletions

View 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))

View 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}

View File

@ -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"}

View File

@ -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]}

View 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)

View File

@ -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)