upgraded functions

This commit is contained in:
Saifeddine ALOUI 2024-05-20 20:35:10 +02:00
parent 1e50bf5224
commit 5e60a753c2
8 changed files with 64 additions and 24 deletions

View File

@ -0,0 +1,22 @@
import math
from functools import partial
def calculate(expression: str) -> float:
try:
# Add the math module functions to the local namespace
allowed_names = {k: v for k, v in math.__dict__.items() if not k.startswith("__")}
# Evaluate the expression safely using the allowed names
result = eval(expression, {"__builtins__": None}, allowed_names)
return result
except Exception as e:
return str(e)
def calculate_function(processor, client):
return {
"function_name": "calculate",
"function": calculate,
"function_description": "Whenever you need to perform mathematic computations, you can call this function with the math expression and you will get the answer.",
"function_parameters": [{"name": "expression", "type": "str"}]
}

View File

@ -72,7 +72,7 @@ class CameraWindow(QtWidgets.QWidget):
self.cap.release() self.cap.release()
event.accept() event.accept()
def take_photo(processor, client, use_ui=False): def take_photo(processor, client, use_ui=False, use_a_single_photo_at_a_time=True):
if use_ui: if use_ui:
def run_app(): def run_app():
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
@ -113,15 +113,17 @@ def take_photo(processor, client, use_ui=False):
fn = image/f"screen_shot_{index}.png" fn = image/f"screen_shot_{index}.png"
cv2.imwrite(str(fn), frame) cv2.imwrite(str(fn), frame)
client.discussion.image_files.append(fn) client.discussion.image_files.append(fn)
if use_a_single_photo_at_a_time:
client.discussion.image_files = [client.discussion.image_files[-1]]
processor.full(f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>') processor.full(f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>')
processor.new_message("") processor.new_message("")
return "Image shot successful" return "Image shot successful"
def take_a_photo_function(processor, client, use_ui = False): def take_a_photo_function(processor, client, use_ui = False, use_a_single_photo_at_a_time=True):
return { return {
"function_name": "take_photo", "function_name": "take_photo",
"function": partial(take_photo, processor=processor, client=client, use_ui = use_ui), "function": partial(take_photo, processor=processor, client=client, use_ui = use_ui, use_a_single_photo_at_a_time = use_a_single_photo_at_a_time),
"function_description": "Uses the webcam to take a photo, displays it so that you can take a look.", "function_description": "Uses the webcam to take a photo, displays it so that you can take a look.",
"function_parameters": [] "function_parameters": []
} }

View File

@ -14,12 +14,13 @@ from functools import partial
class ScreenshotWindow(QtWidgets.QWidget): class ScreenshotWindow(QtWidgets.QWidget):
def __init__(self, client, screenshot, fn_view, fn): def __init__(self, client, screenshot, fn_view, fn, use_a_single_photo_at_a_time= True):
super().__init__() super().__init__()
self.client = client self.client = client
self.screenshot = screenshot self.screenshot = screenshot
self.fn_view = fn_view self.fn_view = fn_view
self.fn = fn self.fn = fn
self.use_a_single_photo_at_a_time = use_a_single_photo_at_a_time
self.initUI() self.initUI()
@ -42,10 +43,13 @@ class ScreenshotWindow(QtWidgets.QWidget):
self.screenshot.save(self.fn_view) self.screenshot.save(self.fn_view)
self.screenshot.save(self.fn) self.screenshot.save(self.fn)
self.client.discussion.image_files.append(self.fn) self.client.discussion.image_files.append(self.fn)
if self.use_a_single_photo_at_a_time:
self.client.discussion.image_files = [self.client.discussion.image_files[-1]]
self.close() self.close()
def take_screenshot(self, client: Client, use_ui: bool = False): def take_screenshot(self, client: Client, use_ui: bool = False, use_a_single_photo_at_a_time= True):
screenshot = pyautogui.screenshot() screenshot = pyautogui.screenshot()
view_image = client.discussion.discussion_folder / "view_images" view_image = client.discussion.discussion_folder / "view_images"
image = client.discussion.discussion_folder / "images" image = client.discussion.discussion_folder / "images"
@ -55,7 +59,7 @@ def take_screenshot(self, client: Client, use_ui: bool = False):
if use_ui: if use_ui:
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
window = ScreenshotWindow(client, screenshot, fn_view, fn) window = ScreenshotWindow(client, screenshot, fn_view, fn, use_a_single_photo_at_a_time)
window.show() window.show()
app.exec_() app.exec_()
return f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>' return f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>'
@ -63,15 +67,15 @@ def take_screenshot(self, client: Client, use_ui: bool = False):
screenshot.save(fn_view) screenshot.save(fn_view)
screenshot.save(fn) screenshot.save(fn)
client.discussion.image_files.append(fn) client.discussion.image_files.append(fn)
if use_a_single_photo_at_a_time:
client.discussion.image_files = [client.discussion.image_files[-1]]
return f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>' return f'<img src="{discussion_path_to_url(fn_view)}" width="80%"></img>'
def take_screenshot_function(client): def take_screenshot_function(client, use_ui=True, use_a_single_photo_at_a_time= True):
return { return {
"function_name": "take_screenshot", "function_name": "take_screenshot",
"function": partial(take_screenshot, client=client), "function": partial(take_screenshot, client=client, use_ui = use_ui, use_a_single_photo_at_a_time= use_a_single_photo_at_a_time),
"function_description": "Takes a screenshot of the current screen. Optionally allows user interface for image cropping and saving.", "function_description": "Takes a screenshot of the current screen.",
"function_parameters": [ "function_parameters": []
{"name": "client", "type": "Client", "description": "The client object managing the discussion and images."},
{"name": "use_ui", "type": "bool", "default": False, "description": "Flag to determine if a user interface should be used for editing the screenshot."}
]
} }

View File

@ -148,7 +148,9 @@ class RTCom:
self.snd_input_device = snd_input_device self.snd_input_device = snd_input_device
self.snd_output_device = snd_output_device self.snd_output_device = snd_output_device
self.logs_folder = logs_folder self.logs_folder = Path(logs_folder)
self.logs_folder.mkdir(exist_ok=True, parents=True)
self.frames = [] self.frames = []
self.silence_counter = 0 self.silence_counter = 0

View File

@ -3435,12 +3435,14 @@ The AI should respond in this format using data from actions_list:
return function_calls return function_calls
def interact_with_function_call(self, prompt, function_definitions, prompt_after_execution=True, callback = None): def interact_with_function_call(self, prompt, function_definitions, prompt_after_execution=True, callback = None, hide_function_call=False):
if len(self.personality.image_files)>0: if len(self.personality.image_files)>0:
out, function_calls = self.generate_with_function_calls_and_images(prompt, self.personality.image_files, function_definitions, callback=callback) out, function_calls = self.generate_with_function_calls_and_images(prompt, self.personality.image_files, function_definitions, callback=callback)
else: else:
out, function_calls = self.generate_with_function_calls(prompt, function_definitions, callback=callback) out, function_calls = self.generate_with_function_calls(prompt, function_definitions, callback=callback)
if len(function_calls)>0: if len(function_calls)>0:
if hide_function_call:
self.full("") #Hide function call
outputs = self.execute_function_calls(function_calls,function_definitions) outputs = self.execute_function_calls(function_calls,function_definitions)
out += "\n!@>function calls results:\n" + "\n".join([str(o) for o in outputs]) out += "\n!@>function calls results:\n" + "\n".join([str(o) for o in outputs])
if prompt_after_execution: if prompt_after_execution:

View File

@ -109,6 +109,7 @@ class LollmsOpenAITTS(LollmsTTS):
def tts_file(self, text, speaker=None, file_name_or_path:Path|str=None, language="en", use_threading=False): def tts_file(self, text, speaker=None, file_name_or_path:Path|str=None, language="en", use_threading=False):
speech_file_path = file_name_or_path speech_file_path = file_name_or_path
text = self.clean_text(text)
response = self.client.audio.speech.create( response = self.client.audio.speech.create(
model=self.model, model=self.model,
voice=self.voice, voice=self.voice,

View File

@ -260,6 +260,7 @@ class LollmsXTTS(LollmsTTS):
return False return False
def tts_file(self, text, file_name_or_path, speaker=None, language="en")->str: def tts_file(self, text, file_name_or_path, speaker=None, language="en")->str:
text = self.clean_text(text)
url = f"{self.xtts_base_url}/tts_to_file" url = f"{self.xtts_base_url}/tts_to_file"
# Define the request body # Define the request body
@ -316,14 +317,7 @@ class LollmsXTTS(LollmsTTS):
return {"status":False,"error":f"{ex}"} return {"status":False,"error":f"{ex}"}
def xtts_audio(self, text, speaker, file_name_or_path:Path|str=None, language="en", use_threading=True): def xtts_audio(self, text, speaker, file_name_or_path:Path|str=None, language="en", use_threading=True):
# Remove HTML tags text = self.clean_text(text)
text = re.sub(r'<.*?>', '', text)
# Remove code blocks (assuming they're enclosed in backticks or similar markers)
text = re.sub(r'```.*?```', '', text, flags=re.DOTALL)
text = re.sub(r'`.*?`', '', text)
# Remove any remaining code-like patterns (this can be adjusted as needed)
text = re.sub(r'[\{\}\[\]\(\)<>]', '', text)
text = text.replace("\\","")
def tts2_audio_th(thread_uid=None): def tts2_audio_th(thread_uid=None):
url = f"{self.xtts_base_url}/tts_to_audio" url = f"{self.xtts_base_url}/tts_to_audio"

View File

@ -10,6 +10,7 @@ from lollms.app import LollmsApplication
from lollms.utilities import PackageManager from lollms.utilities import PackageManager
from pathlib import Path from pathlib import Path
from ascii_colors import ASCIIColors from ascii_colors import ASCIIColors
import re
try: try:
if not PackageManager.check_package_installed("sounddevice"): if not PackageManager.check_package_installed("sounddevice"):
# os.system("sudo apt-get install portaudio19-dev") # os.system("sudo apt-get install portaudio19-dev")
@ -148,3 +149,15 @@ class LollmsTTS:
"status": True, "status": True,
"device_names": [device['name'] for device in devices if device["max_output_channels"]>0] "device_names": [device['name'] for device in devices if device["max_output_channels"]>0]
} }
@staticmethod
def clean_text(text):
# Remove HTML tags
text = re.sub(r'<.*?>', '', text)
# Remove code blocks (assuming they're enclosed in backticks or similar markers)
text = re.sub(r'```.*?```', '', text, flags=re.DOTALL)
text = re.sub(r'`.*?`', '', text)
# Remove any remaining code-like patterns (this can be adjusted as needed)
text = re.sub(r'[\{\}\[\]\(\)<>]', '', text)
text = text.replace("\\","")
return text