This commit is contained in:
Saifeddine ALOUI 2025-04-08 16:39:17 +02:00
parent e649f1c4e3
commit e5cd49c9c4
5 changed files with 1501 additions and 75 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ class Client:
self.rag_databases = []
self.generated_text = ""
self.cancel_generation = False
self.generation_thread:Thread = None
self.generation_routine:Thread = None
self.processing = False
self.schedule_for_deletion = False
self.continuing = False

View File

@ -6,7 +6,7 @@ from enum import Enum
from lollms.types import MSG_OPERATION_TYPE
from lollms.templating import LollmsLLMTemplate
from typing import Any, List
import asyncio
class NotificationType(Enum):
"""Notification types."""
@ -54,9 +54,21 @@ class LoLLMsCom:
self.rt_com = None
self.model = None
try:
self.loop = asyncio.get_running_loop()
except Exception as ex:
self.loop = None
# Helper to schedule tasks - ensures self.loop is checked
def schedule_task(self, coro):
if self.loop:
# Create task schedules it, doesn't wait
self.loop.create_task(coro)
else:
# This ideally shouldn't happen if setup is correct
print(f"ERROR: Loop not available when trying to schedule {coro}")
def InfoMessage(self, content, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task( self.notify(
content,
notification_type=NotificationType.NOTIF_SUCCESS,
duration=0,
@ -64,18 +76,20 @@ class LoLLMsCom:
display_type=NotificationDisplayType.MESSAGE_BOX,
verbose=verbose
)
def ShowBlockingMessage(self, content, client_id=None, verbose:bool=None):
self.notify(
)
async def ShowBlockingMessage(self, content, client_id=None, verbose:bool=None):
self.schedule_task( self.notify(
content,
notification_type=NotificationType.NOTIF_SUCCESS,
duration=0,
client_id=client_id,
display_type=NotificationDisplayType.SHOW_BLOCKING_MESSAGE,
verbose=verbose
)
)
)
def HideBlockingMessage(self, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task( self.notify(
"",
notification_type=NotificationType.NOTIF_SUCCESS,
duration=0,
@ -83,10 +97,10 @@ class LoLLMsCom:
display_type=NotificationDisplayType.HIDE_BLOCKING_MESSAGE,
verbose=verbose
)
)
def YesNoMessage(self, content, duration:int=4, client_id=None, verbose:bool=None):
async def YesNoMessage(self, content, duration:int=4, client_id=None, verbose:bool=None):
infos={
"wait":True,
"result":False
@ -96,7 +110,7 @@ class LoLLMsCom:
infos["result"] = result["yesRes"]
infos["wait"]=False
self.notify(
await self.notify(
content,
notification_type=NotificationType.NOTIF_SUCCESS,
duration=duration,
@ -114,7 +128,7 @@ class LoLLMsCom:
pass
def info(self, content, duration:int=4, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task( self.notify(
content,
notification_type=NotificationType.NOTIF_SUCCESS,
duration=duration,
@ -122,9 +136,9 @@ class LoLLMsCom:
display_type=NotificationDisplayType.TOAST,
verbose=verbose
)
)
def warning(self, content, duration:int=4, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task(self.notify(
content,
notification_type=NotificationType.NOTIF_WARNING,
duration=duration,
@ -132,9 +146,10 @@ class LoLLMsCom:
display_type=NotificationDisplayType.TOAST,
verbose=verbose
)
)
def success(self, content, duration:int=4, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task(self.notify(
content,
notification_type=NotificationType.NOTIF_SUCCESS,
duration=duration,
@ -142,9 +157,9 @@ class LoLLMsCom:
display_type=NotificationDisplayType.TOAST,
verbose=verbose
)
)
def error(self, content, duration:int=4, client_id=None, verbose:bool=None):
self.notify(
self.schedule_task(self.notify(
content,
notification_type=NotificationType.NOTIF_ERROR,
duration=duration,
@ -152,8 +167,8 @@ class LoLLMsCom:
display_type=NotificationDisplayType.TOAST,
verbose = verbose
)
def new_message(self,
)
async def new_message(self,
client_id,
sender=None,
content="",
@ -165,6 +180,17 @@ class LoLLMsCom:
open=False
):
pass
async def start_message_generation(
self,
message,
message_id,
client_id,
is_continue=False,
generation_type=None,
force_using_internet=False,
):
pass
def set_message_content(self, full_text:str, callback: Callable[[str | list | None, MSG_OPERATION_TYPE, str, Any | None], bool]=None):
"""This sends full text to front end
@ -178,7 +204,7 @@ class LoLLMsCom:
def emit_socket_io_info(self, name, data, client_id):
pass
def notify(
async def notify(
self,
content:str,
notification_type:NotificationType=NotificationType.NOTIF_SUCCESS,
@ -201,7 +227,7 @@ class LoLLMsCom:
ASCIIColors.red(content)
def notify_model_install(self,
async def notify_model_install(self,
installation_path,
model_name,
binding_folder,

View File

@ -85,14 +85,7 @@ class LOLLMSElfServer(LollmsApplication):
return full_path
return None
def prepare_reception(self, client_id):
if not self.session.get_client(client_id).continuing:
self.session.get_client(client_id).generated_text = ""
self.session.get_client(client_id).first_chunk=True
self.nb_received_tokens = 0
self.start_time = datetime.now()
def notify_model_install(self,
installation_path,

View File

@ -30,13 +30,13 @@ lollmsElfServer = LOLLMSElfServer.get_instance()
# ----------------------------------- events -----------------------------------------
def add_events(sio:socketio):
@sio.on('cancel_generation')
def cancel_generation(sid):
async def cancel_generation(sid):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
lollmsElfServer.cancel_gen = True
#kill thread
ASCIIColors.error(f'Client {sid} requested cancelling generation')
terminate_thread(client.generation_thread)
client.generation_routine.cancel()
lollmsElfServer.busy=False
if lollmsElfServer.tts:
lollmsElfServer.tts.stop()
@ -45,18 +45,18 @@ def add_events(sio:socketio):
@sio.on('cancel_text_generation')
def cancel_text_generation(sid, data):
async def cancel_text_generation(sid, data):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
client.requested_stop=True
print(f"Client {client_id} requested canceling generation")
run_async(partial(lollmsElfServer.sio.emit,"generation_canceled", {"message":"Generation is canceled."}, to=client_id))
lollmsElfServer.sio.emit("generation_canceled", {"message":"Generation is canceled."}, to=client_id)
lollmsElfServer.busy = False
# A copy of the original lollms-server generation code needed for playground
@sio.on('generate_text')
def handle_generate_text(sid, data):
async def handle_generate_text(sid, data):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
lollmsElfServer.cancel_gen = False
@ -138,7 +138,7 @@ def add_events(sio:socketio):
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
ump = 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)
@ -210,8 +210,8 @@ def add_events(sio:socketio):
ASCIIColors.error(f"\ndone")
lollmsElfServer.busy = False
client.generation_thread = threading.Thread(target=do_generation)
client.generation_thread.start()
client.generation_routine = threading.Thread(target=do_generation)
client.generation_routine.start()
lollmsElfServer.busy=True
except Exception as ex:
@ -224,7 +224,7 @@ def add_events(sio:socketio):
@sio.on('generate_msg')
def generate_msg(sid, data):
async def generate_msg(sid, data):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
lollmsElfServer.cancel_gen = False
@ -248,26 +248,17 @@ def add_events(sio:socketio):
lollmsElfServer.session.get_client(client_id).discussion = lollmsElfServer.db.load_last_discussion()
prompt = data["prompt"]
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
try:
nb_tokens = len(lollmsElfServer.model.tokenize(prompt))
except:
nb_tokens = None
created_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
message = lollmsElfServer.session.get_client(client_id).discussion.add_message(
message_type = MSG_OPERATION_TYPE.MSG_OPERATION_TYPE_SET_CONTENT.value,
sender_type = SENDER_TYPES.SENDER_TYPES_USER.value,
sender = ump.replace(lollmsElfServer.config.discussion_prompt_separator,"").replace(":",""),
content=prompt,
metadata=None,
parent_message_id=lollmsElfServer.message_id,
created_at=created_at,
nb_tokens=nb_tokens
ump = lollmsElfServer.config.user_name.strip() if lollmsElfServer.config.use_user_name_in_discussions else lollmsElfServer.personality.user_message_prefix
message = await lollmsElfServer.new_message(client_id, ump, prompt)
await lollmsElfServer.update_message_step(
client_id,
"🔥 warming up ...",
MSG_OPERATION_TYPE.MSG_OPERATION_TYPE_STEP_END_SUCCESS,
)
ASCIIColors.green("Starting message generation by "+lollmsElfServer.personality.name)
client.generation_thread = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message.id, client_id))
client.generation_thread.start()
await lollmsElfServer.start_message_generation(message, message.id, client_id)
# client.generation_routine = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message.id, client_id))
# client.generation_routine.start()
lollmsElfServer.busy=True
#tpe = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message_id, client_id))
#tpe.start()
@ -275,7 +266,7 @@ def add_events(sio:socketio):
lollmsElfServer.error("I am busy. Come back later.", client_id=client_id)
@sio.on('generate_msg_from')
def generate_msg_from(sid, data):
async def generate_msg_from(sid, data):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
lollmsElfServer.cancel_gen = False
@ -294,11 +285,10 @@ def add_events(sio:socketio):
message = lollmsElfServer.session.get_client(client_id).discussion.load_message(id_)
if message is None:
return
client.generation_thread = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message.id, client_id, False, generation_type))
client.generation_thread.start()
await lollmsElfServer.start_message_generation(message, message.id, client_id, True)
@sio.on('continue_generate_msg_from')
def handle_connection(sid, data):
async def handle_connection(sid, data):
client_id = sid
client = lollmsElfServer.session.get_client(client_id)
lollmsElfServer.cancel_gen = False
@ -316,5 +306,4 @@ def add_events(sio:socketio):
message = lollmsElfServer.session.get_client(client_id).discussion.load_message(id_)
client.generated_text=message.content
client.generation_thread = threading.Thread(target=lollmsElfServer.start_message_generation, args=(message, message.id, client_id, True))
client.generation_thread.start()
await lollmsElfServer.start_message_generation(message, message.id, client_id, True)