diff --git a/src/window.py b/src/window.py
index afa6477..bf921b6 100644
--- a/src/window.py
+++ b/src/window.py
@@ -120,6 +120,123 @@ class AlpacaWindow(Adw.ApplicationWindow):
style_manager = Adw.StyleManager()
+ @Gtk.Template.Callback()
+ def verify_if_image_can_be_used(self, pspec=None, user_data=None):
+ if self.model_drop_down.get_selected_item() == None: return True
+ selected = self.model_drop_down.get_selected_item().get_string().split(":")[0]
+ if selected in ['llava', 'bakllava', 'moondream', 'llava-llama3']:
+ self.image_button.set_sensitive(True)
+ return True
+ else:
+ self.image_button.set_sensitive(False)
+ self.image_button.set_css_classes([])
+ self.image_button.get_child().set_icon_name("image-x-generic-symbolic")
+ self.attached_image = {"path": None, "base64": None}
+ return False
+
+ @Gtk.Template.Callback()
+ def send_message(self, button=None):
+ if button and self.bot_message: #STOP BUTTON
+ if self.loading_spinner: self.chat_container.remove(self.loading_spinner)
+ if self.verify_if_image_can_be_used(): self.image_button.set_sensitive(True)
+ self.image_button.set_css_classes([])
+ self.image_button.get_child().set_icon_name("image-x-generic-symbolic")
+ self.attached_image = {"path": None, "base64": None}
+ self.toggle_ui_sensitive(True)
+ self.send_button.set_css_classes(["suggested-action"])
+ self.send_button.get_child().set_label("Send")
+ self.send_button.get_child().set_icon_name("send-to-symbolic")
+ self.bot_message = None
+ self.bot_message_box = None
+ self.bot_message_view = None
+ else:
+ 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_model = self.model_drop_down.get_selected_item()
+ if current_model is None:
+ self.show_toast("info", 0, self.main_overlay)
+ return
+ formated_datetime = datetime.now().strftime("%Y/%m/%d %H:%M")
+ self.chats["chats"][self.chats["selected_chat"]]["messages"].append({
+ "role": "user",
+ "model": "User",
+ "date": formated_datetime,
+ "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)
+ })
+ data = {
+ "model": current_model.get_string(),
+ "messages": self.chats["chats"][self.chats["selected_chat"]]["messages"]
+ }
+ if self.verify_if_image_can_be_used() and self.attached_image["base64"] is not None:
+ data["messages"][-1]["images"] = [self.attached_image["base64"]]
+ self.send_button.set_css_classes(["destructive-action"])
+ self.send_button.get_child().set_label("Stop")
+ self.send_button.get_child().set_icon_name("edit-delete-symbolic")
+ self.toggle_ui_sensitive(False)
+ self.image_button.set_sensitive(False)
+
+ self.show_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), False, f"\n\n{formated_datetime}", self.attached_image["base64"])
+ 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)
+ self.show_message("", True)
+
+ vadjustment = self.chat_window.get_vadjustment()
+ vadjustment.set_value(vadjustment.get_upper())
+ thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model']))
+ thread.start()
+
+ @Gtk.Template.Callback()
+ def manage_models_button_activate(self, button=None):
+ self.update_list_local_models()
+ self.manage_models_dialog.present(self)
+
+ @Gtk.Template.Callback()
+ def welcome_carousel_page_changed(self, carousel, index):
+ 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("Connect")
+ else: self.welcome_next_button.set_label("Next")
+
+ @Gtk.Template.Callback()
+ def welcome_previous_button_activate(self, button):
+ self.welcome_carousel.scroll_to(self.welcome_carousel.get_nth_page(self.welcome_carousel.get_position()-1), True)
+
+ @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)
+ else:
+ self.welcome_dialog.force_close()
+ if not self.verify_connection():
+ self.connection_error()
+
+ @Gtk.Template.Callback()
+ def open_image(self, button):
+ if "destructive-action" in button.get_css_classes():
+ dialogs.remove_image(self)
+ else:
+ file_dialog = Gtk.FileDialog(default_filter=self.file_filter_image)
+ file_dialog.open(self, None, self.load_image)
+
+ @Gtk.Template.Callback()
+ def chat_changed(self, listbox, row):
+ if row and row.get_name() != self.chats["selected_chat"]:
+ self.chats["selected_chat"] = row.get_name()
+ self.load_history_into_chat()
+ if len(self.chats["chats"][self.chats["selected_chat"]]["messages"]) > 0:
+ for i in range(self.model_string_list.get_n_items()):
+ if self.model_string_list.get_string(i) == self.chats["chats"][self.chats["selected_chat"]]["messages"][-1]["model"]:
+ self.model_drop_down.set_selected(i)
+ break
+
+ @Gtk.Template.Callback()
+ def change_remote_url(self, entry):
+ self.remote_url = entry.get_text()
+ if self.run_remote:
+ connection_handler.url = self.remote_url
+ if self.verify_connection() == False:
+ entry.set_css_classes(["error"])
+ self.show_toast("error", 1, self.preferences_dialog)
+
def show_toast(self, message_type:str, message_id:int, overlay):
if message_type not in self.toast_messages or message_id > len(self.toast_messages[message_type] or message_id < 0):
message_type = "error"
@@ -208,20 +325,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.bot_message_view = message_text
self.bot_message_box = message_box
- @Gtk.Template.Callback()
- def verify_if_image_can_be_used(self, pspec=None, user_data=None):
- if self.model_drop_down.get_selected_item() == None: return True
- selected = self.model_drop_down.get_selected_item().get_string().split(":")[0]
- if selected in ['llava', 'bakllava', 'moondream', 'llava-llama3']:
- self.image_button.set_sensitive(True)
- return True
- else:
- self.image_button.set_sensitive(False)
- self.image_button.set_css_classes([])
- self.image_button.get_child().set_icon_name("image-x-generic-symbolic")
- self.attached_image = {"path": None, "base64": None}
- return False
-
def update_list_local_models(self):
self.local_models = []
response = connection_handler.simple_get(connection_handler.url + "/api/tags")
@@ -421,57 +524,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
if response['status'] == 'error':
GLib.idle_add(self.connection_error)
- @Gtk.Template.Callback()
- def send_message(self, button=None):
- if button and self.bot_message: #STOP BUTTON
- if self.loading_spinner: self.chat_container.remove(self.loading_spinner)
- if self.verify_if_image_can_be_used(): self.image_button.set_sensitive(True)
- self.image_button.set_css_classes([])
- self.image_button.get_child().set_icon_name("image-x-generic-symbolic")
- self.attached_image = {"path": None, "base64": None}
- self.toggle_ui_sensitive(True)
- self.send_button.set_css_classes(["suggested-action"])
- self.send_button.get_child().set_label("Send")
- self.send_button.get_child().set_icon_name("send-to-symbolic")
- self.bot_message = None
- self.bot_message_box = None
- self.bot_message_view = None
- else:
- 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_model = self.model_drop_down.get_selected_item()
- if current_model is None:
- self.show_toast("info", 0, self.main_overlay)
- return
- formated_datetime = datetime.now().strftime("%Y/%m/%d %H:%M")
- self.chats["chats"][self.chats["selected_chat"]]["messages"].append({
- "role": "user",
- "model": "User",
- "date": formated_datetime,
- "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)
- })
- data = {
- "model": current_model.get_string(),
- "messages": self.chats["chats"][self.chats["selected_chat"]]["messages"]
- }
- if self.verify_if_image_can_be_used() and self.attached_image["base64"] is not None:
- data["messages"][-1]["images"] = [self.attached_image["base64"]]
- self.send_button.set_css_classes(["destructive-action"])
- self.send_button.get_child().set_label("Stop")
- self.send_button.get_child().set_icon_name("edit-delete-symbolic")
- self.toggle_ui_sensitive(False)
- self.image_button.set_sensitive(False)
-
- self.show_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), False, f"\n\n{formated_datetime}", self.attached_image["base64"])
- 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)
- self.show_message("", True)
-
- vadjustment = self.chat_window.get_vadjustment()
- vadjustment.set_value(vadjustment.get_upper())
- thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model']))
- thread.start()
-
def pull_model_update(self, data, model_name):
if model_name in list(self.pulling_models.keys()):
GLib.idle_add(self.pulling_models[model_name].set_subtitle, data['status'] + (f" | {round(data['completed'] / data['total'] * 100, 2)}%" if 'completed' in data and 'total' in data else ""))
@@ -548,30 +600,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
model.add_suffix(pull_button)
self.available_model_list_box.append(model)
- @Gtk.Template.Callback()
- def manage_models_button_activate(self, button=None):
- self.update_list_local_models()
- self.manage_models_dialog.present(self)
-
- @Gtk.Template.Callback()
- def welcome_carousel_page_changed(self, carousel, index):
- 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("Connect")
- else: self.welcome_next_button.set_label("Next")
-
- @Gtk.Template.Callback()
- def welcome_previous_button_activate(self, button):
- self.welcome_carousel.scroll_to(self.welcome_carousel.get_nth_page(self.welcome_carousel.get_position()-1), True)
-
- @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)
- else:
- self.welcome_dialog.force_close()
- if not self.verify_connection():
- self.connection_error()
-
def save_history(self):
with open(os.path.join(self.config_dir, "chats.json"), "w+") as f:
json.dump(self.chats, f, indent=4)
@@ -628,14 +656,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.image_button.get_child().set_icon_name("image-x-generic-symbolic")
self.attached_image = {"path": None, "base64": None}
- @Gtk.Template.Callback()
- def open_image(self, button):
- if "destructive-action" in button.get_css_classes():
- dialogs.remove_image(self)
- else:
- file_dialog = Gtk.FileDialog(default_filter=self.file_filter_image)
- file_dialog.open(self, None, self.load_image)
-
def generate_numbered_chat_name(self, chat_name) -> str:
if chat_name in self.chats["chats"]:
for i in range(len(list(self.chats["chats"].keys()))):
@@ -723,17 +743,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
for name, content in self.chats['chats'].items():
self.new_chat_element(name)
- @Gtk.Template.Callback()
- def chat_changed(self, listbox, row):
- if row and row.get_name() != self.chats["selected_chat"]:
- self.chats["selected_chat"] = row.get_name()
- self.load_history_into_chat()
- if len(self.chats["chats"][self.chats["selected_chat"]]["messages"]) > 0:
- for i in range(self.model_string_list.get_n_items()):
- if self.model_string_list.get_string(i) == self.chats["chats"][self.chats["selected_chat"]]["messages"][-1]["model"]:
- self.model_drop_down.set_selected(i)
- break
-
def show_preferences_dialog(self):
self.preferences_dialog.present(self)
@@ -771,15 +780,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
if self.verify_connection() == False: self.connection_error()
self.update_list_available_models()
- @Gtk.Template.Callback()
- def change_remote_url(self, entry):
- self.remote_url = entry.get_text()
- if self.run_remote:
- connection_handler.url = self.remote_url
- if self.verify_connection() == False:
- entry.set_css_classes(["error"])
- self.show_toast("error", 1, self.preferences_dialog)
-
def on_replace_contents(self, file, result):
file.replace_contents_finish(result)
self.show_toast("good", 2, self.main_overlay)