From a4968f02598b66a4b0dfe6702109d2597458c241 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:00:55 -0600 Subject: [PATCH 1/6] Filter improvements fixes pixelart --- .../data/bootstrap/imagefilter_bootstrap_data.py | 6 +++--- src/airunner/filters/base_filter.py | 3 +++ src/airunner/filters/pixel_art.py | 12 +++++++++--- src/airunner/widgets/slider/filter_slider_widget.py | 1 - 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/airunner/data/bootstrap/imagefilter_bootstrap_data.py b/src/airunner/data/bootstrap/imagefilter_bootstrap_data.py index 4808e0c59..cbcc3dc45 100644 --- a/src/airunner/data/bootstrap/imagefilter_bootstrap_data.py +++ b/src/airunner/data/bootstrap/imagefilter_bootstrap_data.py @@ -14,10 +14,10 @@ }, 'smoothing': { 'name': 'smoothing', - 'value': '1', + 'value': '0', 'value_type': 'int', - 'min_value': None, - 'max_value': None + 'min_value': '0', + 'max_value': '100' }, 'base_size': { 'name': 'base_size', diff --git a/src/airunner/filters/base_filter.py b/src/airunner/filters/base_filter.py index 53dceffe8..323853a12 100644 --- a/src/airunner/filters/base_filter.py +++ b/src/airunner/filters/base_filter.py @@ -1,9 +1,12 @@ from PIL import ImageFilter +from airunner.handlers.logger import Logger + class BaseFilter(ImageFilter.Filter): def __init__(self, **kwargs): super().__init__() + self.logger = Logger(prefix=self.__class__.__name__) self.image = None self.image_id = None diff --git a/src/airunner/filters/pixel_art.py b/src/airunner/filters/pixel_art.py index 8354d4be4..6227cd3c4 100644 --- a/src/airunner/filters/pixel_art.py +++ b/src/airunner/filters/pixel_art.py @@ -1,14 +1,15 @@ -from PIL import Image +from PIL import Image, ImageFilter from airunner.filters.base_filter import BaseFilter - class PixelFilter(BaseFilter): current_number_of_colors = 0 + smoothing = 0 # Default smoothing value def apply_filter(self, image, do_reset): # Reduce number of colors number_of_colors = getattr(self, "number_of_colors", 24) base_size = getattr(self, "base_size", 256) + smoothing = getattr(self, "smoothing", 0) # ensure number_of_colors is an integer divisible by 2 number_of_colors = int(number_of_colors) // 2 * 2 if self.current_number_of_colors != number_of_colors or do_reset: @@ -17,7 +18,7 @@ def apply_filter(self, image, do_reset): quantized = image.quantize(number_of_colors) self.image = quantized.convert("RGBA") except ValueError: - print("Bad number of colors") + self.logger.debug("Bad number of colors") image = self.image # Downsize while maintaining aspect ratio @@ -32,4 +33,9 @@ def apply_filter(self, image, do_reset): target_height = int(new_height / scale) final_image = downsized.resize((target_width, target_height), Image.Resampling.NEAREST) + # Apply smoothing if enabled + if smoothing > 0: + for _ in range(smoothing // 10): # Apply smoothing filter multiple times + final_image = final_image.filter(ImageFilter.SMOOTH) + return final_image diff --git a/src/airunner/widgets/slider/filter_slider_widget.py b/src/airunner/widgets/slider/filter_slider_widget.py index 72eadb345..990f53a6e 100644 --- a/src/airunner/widgets/slider/filter_slider_widget.py +++ b/src/airunner/widgets/slider/filter_slider_widget.py @@ -5,7 +5,6 @@ class FilterSliderWidget(SliderWidget): def __init__(self, *args, session, filter_value, preview_filter, **kwargs): - self.session = session self._filter_value = filter_value self.preview_filter = preview_filter super().__init__(*args, **kwargs) From 5b5d87dce19935950e1006f8446f821ddc98172f Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:01:18 -0600 Subject: [PATCH 2/6] remove print debugging from box blur --- src/airunner/filters/box_blur.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/airunner/filters/box_blur.py b/src/airunner/filters/box_blur.py index e80e1adb3..811184cd5 100644 --- a/src/airunner/filters/box_blur.py +++ b/src/airunner/filters/box_blur.py @@ -4,5 +4,4 @@ class BoxBlur(BaseFilter): def apply_filter(self, image, do_reset=False): - print("APPLY FILTER") return image.filter(ImageFilterBoxBlur(radius=self.radius)) From bda4e19832a8cc0972b13d539806a038d66d9a69 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:03:29 -0600 Subject: [PATCH 3/6] bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fa187152d..e0697abcd 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="airunner", - version="3.1.1", + version="3.1.2", author="Capsize LLC", description="A Stable Diffusion GUI", long_description=open("README.md", "r", encoding="utf-8").read(), From 3cf8d879f388bc561b712adc82b119eb97f5797b Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:16:07 -0600 Subject: [PATCH 4/6] improvement to saftey checker load balancing to prevent memory error --- src/airunner/handlers/stablediffusion/sd_handler.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/airunner/handlers/stablediffusion/sd_handler.py b/src/airunner/handlers/stablediffusion/sd_handler.py index 95c3c6eb4..bc5518dfa 100644 --- a/src/airunner/handlers/stablediffusion/sd_handler.py +++ b/src/airunner/handlers/stablediffusion/sd_handler.py @@ -698,6 +698,8 @@ def _check_and_mark_nsfw_images(self, images) -> tuple: if not self._feature_extractor or not self._safety_checker: return images, [False] * len(images) + self._safety_checker.to(self._device) + safety_checker_input = self._feature_extractor(images, return_tensors="pt").to(self._device) _, has_nsfw_concepts = self._safety_checker( images=[np.array(img) for img in images], @@ -730,6 +732,8 @@ def _check_and_mark_nsfw_images(self, images) -> tuple: images[i] = img + self._safety_checker.to("cpu") + return images, has_nsfw_concepts def _load_safety_checker(self): @@ -755,7 +759,7 @@ def _load_safety_checker_model(self): self._safety_checker = StableDiffusionSafetyChecker.from_pretrained( safety_checker_path, torch_dtype=self.data_type, - device_map=self._device, + device_map="cpu", local_files_only=True, use_safetensors=False ) @@ -781,7 +785,6 @@ def _load_feature_extractor(self): self._feature_extractor = CLIPFeatureExtractor.from_pretrained( feature_extractor_path, torch_dtype=self.data_type, - device_map=self._device, local_files_only=True, use_safetensors=True ) From fe808ab3cc02f6b6c4096c7306bf0ff2348988f8 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 01:40:17 -0600 Subject: [PATCH 5/6] Improved design of LLM history --- src/airunner/resources_rc.py | 92 +++++------ .../widgets/llm/llm_history_item_widget.py | 50 ++++++ .../widgets/llm/llm_history_widget.py | 28 +--- .../widgets/llm/templates/llm_history_item.ui | 150 ++++++++++++++++++ .../llm/templates/llm_history_item_ui.py | 105 ++++++++++++ 5 files changed, 357 insertions(+), 68 deletions(-) create mode 100644 src/airunner/widgets/llm/llm_history_item_widget.py create mode 100644 src/airunner/widgets/llm/templates/llm_history_item.ui create mode 100644 src/airunner/widgets/llm/templates/llm_history_item_ui.py diff --git a/src/airunner/resources_rc.py b/src/airunner/resources_rc.py index a343137b9..f8cf9938e 100644 --- a/src/airunner/resources_rc.py +++ b/src/airunner/resources_rc.py @@ -8067,97 +8067,97 @@ \x00\x00\x00\x10\x00\x02\x00\x00\x00.\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00m\xe5\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x082\x00\x00\x00\x00\x00\x01\x00\x01\xbev\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x06\xae\x00\x00\x00\x00\x00\x01\x00\x01oa\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x08T\x00\x00\x00\x00\x00\x01\x00\x01\xc5Z\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x03\x92\x00\x00\x00\x00\x00\x01\x00\x00\x9b]\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x03n\x00\x00\x00\x00\x00\x01\x00\x00\x94\xf9\ -\x00\x00\x01\x92n\xe1\xd8\x16\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00&\x16\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x05F\x00\x00\x00\x00\x00\x01\x00\x01\x01Z\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x04\xb6\x00\x00\x00\x00\x00\x01\x00\x00\xe0C\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x01*\x00\x00\x00\x00\x00\x01\x00\x007r\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x00\xa4\x12\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x19\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x07\xbc\x00\x00\x00\x00\x00\x01\x00\x01\xa7\x89\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00{\x97\ -\x00\x00\x01\x92n\xe1\xd8\x16\ +\x00\x00\x01\x92\xba\xea\xcb\x89\ \x00\x00\x03J\x00\x00\x00\x00\x00\x01\x00\x00\x8cT\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x05\xea\x00\x00\x00\x00\x00\x01\x00\x01\x1e\xa2\ -\x00\x00\x01\x92n\xe1\xd8\x16\ +\x00\x00\x01\x92\xba\xea\xcb\x89\ \x00\x00\x06X\x00\x00\x00\x00\x00\x01\x00\x013b\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x06~\x00\x00\x00\x00\x00\x01\x00\x01=\x1c\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xbf\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x03\x18\x00\x00\x00\x00\x00\x01\x00\x00\x82X\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x04\xea\x00\x00\x00\x00\x00\x01\x00\x00\xe82\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x05n\x00\x00\x00\x00\x00\x01\x00\x01\x07\xbe\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x00p\x00\x00\x00\x00\x00\x01\x00\x00\x17\x09\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x08\x0a\x00\x00\x00\x00\x00\x01\x00\x01\xb7\x00\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x07X\x00\x00\x00\x00\x00\x01\x00\x01\x90\x8c\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x05\xb8\x00\x00\x00\x00\x00\x01\x00\x01\x0e\xc9\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x04t\x00\x00\x00\x00\x00\x01\x00\x00\xd8\xaf\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x06\x1a\x00\x00\x00\x00\x00\x01\x00\x01+\xd1\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x04 \x00\x00\x00\x00\x00\x01\x00\x00\xb3\xae\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x07\x84\x00\x00\x00\x00\x00\x01\x00\x01\x97\xd9\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x07\xe8\x00\x00\x00\x00\x00\x01\x00\x01\xae\xab\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00gF\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcd>\ \x00\x00\x04D\x00\x00\x00\x00\x00\x01\x00\x00\xbaK\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x000\x84\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x01\xb0\x00\x00\x00\x00\x00\x01\x00\x00F\x5c\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x03\xee\x00\x04\x00\x00\x00\x01\x00\x00\xab`\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xf7g\x80\ \x00\x00\x01Z\x00\x04\x00\x00\x00\x01\x00\x00@\xe4\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x06\xd0\x00\x00\x00\x00\x00\x01\x00\x01v\xda\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x01\xe2\x00\x00\x00\x00\x00\x01\x00\x00Mi\ -\x00\x00\x01\x92n\xe1\xd8\x13\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x05\x1a\x00\x00\x00\x00\x00\x01\x00\x00\xf76\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcb\x87\ \x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00S\xd6\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ \x00\x00\x07\x12\x00\x00\x00\x00\x00\x01\x00\x01}\x88\ -\x00\x00\x01\x92n\xe1\xd8\x16\ +\x00\x00\x01\x92\xba\xea\xcb\x89\ \x00\x00\x02d\x00\x00\x00\x00\x00\x01\x00\x00Z\x8c\ -\x00\x00\x01\x92n\xe1\xd8\x12\ +\x00\x00\x01\x92\xba\xea\xcb\x86\ \x00\x00\x08\x80\x00\x00\x00\x00\x00\x01\x00\x01\xd6\xbe\ -\x00\x00\x01\x92n\xe1\xd8\x14\ +\x00\x00\x01\x92\xba\xea\xcd?\ \x00\x00\x072\x00\x00\x00\x00\x00\x01\x00\x01\x87\xd0\ -\x00\x00\x01\x92n\xe1\xd8\x15\ +\x00\x00\x01\x92\xba\xea\xcb\x88\ " def qInitResources(): diff --git a/src/airunner/widgets/llm/llm_history_item_widget.py b/src/airunner/widgets/llm/llm_history_item_widget.py new file mode 100644 index 000000000..19684eac0 --- /dev/null +++ b/src/airunner/widgets/llm/llm_history_item_widget.py @@ -0,0 +1,50 @@ +# airunner/widgets/llm/llm_history_widget.py +from PySide6.QtCore import Slot +from PySide6.QtWidgets import QVBoxLayout, QPushButton, QSpacerItem, QSizePolicy, QHBoxLayout, QWidget, QLabel + +from airunner.data.models.settings_models import Message, LLMGeneratorSettings +from airunner.enums import SignalCode +from airunner.widgets.base_widget import BaseWidget +from airunner.widgets.llm.templates.llm_history_item_ui import Ui_llm_history_item_widget + + +class LLMHistoryItemWidget(BaseWidget): + widget_class_ = Ui_llm_history_item_widget + + def __init__(self, *args, **kwargs): + self.conversation = kwargs.pop("conversation") + super(LLMHistoryItemWidget, self).__init__(*args, **kwargs) + self.spacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) + + self.ui.conversation_description.setText(self.conversation.title) + + first_message = self.session.query(Message).filter_by(conversation_id=self.conversation.id).first() + chatbot_name = "Unknown" + if first_message and first_message.chatbot_id: + chatbot = self.get_chatbot_by_id(first_message.chatbot_id) + if chatbot: + chatbot_name = chatbot.name + + self.ui.botname.setText(chatbot_name) + self.ui.timestamp.setText(str(self.conversation.timestamp)) + + @Slot() + def action_load_conversation_clicked(self): + first_message = self.session.query(Message).filter_by(conversation_id=self.conversation.id).first() + chatbot_id = first_message.chatbot_id + self.session.query(LLMGeneratorSettings).update({"current_chatbot": chatbot_id}) + self.session.commit() + self.emit_signal(SignalCode.LOAD_CONVERSATION, { + "conversation_id": self.conversation.id, + "chatbot_id": chatbot_id + }) + + @Slot() + def action_delete_conversation_clicked(self): + conversation_id = self.conversation.id + self.delete_conversation(conversation_id) + self.emit_signal(SignalCode.CONVERSATION_DELETED, { + "conversation_id": conversation_id + }) + self.setParent(None) + self.deleteLater() diff --git a/src/airunner/widgets/llm/llm_history_widget.py b/src/airunner/widgets/llm/llm_history_widget.py index e814b72c1..0834e6c9d 100644 --- a/src/airunner/widgets/llm/llm_history_widget.py +++ b/src/airunner/widgets/llm/llm_history_widget.py @@ -5,6 +5,7 @@ from airunner.data.models.settings_models import Message, LLMGeneratorSettings from airunner.enums import SignalCode from airunner.widgets.base_widget import BaseWidget +from airunner.widgets.llm.llm_history_item_widget import LLMHistoryItemWidget from airunner.widgets.llm.templates.llm_history_widget_ui import Ui_llm_history_widget class LLMHistoryWidget(BaseWidget): @@ -42,28 +43,11 @@ def load_conversations(self): self.ui.scrollAreaWidgetContents.setLayout(layout) for conversation in conversations: - h_layout = QHBoxLayout() - button = QPushButton(conversation.title) - button.clicked.connect(lambda _, c=conversation: self.on_conversation_click(c)) - - # Extract chatbot_id from the first message of the conversation - first_message = self.session.query(Message).filter_by(conversation_id=conversation.id).first() - chatbot_name = "Unknown" - if first_message and first_message.chatbot_id: - chatbot = self.get_chatbot_by_id(first_message.chatbot_id) - if chatbot: - chatbot_name = chatbot.name - - chatbot_label = QLabel(f"Chatbot: {chatbot_name}") - delete_button = QPushButton("Delete") - delete_button.clicked.connect(lambda _, widget=h_layout, c=conversation: self.on_delete_conversation(widget, c)) - h_layout.addWidget(button) - h_layout.addWidget(chatbot_label) - h_layout.addWidget(delete_button) - - container_widget = QWidget() - container_widget.setLayout(h_layout) - layout.addWidget(container_widget) + llm_history_item_widget = LLMHistoryItemWidget( + conversation=conversation + ) + # add to layout + layout.addWidget(llm_history_item_widget) # Add a vertical spacer at the end layout.addItem(self.spacer) diff --git a/src/airunner/widgets/llm/templates/llm_history_item.ui b/src/airunner/widgets/llm/templates/llm_history_item.ui new file mode 100644 index 000000000..5b603c953 --- /dev/null +++ b/src/airunner/widgets/llm/templates/llm_history_item.ui @@ -0,0 +1,150 @@ + + + llm_history_item_widget + + + + 0 + 0 + 384 + 217 + + + + Form + + + + 10 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + + + + 5 + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Date + + + + + + + Qt::Orientation::Vertical + + + + + + + Bot name + + + + + + + Qt::Orientation::Vertical + + + + + + + Load conversation + + + + + + + + + + + + + Deleted conversation + + + + + + + + + + + + + + + + + pushButton + clicked() + llm_history_item_widget + action_load_conversation_clicked() + + + 406 + 262 + + + 322 + -17 + + + + + pushButton_2 + clicked() + llm_history_item_widget + action_delete_conversation_clicked() + + + 440 + 258 + + + 378 + -11 + + + + + + action_load_conversation_clicked() + action_delete_conversation_clicked() + + diff --git a/src/airunner/widgets/llm/templates/llm_history_item_ui.py b/src/airunner/widgets/llm/templates/llm_history_item_ui.py new file mode 100644 index 000000000..4488eba50 --- /dev/null +++ b/src/airunner/widgets/llm/templates/llm_history_item_ui.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'llm_history_item.ui' +## +## Created by: Qt User Interface Compiler version 6.7.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QHBoxLayout, + QLabel, QPushButton, QSizePolicy, QSpacerItem, + QTextBrowser, QWidget) + +class Ui_llm_history_item_widget(object): + def setupUi(self, llm_history_item_widget): + if not llm_history_item_widget.objectName(): + llm_history_item_widget.setObjectName(u"llm_history_item_widget") + llm_history_item_widget.resize(384, 217) + self.gridLayout = QGridLayout(llm_history_item_widget) + self.gridLayout.setSpacing(10) + self.gridLayout.setObjectName(u"gridLayout") + self.gridLayout.setContentsMargins(10, 0, 0, 0) + self.conversation_description = QTextBrowser(llm_history_item_widget) + self.conversation_description.setObjectName(u"conversation_description") + + self.gridLayout.addWidget(self.conversation_description, 0, 0, 1, 1) + + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setSpacing(5) + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + + self.horizontalLayout.addItem(self.horizontalSpacer) + + self.timestamp = QLabel(llm_history_item_widget) + self.timestamp.setObjectName(u"timestamp") + + self.horizontalLayout.addWidget(self.timestamp) + + self.line = QFrame(llm_history_item_widget) + self.line.setObjectName(u"line") + self.line.setFrameShape(QFrame.Shape.VLine) + self.line.setFrameShadow(QFrame.Shadow.Sunken) + + self.horizontalLayout.addWidget(self.line) + + self.botname = QLabel(llm_history_item_widget) + self.botname.setObjectName(u"botname") + + self.horizontalLayout.addWidget(self.botname) + + self.line_2 = QFrame(llm_history_item_widget) + self.line_2.setObjectName(u"line_2") + self.line_2.setFrameShape(QFrame.Shape.VLine) + self.line_2.setFrameShadow(QFrame.Shadow.Sunken) + + self.horizontalLayout.addWidget(self.line_2) + + self.pushButton = QPushButton(llm_history_item_widget) + self.pushButton.setObjectName(u"pushButton") + icon = QIcon(QIcon.fromTheme(u"document-open")) + self.pushButton.setIcon(icon) + + self.horizontalLayout.addWidget(self.pushButton) + + self.pushButton_2 = QPushButton(llm_history_item_widget) + self.pushButton_2.setObjectName(u"pushButton_2") + icon1 = QIcon(QIcon.fromTheme(u"user-trash")) + self.pushButton_2.setIcon(icon1) + + self.horizontalLayout.addWidget(self.pushButton_2) + + + self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1) + + + self.retranslateUi(llm_history_item_widget) + self.pushButton.clicked.connect(llm_history_item_widget.action_load_conversation_clicked) + self.pushButton_2.clicked.connect(llm_history_item_widget.action_delete_conversation_clicked) + + QMetaObject.connectSlotsByName(llm_history_item_widget) + # setupUi + + def retranslateUi(self, llm_history_item_widget): + llm_history_item_widget.setWindowTitle(QCoreApplication.translate("llm_history_item_widget", u"Form", None)) + self.timestamp.setText(QCoreApplication.translate("llm_history_item_widget", u"Date", None)) + self.botname.setText(QCoreApplication.translate("llm_history_item_widget", u"Bot name", None)) +#if QT_CONFIG(tooltip) + self.pushButton.setToolTip(QCoreApplication.translate("llm_history_item_widget", u"Load conversation", None)) +#endif // QT_CONFIG(tooltip) + self.pushButton.setText("") +#if QT_CONFIG(tooltip) + self.pushButton_2.setToolTip(QCoreApplication.translate("llm_history_item_widget", u"Deleted conversation", None)) +#endif // QT_CONFIG(tooltip) + self.pushButton_2.setText("") + # retranslateUi + From 5a6487fca68cf1d802b807775091665f2b4fc4f2 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Thu, 24 Oct 2024 02:10:43 -0600 Subject: [PATCH 6/6] move bot mood to conversation model rather that chatbot model this change prevents previous chatbot moods from carrying over into new conversations. the problem was that the mood was persistent and sometimes contained information from previous chats making it seem like the conversation was cached. --- ...ff7468e8_move_bot_mood_from_chatbot_to_.py | 42 +++ src/airunner/data/models/settings_models.py | 2 +- src/airunner/handlers/llm/agent/base_agent.py | 34 +- .../generator_form/generator_form_widget.py | 13 +- src/airunner/widgets/llm/bot_preferences.py | 4 - .../widgets/llm/chat_prompt_widget.py | 3 +- .../widgets/llm/llm_history_item_widget.py | 1 + .../widgets/llm/llm_history_widget.py | 1 + .../widgets/llm/templates/bot_preferences.ui | 300 +++++++----------- .../llm/templates/bot_preferences_ui.py | 234 +++++++------- src/airunner/windows/main/settings_mixin.py | 9 +- 11 files changed, 303 insertions(+), 340 deletions(-) create mode 100644 src/airunner/alembic/versions/f403ff7468e8_move_bot_mood_from_chatbot_to_.py diff --git a/src/airunner/alembic/versions/f403ff7468e8_move_bot_mood_from_chatbot_to_.py b/src/airunner/alembic/versions/f403ff7468e8_move_bot_mood_from_chatbot_to_.py new file mode 100644 index 000000000..8a280a1ed --- /dev/null +++ b/src/airunner/alembic/versions/f403ff7468e8_move_bot_mood_from_chatbot_to_.py @@ -0,0 +1,42 @@ +"""Move bot_mood from Chatbot to Conversation + +Revision ID: f403ff7468e8 +Revises: 536e18463461 +Create Date: 2024-10-24 01:43:30.378281 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import sqlite + +# revision identifiers, used by Alembic. +revision: str = 'f403ff7468e8' +down_revision: Union[str, None] = '536e18463461' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + +def upgrade(): + try: + # Add bot_mood column to conversation table + op.add_column('conversations', sa.Column('bot_mood', sa.Text(), nullable=True)) + except sqlite.DatabaseError: + pass + + try: + # Remove bot_mood column from chatbot table + op.drop_column('chatbots', 'bot_mood') + except sqlite.DatabaseError: + pass + +def downgrade(): + try: + op.add_column('chatbots', sa.Column('bot_mood', sa.Text(), nullable=True)) + except sqlite.DatabaseError: + pass + + try: + op.drop_column('conversations', 'bot_mood') + except sqlite.DatabaseError: + pass diff --git a/src/airunner/data/models/settings_models.py b/src/airunner/data/models/settings_models.py index 2700481d9..b6000dcbf 100644 --- a/src/airunner/data/models/settings_models.py +++ b/src/airunner/data/models/settings_models.py @@ -354,7 +354,6 @@ class Chatbot(Base): use_datetime = Column(Boolean, default=True) assign_names = Column(Boolean, default=True) bot_personality = Column(Text, default="happy. He loves {{ username }}") - bot_mood = Column(Text, default="") prompt_template = Column(Text, default="Mistral 7B Instruct: Default Chatbot") use_tool_filter = Column(Boolean, default=False) use_gpu = Column(Boolean, default=True) @@ -546,6 +545,7 @@ class Conversation(Base): timestamp = Column(DateTime, default=datetime.datetime.now(datetime.timezone.utc)) title = Column(String, nullable=True) # New column added messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan") + bot_mood = Column(Text, default="") class Message(Base): diff --git a/src/airunner/handlers/llm/agent/base_agent.py b/src/airunner/handlers/llm/agent/base_agent.py index ee1c37d73..01ab7d33d 100644 --- a/src/airunner/handlers/llm/agent/base_agent.py +++ b/src/airunner/handlers/llm/agent/base_agent.py @@ -94,6 +94,7 @@ def __init__(self, *args, **kwargs): self.is_mistral = kwargs.pop("is_mistral", True) self.conversation_id = None self.conversation_title = None + self.conversation = None self.history = self.load_history_from_db(self.conversation_id) # Load history by conversation ID super().__init__(*args, **kwargs) self.prompt = "" @@ -136,14 +137,16 @@ def botname(self) -> str: @property def bot_mood(self) -> str: - return self.chatbot.bot_mood + return self.conversation.bot_mood if self.conversation else "" @bot_mood.setter def bot_mood(self, value: str): - chatbot = self.chatbot - chatbot.bot_mood = value - self.save_object(chatbot) - self.emit_signal(SignalCode.BOT_MOOD_UPDATED) + conversation = self.conversation + conversation.bot_mood = value + self.save_object(conversation) + self.emit_signal(SignalCode.BOT_MOOD_UPDATED, { + "mood": value + }) @property def bot_personality(self) -> str: @@ -241,17 +244,11 @@ def _update_conversation_title(self, title): def _create_conversation(self): # Get the most recent conversation ID - recent_conversation_id = self.get_most_recent_conversation_id() - - # Check if there are messages for the most recent conversation ID - if recent_conversation_id is not None: - messages = self.load_history_from_db(recent_conversation_id) - if not messages: - self.conversation_id = recent_conversation_id - return - - # If there are messages or no recent conversation ID, create a new conversation - self.conversation_id = self.create_conversation() + self.conversation = self.get_most_recent_conversation() + if not self.conversation: + self.conversation = self.create_conversation() + self.conversation_id = self.conversation.id + self.history = self.load_history_from_db(self.conversation_id) def interrupt_process(self): self.do_interrupt = True @@ -818,7 +815,12 @@ def add_message_to_history( def on_load_conversation(self, message): self.history = [] + self.conversation = message["conversation"] self.conversation_id = message["conversation_id"] + + # Merge the conversation object into the current session + self.conversation = self.session.merge(self.conversation) + self.history = self.load_history_from_db(self.conversation_id) self.set_conversation_title() self.emit_signal(SignalCode.SET_CONVERSATION, { diff --git a/src/airunner/widgets/generator_form/generator_form_widget.py b/src/airunner/widgets/generator_form/generator_form_widget.py index 1357a2d0a..cf00d140e 100644 --- a/src/airunner/widgets/generator_form/generator_form_widget.py +++ b/src/airunner/widgets/generator_form/generator_form_widget.py @@ -91,6 +91,7 @@ class GeneratorForm(BaseWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.conversation = None self.seed_override = None self.parent = None self.initialized = False @@ -157,8 +158,8 @@ def on_keyboard_shortcuts_updated(self): def on_application_settings_changed_signal(self, _data): self.toggle_secondary_prompts() - def on_bot_mood_updated(self): - self._set_chatbot_mood() + def on_bot_mood_updated(self, data): + self._set_chatbot_mood(data["mood"]) def on_generate_image_signal(self, _data): self.handle_generate_button_clicked() @@ -254,13 +255,15 @@ def finalize_image_generated_by_llm(self, data): # End LLM Generated Image handlers ########################################################################## - def _set_chatbot_mood(self): - self.ui.mood_label.setText(self.chatbot.bot_mood) + def _set_chatbot_mood(self, mood=None): + self.ui.mood_label.setText(mood if mood else self.conversation.bot_mood if self.conversation else "") def handle_generate_image_from_image(self, image): pass - def on_load_conversation(self, _data): + def on_load_conversation(self, data): + self.conversation = data["conversation"] + self._set_chatbot_mood() self.ui.generator_form_tabs.setCurrentIndex(1) def toggle_secondary_prompts(self): diff --git a/src/airunner/widgets/llm/bot_preferences.py b/src/airunner/widgets/llm/bot_preferences.py index 2742ee960..33611d9cb 100644 --- a/src/airunner/widgets/llm/bot_preferences.py +++ b/src/airunner/widgets/llm/bot_preferences.py @@ -39,7 +39,6 @@ def load_form_elements(self): self.ui.username.setText(self.chatbot.username) self.ui.botname.setText(self.chatbot.botname) self.ui.bot_personality.setPlainText(self.chatbot.bot_personality) - self.ui.bot_mood.setPlainText(self.chatbot.bot_mood) self.ui.names_groupbox.setChecked(self.chatbot.assign_names) self.ui.personality_groupbox.setChecked(self.chatbot.use_personality) self.ui.mood_groupbox.setChecked(self.chatbot.use_mood) @@ -55,9 +54,6 @@ def username_changed(self, val): def botname_changed(self, val): self.update_chatbot("botname", val) - - def bot_mood_changed(self): - self.update_chatbot("bot_mood", self.ui.bot_mood.toPlainText()) def bot_personality_changed(self): self.update_chatbot("bot_personality", self.ui.bot_personality.toPlainText()) diff --git a/src/airunner/widgets/llm/chat_prompt_widget.py b/src/airunner/widgets/llm/chat_prompt_widget.py index 7a287e616..4f00d6742 100644 --- a/src/airunner/widgets/llm/chat_prompt_widget.py +++ b/src/airunner/widgets/llm/chat_prompt_widget.py @@ -148,7 +148,8 @@ def _clear_conversation(self): self._create_conversation() def _create_conversation(self): - conversation_id = self.create_conversation() + conversation = self.create_conversation() + conversation_id = conversation.id self.emit_signal(SignalCode.LLM_CLEAR_HISTORY_SIGNAL, { "conversation_id": conversation_id }) diff --git a/src/airunner/widgets/llm/llm_history_item_widget.py b/src/airunner/widgets/llm/llm_history_item_widget.py index 19684eac0..ea5504c89 100644 --- a/src/airunner/widgets/llm/llm_history_item_widget.py +++ b/src/airunner/widgets/llm/llm_history_item_widget.py @@ -36,6 +36,7 @@ def action_load_conversation_clicked(self): self.session.commit() self.emit_signal(SignalCode.LOAD_CONVERSATION, { "conversation_id": self.conversation.id, + "conversation": self.conversation, "chatbot_id": chatbot_id }) diff --git a/src/airunner/widgets/llm/llm_history_widget.py b/src/airunner/widgets/llm/llm_history_widget.py index 0834e6c9d..6388706de 100644 --- a/src/airunner/widgets/llm/llm_history_widget.py +++ b/src/airunner/widgets/llm/llm_history_widget.py @@ -61,6 +61,7 @@ def on_conversation_click(self, conversation): self.session.commit() self.emit_signal(SignalCode.LOAD_CONVERSATION, { "conversation_id": conversation.id, + "conversation": conversation, "chatbot_id": chatbot_id }) diff --git a/src/airunner/widgets/llm/templates/bot_preferences.ui b/src/airunner/widgets/llm/templates/bot_preferences.ui index 8ea998ad3..4fe5d4c06 100644 --- a/src/airunner/widgets/llm/templates/bot_preferences.ui +++ b/src/airunner/widgets/llm/templates/bot_preferences.ui @@ -59,94 +59,48 @@ 10 - - + + - Agent Type + System Instructions - - - - - - Chatbot - - - - - Tool - - - - - - - - - - - Existing Agents + + true - - - - - - 40 - 16777215 - - - - Add new agent - - - - - - + + + + + + 0 + 0 + - - - - - - - - + - 40 - 16777215 + 0 + 150 - - Delete agent - - - - - - + + Instructions for the LLM - - + + - Documents + Bot Personality - + + true + + - - - Browse - - - - - + 0 @@ -156,23 +110,19 @@ 0 - 150 + 75 - - true + + EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}. + + + + + + + A brief description of the bot's personality - - - - 0 - 0 - 674 - 148 - - - - @@ -245,37 +195,6 @@ - - - - System Instructions - - - true - - - - - - - 0 - 0 - - - - - 0 - 150 - - - - Instructions for the LLM - - - - - - @@ -307,55 +226,94 @@ - - + + - Bot Personality - - - true + Existing Agents - - - - - - 0 - 0 - - - + + + + - 0 - 75 + 40 + 16777215 - - EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}. + + Add new agent + + + + + + - + + + + + + + 40 + 16777215 + + + + Delete agent + - A brief description of the bot's personality + + + + - - + + - Bot Mood + Agent Type - - true + + + + + + Chatbot + + + + + Tool + + + + + + + + + + + Documents - + + + + + Browse + + + - + 0 @@ -365,12 +323,23 @@ 0 - 75 + 150 - - EXAMPLE: Excited + + true + + + + 0 + 0 + 674 + 148 + + + + @@ -432,22 +401,6 @@ - - bot_mood - textChanged() - bot_preferences - bot_mood_changed() - - - 548 - 1100 - - - 451 - 0 - - - names_groupbox toggled(bool) @@ -512,22 +465,6 @@ - - mood_groupbox - toggled(bool) - bot_preferences - toggle_use_mood(bool) - - - 73 - 1068 - - - 0 - 276 - - - guardrails_groupbox toggled(bool) @@ -645,7 +582,6 @@ username_changed(QString) botname_changed(QString) bot_personality_changed() - bot_mood_changed() toggle_use_names(bool) toggle_use_personality(bool) toggle_use_mood(bool) diff --git a/src/airunner/widgets/llm/templates/bot_preferences_ui.py b/src/airunner/widgets/llm/templates/bot_preferences_ui.py index fe87fff24..86347eb46 100644 --- a/src/airunner/widgets/llm/templates/bot_preferences_ui.py +++ b/src/airunner/widgets/llm/templates/bot_preferences_ui.py @@ -39,77 +39,45 @@ def setupUi(self, bot_preferences): self.gridLayout.setObjectName(u"gridLayout") self.gridLayout.setVerticalSpacing(10) self.gridLayout.setContentsMargins(10, 10, 10, 10) - self.groupBox_2 = QGroupBox(self.scrollAreaWidgetContents_2) - self.groupBox_2.setObjectName(u"groupBox_2") - self.gridLayout_8 = QGridLayout(self.groupBox_2) - self.gridLayout_8.setObjectName(u"gridLayout_8") - self.comboBox = QComboBox(self.groupBox_2) - self.comboBox.addItem("") - self.comboBox.addItem("") - self.comboBox.setObjectName(u"comboBox") - - self.gridLayout_8.addWidget(self.comboBox, 0, 0, 1, 1) - - - self.gridLayout.addWidget(self.groupBox_2, 0, 0, 1, 1) - - self.groupBox = QGroupBox(self.scrollAreaWidgetContents_2) - self.groupBox.setObjectName(u"groupBox") - self.gridLayout_3 = QGridLayout(self.groupBox) - self.gridLayout_3.setObjectName(u"gridLayout_3") - self.create_new_button = QPushButton(self.groupBox) - self.create_new_button.setObjectName(u"create_new_button") - self.create_new_button.setMaximumSize(QSize(40, 16777215)) - icon = QIcon(QIcon.fromTheme(u"list-add")) - self.create_new_button.setIcon(icon) - - self.gridLayout_3.addWidget(self.create_new_button, 0, 1, 1, 1) - - self.saved_chatbots = QComboBox(self.groupBox) - self.saved_chatbots.setObjectName(u"saved_chatbots") - - self.gridLayout_3.addWidget(self.saved_chatbots, 0, 0, 1, 1) - - self.delete_button = QPushButton(self.groupBox) - self.delete_button.setObjectName(u"delete_button") - self.delete_button.setMaximumSize(QSize(40, 16777215)) - icon1 = QIcon(QIcon.fromTheme(u"process-stop")) - self.delete_button.setIcon(icon1) + self.system_instructions_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) + self.system_instructions_groupbox.setObjectName(u"system_instructions_groupbox") + self.system_instructions_groupbox.setCheckable(True) + self.verticalLayout_3 = QVBoxLayout(self.system_instructions_groupbox) + self.verticalLayout_3.setObjectName(u"verticalLayout_3") + self.system_instructions = QPlainTextEdit(self.system_instructions_groupbox) + self.system_instructions.setObjectName(u"system_instructions") + sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.system_instructions.sizePolicy().hasHeightForWidth()) + self.system_instructions.setSizePolicy(sizePolicy) + self.system_instructions.setMinimumSize(QSize(0, 150)) - self.gridLayout_3.addWidget(self.delete_button, 0, 2, 1, 1) + self.verticalLayout_3.addWidget(self.system_instructions) - self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1) + self.gridLayout.addWidget(self.system_instructions_groupbox, 4, 0, 1, 1) - self.groupBox_3 = QGroupBox(self.scrollAreaWidgetContents_2) - self.groupBox_3.setObjectName(u"groupBox_3") - self.gridLayout_9 = QGridLayout(self.groupBox_3) - self.gridLayout_9.setObjectName(u"gridLayout_9") - self.browse_documents_button = QPushButton(self.groupBox_3) - self.browse_documents_button.setObjectName(u"browse_documents_button") + self.personality_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) + self.personality_groupbox.setObjectName(u"personality_groupbox") + self.personality_groupbox.setCheckable(True) + self.gridLayout_5 = QGridLayout(self.personality_groupbox) + self.gridLayout_5.setObjectName(u"gridLayout_5") + self.bot_personality = QPlainTextEdit(self.personality_groupbox) + self.bot_personality.setObjectName(u"bot_personality") + sizePolicy.setHeightForWidth(self.bot_personality.sizePolicy().hasHeightForWidth()) + self.bot_personality.setSizePolicy(sizePolicy) + self.bot_personality.setMinimumSize(QSize(0, 75)) - self.gridLayout_9.addWidget(self.browse_documents_button, 1, 0, 1, 1) + self.gridLayout_5.addWidget(self.bot_personality, 1, 0, 1, 1) - self.target_files = QScrollArea(self.groupBox_3) - self.target_files.setObjectName(u"target_files") - sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.target_files.sizePolicy().hasHeightForWidth()) - self.target_files.setSizePolicy(sizePolicy) - self.target_files.setMinimumSize(QSize(0, 150)) - self.target_files.setWidgetResizable(True) - self.scrollAreaWidgetContents = QWidget() - self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents") - self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 674, 148)) - self.gridLayout_10 = QGridLayout(self.scrollAreaWidgetContents) - self.gridLayout_10.setObjectName(u"gridLayout_10") - self.target_files.setWidget(self.scrollAreaWidgetContents) + self.label_2 = QLabel(self.personality_groupbox) + self.label_2.setObjectName(u"label_2") - self.gridLayout_9.addWidget(self.target_files, 0, 0, 1, 1) + self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 1) - self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1) + self.gridLayout.addWidget(self.personality_groupbox, 6, 0, 1, 1) self.names_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) self.names_groupbox.setObjectName(u"names_groupbox") @@ -154,22 +122,6 @@ def setupUi(self, bot_preferences): self.gridLayout.addWidget(self.names_groupbox, 3, 0, 1, 1) - self.system_instructions_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) - self.system_instructions_groupbox.setObjectName(u"system_instructions_groupbox") - self.system_instructions_groupbox.setCheckable(True) - self.verticalLayout_3 = QVBoxLayout(self.system_instructions_groupbox) - self.verticalLayout_3.setObjectName(u"verticalLayout_3") - self.system_instructions = QPlainTextEdit(self.system_instructions_groupbox) - self.system_instructions.setObjectName(u"system_instructions") - sizePolicy.setHeightForWidth(self.system_instructions.sizePolicy().hasHeightForWidth()) - self.system_instructions.setSizePolicy(sizePolicy) - self.system_instructions.setMinimumSize(QSize(0, 150)) - - self.verticalLayout_3.addWidget(self.system_instructions) - - - self.gridLayout.addWidget(self.system_instructions_groupbox, 4, 0, 1, 1) - self.guardrails_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) self.guardrails_groupbox.setObjectName(u"guardrails_groupbox") self.guardrails_groupbox.setCheckable(True) @@ -186,42 +138,74 @@ def setupUi(self, bot_preferences): self.gridLayout.addWidget(self.guardrails_groupbox, 5, 0, 1, 1) - self.personality_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) - self.personality_groupbox.setObjectName(u"personality_groupbox") - self.personality_groupbox.setCheckable(True) - self.gridLayout_5 = QGridLayout(self.personality_groupbox) - self.gridLayout_5.setObjectName(u"gridLayout_5") - self.bot_personality = QPlainTextEdit(self.personality_groupbox) - self.bot_personality.setObjectName(u"bot_personality") - sizePolicy.setHeightForWidth(self.bot_personality.sizePolicy().hasHeightForWidth()) - self.bot_personality.setSizePolicy(sizePolicy) - self.bot_personality.setMinimumSize(QSize(0, 75)) + self.groupBox = QGroupBox(self.scrollAreaWidgetContents_2) + self.groupBox.setObjectName(u"groupBox") + self.gridLayout_3 = QGridLayout(self.groupBox) + self.gridLayout_3.setObjectName(u"gridLayout_3") + self.create_new_button = QPushButton(self.groupBox) + self.create_new_button.setObjectName(u"create_new_button") + self.create_new_button.setMaximumSize(QSize(40, 16777215)) + icon = QIcon(QIcon.fromTheme(u"list-add")) + self.create_new_button.setIcon(icon) - self.gridLayout_5.addWidget(self.bot_personality, 1, 0, 1, 1) + self.gridLayout_3.addWidget(self.create_new_button, 0, 1, 1, 1) - self.label_2 = QLabel(self.personality_groupbox) - self.label_2.setObjectName(u"label_2") + self.saved_chatbots = QComboBox(self.groupBox) + self.saved_chatbots.setObjectName(u"saved_chatbots") - self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 1) + self.gridLayout_3.addWidget(self.saved_chatbots, 0, 0, 1, 1) + self.delete_button = QPushButton(self.groupBox) + self.delete_button.setObjectName(u"delete_button") + self.delete_button.setMaximumSize(QSize(40, 16777215)) + icon1 = QIcon(QIcon.fromTheme(u"process-stop")) + self.delete_button.setIcon(icon1) - self.gridLayout.addWidget(self.personality_groupbox, 6, 0, 1, 1) + self.gridLayout_3.addWidget(self.delete_button, 0, 2, 1, 1) - self.mood_groupbox = QGroupBox(self.scrollAreaWidgetContents_2) - self.mood_groupbox.setObjectName(u"mood_groupbox") - self.mood_groupbox.setCheckable(True) - self.gridLayout_2 = QGridLayout(self.mood_groupbox) - self.gridLayout_2.setObjectName(u"gridLayout_2") - self.bot_mood = QPlainTextEdit(self.mood_groupbox) - self.bot_mood.setObjectName(u"bot_mood") - sizePolicy.setHeightForWidth(self.bot_mood.sizePolicy().hasHeightForWidth()) - self.bot_mood.setSizePolicy(sizePolicy) - self.bot_mood.setMinimumSize(QSize(0, 75)) - self.gridLayout_2.addWidget(self.bot_mood, 0, 0, 1, 1) + self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1) + self.groupBox_2 = QGroupBox(self.scrollAreaWidgetContents_2) + self.groupBox_2.setObjectName(u"groupBox_2") + self.gridLayout_8 = QGridLayout(self.groupBox_2) + self.gridLayout_8.setObjectName(u"gridLayout_8") + self.comboBox = QComboBox(self.groupBox_2) + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.setObjectName(u"comboBox") - self.gridLayout.addWidget(self.mood_groupbox, 7, 0, 1, 1) + self.gridLayout_8.addWidget(self.comboBox, 0, 0, 1, 1) + + + self.gridLayout.addWidget(self.groupBox_2, 0, 0, 1, 1) + + self.groupBox_3 = QGroupBox(self.scrollAreaWidgetContents_2) + self.groupBox_3.setObjectName(u"groupBox_3") + self.gridLayout_9 = QGridLayout(self.groupBox_3) + self.gridLayout_9.setObjectName(u"gridLayout_9") + self.browse_documents_button = QPushButton(self.groupBox_3) + self.browse_documents_button.setObjectName(u"browse_documents_button") + + self.gridLayout_9.addWidget(self.browse_documents_button, 1, 0, 1, 1) + + self.target_files = QScrollArea(self.groupBox_3) + self.target_files.setObjectName(u"target_files") + sizePolicy.setHeightForWidth(self.target_files.sizePolicy().hasHeightForWidth()) + self.target_files.setSizePolicy(sizePolicy) + self.target_files.setMinimumSize(QSize(0, 150)) + self.target_files.setWidgetResizable(True) + self.scrollAreaWidgetContents = QWidget() + self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents") + self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 674, 148)) + self.gridLayout_10 = QGridLayout(self.scrollAreaWidgetContents) + self.gridLayout_10.setObjectName(u"gridLayout_10") + self.target_files.setWidget(self.scrollAreaWidgetContents) + + self.gridLayout_9.addWidget(self.target_files, 0, 0, 1, 1) + + + self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1) self.scrollArea.setWidget(self.scrollAreaWidgetContents_2) @@ -232,12 +216,10 @@ def setupUi(self, bot_preferences): self.username.textChanged.connect(bot_preferences.username_changed) self.botname.textChanged.connect(bot_preferences.botname_changed) self.bot_personality.textChanged.connect(bot_preferences.bot_personality_changed) - self.bot_mood.textChanged.connect(bot_preferences.bot_mood_changed) self.names_groupbox.toggled.connect(bot_preferences.toggle_use_names) self.personality_groupbox.toggled.connect(bot_preferences.toggle_use_personality) self.guardrails_prompt.textChanged.connect(bot_preferences.guardrails_prompt_changed) self.system_instructions.textChanged.connect(bot_preferences.system_instructions_changed) - self.mood_groupbox.toggled.connect(bot_preferences.toggle_use_mood) self.guardrails_groupbox.toggled.connect(bot_preferences.toggle_use_guardrails) self.system_instructions_groupbox.toggled.connect(bot_preferences.toggle_use_system_instructions) self.saved_chatbots.currentTextChanged.connect(bot_preferences.saved_chatbots_changed) @@ -251,10 +233,20 @@ def setupUi(self, bot_preferences): def retranslateUi(self, bot_preferences): bot_preferences.setWindowTitle(QCoreApplication.translate("bot_preferences", u"Form", None)) - self.groupBox_2.setTitle(QCoreApplication.translate("bot_preferences", u"Agent Type", None)) - self.comboBox.setItemText(0, QCoreApplication.translate("bot_preferences", u"Chatbot", None)) - self.comboBox.setItemText(1, QCoreApplication.translate("bot_preferences", u"Tool", None)) - + self.system_instructions_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"System Instructions", None)) + self.system_instructions.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"Instructions for the LLM", None)) + self.personality_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Bot Personality", None)) + self.bot_personality.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}.", None)) + self.label_2.setText(QCoreApplication.translate("bot_preferences", u"A brief description of the bot's personality", None)) + self.names_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Use names", None)) + self.label.setText(QCoreApplication.translate("bot_preferences", u"Assistant name", None)) + self.botname.setText(QCoreApplication.translate("bot_preferences", u"AI Runner", None)) + self.botname.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"Bot name", None)) + self.label_3.setText(QCoreApplication.translate("bot_preferences", u"User name", None)) + self.username.setText(QCoreApplication.translate("bot_preferences", u"User", None)) + self.username.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"User name", None)) + self.guardrails_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Guardrails", None)) + self.guardrails_prompt.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"The guardrails prompt is used to moderate results.", None)) self.groupBox.setTitle(QCoreApplication.translate("bot_preferences", u"Existing Agents", None)) #if QT_CONFIG(tooltip) self.create_new_button.setToolTip(QCoreApplication.translate("bot_preferences", u"Add new agent", None)) @@ -264,23 +256,11 @@ def retranslateUi(self, bot_preferences): self.delete_button.setToolTip(QCoreApplication.translate("bot_preferences", u"Delete agent", None)) #endif // QT_CONFIG(tooltip) self.delete_button.setText("") + self.groupBox_2.setTitle(QCoreApplication.translate("bot_preferences", u"Agent Type", None)) + self.comboBox.setItemText(0, QCoreApplication.translate("bot_preferences", u"Chatbot", None)) + self.comboBox.setItemText(1, QCoreApplication.translate("bot_preferences", u"Tool", None)) + self.groupBox_3.setTitle(QCoreApplication.translate("bot_preferences", u"Documents", None)) self.browse_documents_button.setText(QCoreApplication.translate("bot_preferences", u"Browse", None)) - self.names_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Use names", None)) - self.label.setText(QCoreApplication.translate("bot_preferences", u"Assistant name", None)) - self.botname.setText(QCoreApplication.translate("bot_preferences", u"AI Runner", None)) - self.botname.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"Bot name", None)) - self.label_3.setText(QCoreApplication.translate("bot_preferences", u"User name", None)) - self.username.setText(QCoreApplication.translate("bot_preferences", u"User", None)) - self.username.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"User name", None)) - self.system_instructions_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"System Instructions", None)) - self.system_instructions.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"Instructions for the LLM", None)) - self.guardrails_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Guardrails", None)) - self.guardrails_prompt.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"The guardrails prompt is used to moderate results.", None)) - self.personality_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Bot Personality", None)) - self.bot_personality.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}.", None)) - self.label_2.setText(QCoreApplication.translate("bot_preferences", u"A brief description of the bot's personality", None)) - self.mood_groupbox.setTitle(QCoreApplication.translate("bot_preferences", u"Bot Mood", None)) - self.bot_mood.setPlaceholderText(QCoreApplication.translate("bot_preferences", u"EXAMPLE: Excited", None)) # retranslateUi diff --git a/src/airunner/windows/main/settings_mixin.py b/src/airunner/windows/main/settings_mixin.py index 46b121119..076b45b98 100644 --- a/src/airunner/windows/main/settings_mixin.py +++ b/src/airunner/windows/main/settings_mixin.py @@ -680,7 +680,7 @@ def create_conversation(self): ) self.session.add(conversation) self.session.commit() - return conversation.id + return conversation def update_conversation_title(self, conversation_id, title): conversation = self.session.query(Conversation).filter_by(id=conversation_id).first() @@ -699,7 +699,8 @@ def add_summary(self, content, conversation_id): self.session.commit() def create_conversation_with_messages(self, messages): - conversation_id = self.create_conversation() + conversation = self.create_conversation() + conversation_id = conversation.id for message in messages: self.add_message_to_history( content=message["content"], @@ -720,9 +721,9 @@ def delete_conversation(self, conversation_id): self.session.query(Conversation).filter_by(id=conversation_id).delete() self.session.commit() - def get_most_recent_conversation_id(self): + def get_most_recent_conversation(self): conversation = self.session.query(Conversation).order_by(Conversation.timestamp.desc()).first() - return conversation.id if conversation else None + return conversation def __settings_updated(self): self.emit_signal(SignalCode.APPLICATION_SETTINGS_CHANGED_SIGNAL)