From 4b6cd17d0a097e488b4adba99b659c55d2158b0f Mon Sep 17 00:00:00 2001 From: jeffser Date: Sun, 4 Aug 2024 21:43:23 -0600 Subject: [PATCH] Linting code --- src/main.py | 2 +- src/window.py | 228 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 138 insertions(+), 92 deletions(-) diff --git a/src/main.py b/src/main.py index 8b4412a..39a15c8 100644 --- a/src/main.py +++ b/src/main.py @@ -20,6 +20,7 @@ Main script run at launch, handles actions, about dialog and the app itself (not the window) """ +import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') from gi.repository import Gtk, Gio, Adw, GLib @@ -29,7 +30,6 @@ from .internal import cache_dir, data_dir import sys import logging -import gi import os logger = logging.getLogger(__name__) diff --git a/src/window.py b/src/window.py index c0ca439..79cae31 100644 --- a/src/window.py +++ b/src/window.py @@ -38,7 +38,6 @@ from .internal import config_dir, data_dir, cache_dir, source_dir logger = logging.getLogger(__name__) - @Gtk.Template(resource_path='/com/jeffser/Alpaca/window.ui') class AlpacaWindow(Adw.ApplicationWindow): app_dir = os.getenv("FLATPAK_DEST") @@ -140,7 +139,8 @@ class AlpacaWindow(Adw.ApplicationWindow): @Gtk.Template.Callback() def verify_if_image_can_be_used(self, pspec=None, user_data=None): logger.debug("Verifying if image can be used") - if self.model_drop_down.get_selected_item() == None: return True + if self.model_drop_down.get_selected_item() == None: + return True selected = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1).split(":")[0] if selected in [key for key, value in self.available_models.items() if value["image"]]: for name, content in self.attachments.items(): @@ -155,7 +155,8 @@ class AlpacaWindow(Adw.ApplicationWindow): @Gtk.Template.Callback() def stop_message(self, button=None): - if self.loading_spinner: self.chat_container.remove(self.loading_spinner) + if self.loading_spinner: + self.chat_container.remove(self.loading_spinner) self.toggle_ui_sensitive(True) self.switch_send_stop_button() self.bot_message = None @@ -179,8 +180,10 @@ class AlpacaWindow(Adw.ApplicationWindow): self.save_history() self.show_toast(_("Message edited successfully"), self.main_overlay) - if self.bot_message or self.get_focus() not in (self.message_text_view, self.send_button): return - if not self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False): return + if self.bot_message or self.get_focus() not in (self.message_text_view, self.send_button): + return + if not self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False): + return current_chat_row = self.chat_list_box.get_selected_row() self.chat_list_box.unselect_all() self.chat_list_box.remove(current_chat_row) @@ -193,18 +196,19 @@ class AlpacaWindow(Adw.ApplicationWindow): if current_model is None: self.show_toast(_("Please select a model before chatting"), self.main_overlay) return - id = self.generate_uuid() + message_id = self.generate_uuid() attached_images = [] attached_files = {} can_use_images = self.verify_if_image_can_be_used() for name, content in self.attachments.items(): - if content["type"] == 'image' and can_use_images: attached_images.append(name) + if content["type"] == 'image' and can_use_images: + attached_images.append(name) else: attached_files[name] = content['type'] - if not os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)): - os.makedirs(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)) - shutil.copy(content['path'], os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name)) + if not os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id)): + os.makedirs(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id)) + shutil.copy(content['path'], os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id, name)) content["button"].get_parent().remove(content["button"]) self.attachments = {} self.attachment_box.set_visible(False) @@ -213,16 +217,16 @@ class AlpacaWindow(Adw.ApplicationWindow): current_datetime = datetime.now() - self.chats["chats"][self.chats["selected_chat"]]["messages"][id] = { + self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id] = { "role": "user", "model": "User", "date": current_datetime.strftime("%Y/%m/%d %H:%M:%S"), "content": self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False) } if len(attached_images) > 0: - self.chats["chats"][self.chats["selected_chat"]]["messages"][id]['images'] = attached_images + self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]['images'] = attached_images if len(attached_files.keys()) > 0: - self.chats["chats"][self.chats["selected_chat"]]["messages"][id]['files'] = attached_files + self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]['files'] = attached_files data = { "model": current_model, "messages": self.convert_history_to_ollama(), @@ -235,12 +239,12 @@ class AlpacaWindow(Adw.ApplicationWindow): #self.attachments[name] = {"path": file_path, "type": file_type, "content": content} raw_message = self.message_text_view.get_buffer().get_text(self.message_text_view.get_buffer().get_start_iter(), self.message_text_view.get_buffer().get_end_iter(), False) formated_date = GLib.markup_escape_text(self.generate_datetime_format(current_datetime)) - self.show_message(raw_message, False, f"\n\n{formated_date}", attached_images, attached_files, id=id) + self.show_message(raw_message, False, f"\n\n{formated_date}", attached_images, attached_files, message_id=message_id) self.message_text_view.get_buffer().set_text("", 0) self.loading_spinner = Gtk.Spinner(spinning=True, margin_top=12, margin_bottom=12, hexpand=True) self.chat_container.append(self.loading_spinner) bot_id=self.generate_uuid() - self.show_message("", True, id=bot_id) + self.show_message("", True, message_id=bot_id) thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], bot_id)) thread.start() @@ -259,8 +263,10 @@ class AlpacaWindow(Adw.ApplicationWindow): @Gtk.Template.Callback() def welcome_carousel_page_changed(self, carousel, index): logger.debug("Showing welcome carousel") - if index == 0: self.welcome_previous_button.set_sensitive(False) - else: self.welcome_previous_button.set_sensitive(True) + if index == 0: + self.welcome_previous_button.set_sensitive(False) + else: + self.welcome_previous_button.set_sensitive(True) if index == carousel.get_n_pages()-1: self.welcome_next_button.set_label(_("Close")) self.welcome_next_button.set_tooltip_text(_("Close")) @@ -274,7 +280,8 @@ class AlpacaWindow(Adw.ApplicationWindow): @Gtk.Template.Callback() def welcome_next_button_activate(self, button): - if button.get_label() == "Next": self.welcome_carousel.scroll_to(self.welcome_carousel.get_nth_page(self.welcome_carousel.get_position()+1), True) + if button.get_label() == "Next": + self.welcome_carousel.scroll_to(self.welcome_carousel.get_nth_page(self.welcome_carousel.get_position()+1), True) else: self.welcome_dialog.force_close() if not self.verify_connection(): @@ -342,8 +349,10 @@ class AlpacaWindow(Adw.ApplicationWindow): @Gtk.Template.Callback() def model_spin_changed(self, spin): value = spin.get_value() - if spin.get_name() != "temperature": value = round(value) - else: value = round(value, 1) + if spin.get_name() != "temperature": + value = round(value) + else: + value = round(value, 1) if self.model_tweaks[spin.get_name()] is not None and self.model_tweaks[spin.get_name()] != value: self.model_tweaks[spin.get_name()] = value self.save_server_config() @@ -391,11 +400,15 @@ class AlpacaWindow(Adw.ApplicationWindow): def override_changed(self, entry): name = entry.get_name() value = entry.get_text() - if (not value and name not in local_instance.overrides) or (value and value in local_instance.overrides and local_instance.overrides[name] == value): return - if not value: del local_instance.overrides[name] - else: local_instance.overrides[name] = value + if (not value and name not in local_instance.overrides) or (value and value in local_instance.overrides and local_instance.overrides[name] == value): + return + if not value: + del local_instance.overrides[name] + else: + local_instance.overrides[name] = value self.save_server_config() - if not self.run_remote: local_instance.reset() + if not self.run_remote: + local_instance.reset() @Gtk.Template.Callback() def link_button_handler(self, button): @@ -413,7 +426,8 @@ class AlpacaWindow(Adw.ApplicationWindow): for i, key in enumerate(self.available_models.keys()): row = self.available_model_list_box.get_row_at_index(i) row.set_visible(re.search(entry.get_text(), '{} {} {}'.format(row.get_title(), (_("image") if self.available_models[key]['image'] else " "), row.get_subtitle()), re.IGNORECASE)) - if row.get_visible(): results += 1 + if row.get_visible(): + results += 1 if entry.get_text() and results == 0: self.available_model_list_box.set_visible(False) self.no_results_page.set_visible(True) @@ -422,12 +436,15 @@ class AlpacaWindow(Adw.ApplicationWindow): self.no_results_page.set_visible(False) def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag - if mode == 0: return "{} ({})".format(name.split(":")[0].replace("-", " ").title(), name.split(":")[1]) - if mode == 1: return "{}:{}".format(name.split(" (")[0].replace(" ", "-").lower(), name.split(" (")[1][:-1]) + if mode == 0: + return "{} ({})".format(name.split(":")[0].replace("-", " ").title(), name.split(":")[1]) + if mode == 1: + return "{}:{}".format(name.split(" (")[0].replace(" ", "-").lower(), name.split(" (")[1][:-1]) def check_alphanumeric(self, editable, text, length, position): new_text = ''.join([char for char in text if char.isalnum() or char in ['-', '.', ':']]) - if new_text != text: editable.stop_emission_by_name("insert-text") + if new_text != text: + editable.stop_emission_by_name("insert-text") def create_model(self, model:str, file:bool): modelfile_buffer = self.create_model_modelfile.get_buffer() @@ -466,31 +483,33 @@ class AlpacaWindow(Adw.ApplicationWindow): logger.info(f"{title}, {body}") notification = Gio.Notification.new(title) notification.set_body(body) - if icon: notification.set_icon(icon) + if icon: + notification.set_icon(icon) self.get_application().send_notification(None, notification) def delete_message(self, message_element): logger.debug("Deleting message") - id = message_element.get_name() - del self.chats["chats"][self.chats["selected_chat"]]["messages"][id] + message_id = message_element.get_name() + del self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id] self.chat_container.remove(message_element) - if os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)): - shutil.rmtree(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id)) + if os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id)): + shutil.rmtree(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id)) self.save_history() def copy_message(self, message_element): logger.debug("Copying message") - id = message_element.get_name() + message_id = message_element.get_name() clipboard = Gdk.Display().get_default().get_clipboard() - clipboard.set(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["content"]) + clipboard.set(self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]["content"]) self.show_toast(_("Message copied to the clipboard"), self.main_overlay) def edit_message(self, message_element, text_view, button_container): logger.debug("Editing message") - if self.editing_message: self.send_message() + if self.editing_message: + self.send_message() button_container.set_visible(False) - id = message_element.get_name() + message_id = message_element.get_name() text_buffer = text_view.get_buffer() end_iter = text_buffer.get_end_iter() @@ -504,7 +523,7 @@ class AlpacaWindow(Adw.ApplicationWindow): text_view.set_css_classes(["view", "editing_message_textview"]) text_view.set_cursor_visible(True) - self.editing_message = {"text_view": text_view, "id": id, "button_container": button_container, "footer": footer} + self.editing_message = {"text_view": text_view, "id": message_id, "button_container": button_container, "footer": footer} def preview_file(self, file_path, file_type, presend_name): logger.debug(f"Previewing file: {file_path}") @@ -547,22 +566,24 @@ class AlpacaWindow(Adw.ApplicationWindow): def convert_history_to_ollama(self): messages = [] - for id, message in self.chats["chats"][self.chats["selected_chat"]]["messages"].items(): + for message_id, message in self.chats["chats"][self.chats["selected_chat"]]["messages"].items(): new_message = message.copy() if 'files' in message and len(message['files']) > 0: del new_message['files'] new_message['content'] = '' for name, file_type in message['files'].items(): - file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name) + file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id, name) file_data = self.get_content_of_file(file_path, file_type) - if file_data: new_message['content'] += f"```[{name}]\n{file_data}\n```" + if file_data: + new_message['content'] += f"```[{name}]\n{file_data}\n```" new_message['content'] += message['content'] if 'images' in message and len(message['images']) > 0: new_message['images'] = [] for name in message['images']: - file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, name) + file_path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id, name) image_data = self.get_content_of_file(file_path, 'image') - if image_data: new_message['images'].append(image_data) + if image_data: + new_message['images'].append(image_data) messages.append(new_message) return messages @@ -581,14 +602,15 @@ Generate a title following these rules: ```""" current_model = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1) data = {"model": current_model, "prompt": prompt, "stream": False} - if 'images' in message: data["images"] = message['images'] + if 'images' in message: + data["images"] = message['images'] response = connection_handler.simple_post(f"{connection_handler.url}/api/generate", data=json.dumps(data)) new_chat_name = json.loads(response.text)["response"].strip().removeprefix("Title: ").removeprefix("title: ").strip('\'"').replace('\n', ' ').title().replace('\'S', '\'s') new_chat_name = new_chat_name[:50] + (new_chat_name[50:] and '...') self.rename_chat(label_element.get_name(), new_chat_name, label_element) - def show_message(self, msg:str, bot:bool, footer:str=None, images:list=None, files:dict=None, id:str=None): + def show_message(self, msg:str, bot:bool, footer:str=None, images:list=None, files:dict=None, message_id:str=None): message_text = Gtk.TextView( editable=False, focusable=True, @@ -603,7 +625,8 @@ Generate a title following these rules: ) message_buffer = message_text.get_buffer() message_buffer.insert(message_buffer.get_end_iter(), msg) - if footer is not None: message_buffer.insert_markup(message_buffer.get_end_iter(), footer, len(footer.encode('utf-8'))) + if footer is not None: + message_buffer.insert_markup(message_buffer.get_end_iter(), footer, len(footer.encode('utf-8'))) delete_button = Gtk.Button( icon_name = "user-trash-symbolic", @@ -656,7 +679,7 @@ Generate a title following these rules: child=image_container ) for image in images: - path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], id, image) + path = os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id, image) try: if not os.path.isfile(path): raise FileNotFoundError("'{}' was not found or is a directory".format(path)) @@ -665,7 +688,7 @@ Generate a title following these rules: button = Gtk.Button( child=image_element, css_classes=["flat", "chat_image_button"], - name=os.path.join(self.data_dir, "chats", "{selected_chat}", id, image), + name=os.path.join(self.data_dir, "chats", "{selected_chat}", message_id, image), tooltip_text=_("Image") ) button.connect("clicked", lambda button, file_path=path: self.preview_file(file_path, 'image', None)) @@ -728,19 +751,19 @@ Generate a title following these rules: tooltip_text=name, child=button_content ) - file_path = os.path.join(self.data_dir, "chats", "{selected_chat}", id, name) + file_path = os.path.join(self.data_dir, "chats", "{selected_chat}", message_id, name) button.connect("clicked", lambda button, file_path=file_path, file_type=file_type: self.preview_file(file_path, file_type, None)) file_container.append(button) message_box.append(file_scroller) message_box.append(message_text) - overlay = Gtk.Overlay(css_classes=["message"], name=id) + overlay = Gtk.Overlay(css_classes=["message"], name=message_id) overlay.set_child(message_box) delete_button.connect("clicked", lambda button, element=overlay: self.delete_message(element)) copy_button.connect("clicked", lambda button, element=overlay: self.copy_message(element)) edit_button.connect("clicked", lambda button, element=overlay, textview=message_text, button_container=button_container: self.edit_message(element, textview, button_container)) - regenerate_button.connect('clicked', lambda button, id=id, bot_message_box=message_box, bot_message_button_container=button_container : self.regenerate_message(id, bot_message_box, bot_message_button_container)) + regenerate_button.connect('clicked', lambda button, message_id=message_id, bot_message_box=message_box, bot_message_button_container=button_container : self.regenerate_message(message_id, bot_message_box, bot_message_button_container)) button_container.append(delete_button) button_container.append(copy_button) button_container.append(regenerate_button if bot else edit_button) @@ -947,19 +970,22 @@ Generate a title following these rules: def generate_datetime_format(self, dt:datetime) -> str: date = GLib.DateTime.new(GLib.DateTime.new_now_local().get_timezone(), dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) current_date = GLib.DateTime.new_now_local() - if date.format("%Y/%m/%d") == current_date.format("%Y/%m/%d"): return date.format("%H:%M %p") - elif date.format("%Y") == current_date.format("%Y"): return date.format("%b %d, %H:%M %p") - else: return date.format("%b %d %Y, %H:%M %p") + if date.format("%Y/%m/%d") == current_date.format("%Y/%m/%d"): + return date.format("%H:%M %p") + elif date.format("%Y") == current_date.format("%Y"): + return date.format("%b %d, %H:%M %p") + else: + return date.format("%b %d %Y, %H:%M %p") - def update_bot_message(self, data, id): + def update_bot_message(self, data, message_id): if self.bot_message is None: self.save_history() sys.exit() vadjustment = self.chat_window.get_vadjustment() - if id not in self.chats["chats"][self.chats["selected_chat"]]["messages"] or vadjustment.get_value() + 50 >= vadjustment.get_upper() - vadjustment.get_page_size(): + if message_id not in self.chats["chats"][self.chats["selected_chat"]]["messages"] or vadjustment.get_value() + 50 >= vadjustment.get_upper() - vadjustment.get_page_size(): GLib.idle_add(vadjustment.set_value, vadjustment.get_upper()) if 'done' in data and data['done']: - formated_date = GLib.markup_escape_text(self.generate_datetime_format(datetime.strptime(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["date"], '%Y/%m/%d %H:%M:%S'))) + formated_date = GLib.markup_escape_text(self.generate_datetime_format(datetime.strptime(self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]["date"], '%Y/%m/%d %H:%M:%S'))) text = f"\n\n{self.convert_model_name(data['model'], 0)}\n{formated_date}" GLib.idle_add(self.bot_message.insert_markup, self.bot_message.get_end_iter(), text, len(text.encode('utf-8'))) self.save_history() @@ -968,11 +994,11 @@ Generate a title following these rules: first_paragraph = self.bot_message.get_text(self.bot_message.get_start_iter(), self.bot_message.get_end_iter(), False).split("\n")[0] GLib.idle_add(self.show_notification, self.chats["selected_chat"], first_paragraph[:100] + (first_paragraph[100:] and '...'), Gio.ThemedIcon.new("chat-message-new-symbolic")) else: - if not self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["content"] and self.loading_spinner: + if not self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]["content"] and self.loading_spinner: GLib.idle_add(self.chat_container.remove, self.loading_spinner) self.loading_spinner = None GLib.idle_add(self.bot_message.insert, self.bot_message.get_end_iter(), data['message']['content']) - self.chats["chats"][self.chats["selected_chat"]]["messages"][id]['content'] += data['message']['content'] + self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id]['content'] += data['message']['content'] def toggle_ui_sensitive(self, status): for element in [self.chat_list_box, self.add_chat_button, self.secondary_menu_button]: @@ -982,10 +1008,10 @@ Generate a title following these rules: self.stop_button.set_visible(self.send_button.get_visible()) self.send_button.set_visible(not self.send_button.get_visible()) - def run_message(self, messages, model, id): + def run_message(self, messages, model, message_id): logger.debug("Running message") self.bot_message_button_container.set_visible(False) - self.chats["chats"][self.chats["selected_chat"]]["messages"][id] = { + self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id] = { "role": "assistant", "model": model, "date": datetime.now().strftime("%Y/%m/%d %H:%M:%S"), @@ -994,8 +1020,9 @@ Generate a title following these rules: if self.regenerate_button: GLib.idle_add(self.chat_container.remove, self.regenerate_button) try: - response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, id=id: self.update_bot_message(data, id)) - if response.status_code != 200: raise Exception('Network Error') + response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, message_id=message_id: self.update_bot_message(data, message_id)) + if response.status_code != 200: + raise Exception('Network Error') GLib.idle_add(self.add_code_blocks) except Exception as e: GLib.idle_add(self.connection_error) @@ -1008,7 +1035,7 @@ Generate a title following these rules: halign=3 ) GLib.idle_add(self.chat_container.append, self.regenerate_button) - self.regenerate_button.connect('clicked', lambda button, id=id, bot_message_box=self.bot_message_box, bot_message_button_container=self.bot_message_button_container : self.regenerate_message(id, bot_message_box, bot_message_button_container)) + self.regenerate_button.connect('clicked', lambda button, message_id=message_id, bot_message_box=self.bot_message_box, bot_message_button_container=self.bot_message_button_container : self.regenerate_message(message_id, bot_message_box, bot_message_button_container)) finally: GLib.idle_add(self.switch_send_stop_button) GLib.idle_add(self.toggle_ui_sensitive, True) @@ -1016,7 +1043,7 @@ Generate a title following these rules: GLib.idle_add(self.chat_container.remove, self.loading_spinner) self.loading_spinner = None - def regenerate_message(self, id, bot_message_box, bot_message_button_container): + def regenerate_message(self, message_id, bot_message_box, bot_message_button_container): self.bot_message_button_container = bot_message_button_container self.bot_message_view = Gtk.TextView( editable=False, @@ -1028,11 +1055,12 @@ Generate a title following these rules: css_classes=["flat"] ) self.bot_message = self.bot_message_view.get_buffer() - for widget in list(bot_message_box): bot_message_box.remove(widget) + for widget in list(bot_message_box): + bot_message_box.remove(widget) bot_message_box.append(self.bot_message_view) - history = self.convert_history_to_ollama()[:list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()).index(id)] - if id in self.chats["chats"][self.chats["selected_chat"]]["messages"]: - del self.chats["chats"][self.chats["selected_chat"]]["messages"][id] + history = self.convert_history_to_ollama()[:list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()).index(message_id)] + if message_id in self.chats["chats"][self.chats["selected_chat"]]["messages"]: + del self.chats["chats"][self.chats["selected_chat"]]["messages"][message_id] data = { "model": self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1), "messages": history, @@ -1041,7 +1069,7 @@ Generate a title following these rules: } self.switch_send_stop_button() self.toggle_ui_sensitive(False) - thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], id)) + thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], message_id)) thread.start() def pull_model_update(self, data, model_name): @@ -1086,7 +1114,8 @@ Generate a title following these rules: GLib.idle_add(self.pulling_model_list_box.set_visible, False) def pull_model(self, model): - if model in list(self.pulling_models.keys()) or model in self.local_models or ":" not in model: return + if model in list(self.pulling_models.keys()) or model in self.local_models or ":" not in model: + return logger.info("Pulling model") self.pulling_model_list_box.set_visible(True) #self.pulling_model_list_box.connect('row_selected', lambda list_box, row: dialogs.stop_pull_model(self, row.get_name()) if row else None) #It isn't working for some reason @@ -1175,9 +1204,9 @@ Generate a title following these rules: if message: formated_date = GLib.markup_escape_text(self.generate_datetime_format(datetime.strptime(message['date'] + (":00" if message['date'].count(":") == 1 else ""), '%Y/%m/%d %H:%M:%S'))) if message['role'] == 'user': - self.show_message(message['content'], False, f"\n\n{formated_date}", message['images'] if 'images' in message else None, message['files'] if 'files' in message else None, id=key) + self.show_message(message['content'], False, f"\n\n{formated_date}", message['images'] if 'images' in message else None, message['files'] if 'files' in message else None, message_id=key) else: - self.show_message(message['content'], True, f"\n\n{self.convert_model_name(message['model'], 0)}\n{formated_date}", id=key) + self.show_message(message['content'], True, f"\n\n{self.convert_model_name(message['model'], 0)}\n{formated_date}", message_id=key) self.add_code_blocks() self.bot_message = None @@ -1187,8 +1216,10 @@ Generate a title following these rules: try: with open(os.path.join(self.data_dir, "chats", "chats.json"), "r", encoding="utf-8") as f: self.chats = json.load(f) - if len(list(self.chats["chats"].keys())) == 0: self.chats["chats"][_("New Chat")] = {"messages": {}} - if "selected_chat" not in self.chats or self.chats["selected_chat"] not in self.chats["chats"]: self.chats["selected_chat"] = list(self.chats["chats"].keys())[0] + if len(list(self.chats["chats"].keys())) == 0: + self.chats["chats"][_("New Chat")] = {"messages": {}} + if "selected_chat" not in self.chats or self.chats["selected_chat"] not in self.chats["chats"]: + self.chats["selected_chat"] = list(self.chats["chats"].keys())[0] if "order" not in self.chats: self.chats["order"] = [] for chat_name in self.chats["chats"].keys(): @@ -1218,7 +1249,7 @@ Generate a title following these rules: chat_name = f"{'.'.join(chat_name.split('.')[:-1])} {i+1}.{chat_name.split('.')[-1]}" break else: - if f"{chat_name} {i+1}" not in compare_list: + if f"{chat_name} {i+1}" not in compare_list: chat_name = f"{chat_name} {i+1}" break return chat_name @@ -1248,7 +1279,8 @@ Generate a title following these rules: def rename_chat(self, old_chat_name, new_chat_name, label_element): logger.info(f"Renaming chat \"{old_chat_name}\" -> \"{new_chat_name}\"") new_chat_name = self.generate_numbered_name(new_chat_name, self.chats["chats"].keys()) - if self.chats["selected_chat"] == old_chat_name: self.chats["selected_chat"] = new_chat_name + if self.chats["selected_chat"] == old_chat_name: + self.chats["selected_chat"] = new_chat_name self.chats["chats"][new_chat_name] = self.chats["chats"][old_chat_name] self.chats["order"][self.chats["order"].index(old_chat_name)] = new_chat_name del self.chats["chats"][old_chat_name] @@ -1318,9 +1350,12 @@ Generate a title following these rules: gesture.connect("released", self.chat_click_handler) chat_row.add_controller(gesture) - if append: self.chat_list_box.append(chat_row) - else: self.chat_list_box.prepend(chat_row) - if select: self.chat_list_box.select_row(chat_row) + if append: + self.chat_list_box.append(chat_row) + else: + self.chat_list_box.prepend(chat_row) + if select: + self.chat_list_box.select_row(chat_row) def update_chat_list(self): self.chat_list_box.remove_all() @@ -1346,8 +1381,10 @@ Generate a title following these rules: connection_handler.bearer_token = None connection_handler.url = f"http://127.0.0.1:{local_instance.port}" local_instance.start() - if self.verify_connection() == False: self.connection_error() - else: self.remote_connection_switch.set_active(False) + if self.verify_connection() == False: + self.connection_error() + else: + self.remote_connection_switch.set_active(False) def connection_error(self): logger.error("Connection error") @@ -1365,13 +1402,16 @@ Generate a title following these rules: if self.run_remote: connection_handler.bearer_token = self.remote_bearer_token connection_handler.url = self.remote_url - if self.verify_connection() == False: self.connection_error() - else: local_instance.stop() + if self.verify_connection() == False: + self.connection_error() + else: + local_instance.stop() else: connection_handler.bearer_token = None connection_handler.url = f"http://127.0.0.1:{local_instance.port}" local_instance.start() - if self.verify_connection() == False: self.connection_error() + if self.verify_connection() == False: + self.connection_error() def on_replace_contents(self, file, result): file.replace_contents_finish(result) @@ -1379,7 +1419,8 @@ Generate a title following these rules: def on_export_chat(self, file_dialog, result, chat_name): file = file_dialog.save_finish(result) - if not file: return + if not file: + return json_data = json.dumps({chat_name: self.chats["chats"][chat_name]}, indent=4).encode("UTF-8") with tempfile.TemporaryDirectory() as temp_dir: @@ -1413,7 +1454,8 @@ Generate a title following these rules: def on_chat_imported(self, file_dialog, result): file = file_dialog.open_finish(result) - if not file: return + if not file: + return stream = file.read(None) data_stream = Gio.DataInputStream.new(stream) tar_content = data_stream.read_bytes(1024 * 1024, None) @@ -1483,7 +1525,8 @@ Generate a title following these rules: return f.read() elif file_type == 'pdf': reader = PdfReader(file_path) - if len(reader.pages) == 0: return None + if len(reader.pages) == 0: + return None text = "" for i, page in enumerate(reader.pages): text += f"\n- Page {i}\n{page.extract_text(extraction_mode='layout', layout_mode_space_vertically=False)}\n" @@ -1494,7 +1537,8 @@ Generate a title following these rules: button = self.attachments[name]['button'] button.get_parent().remove(button) del self.attachments[name] - if len(self.attachments) == 0: self.attachment_box.set_visible(False) + if len(self.attachments) == 0: + self.attachment_box.set_visible(False) def attach_file(self, file_path, file_type): logger.debug(f"Attaching file: {file_path}") @@ -1652,7 +1696,8 @@ Generate a title following these rules: self.seed_spin.set_value(self.model_tweaks['seed']) self.keep_alive_spin.set_value(self.model_tweaks['keep_alive']) #Overrides - if "ollama_overrides" in data: local_instance.overrides = data['ollama_overrides'] + if "ollama_overrides" in data: + local_instance.overrides = data['ollama_overrides'] for element in [ self.override_HSA_OVERRIDE_GFX_VERSION, self.override_CUDA_VISIBLE_DEVICES, @@ -1678,7 +1723,8 @@ Generate a title following these rules: local_instance.start() connection_handler.url = f"http://127.0.0.1:{local_instance.port}" self.welcome_dialog.present(self) - if self.verify_connection() is False: self.connection_error() + if self.verify_connection() is False: + self.connection_error() self.update_list_available_models() self.load_history() self.update_chat_list()