Added welcome screen

This commit is contained in:
jeffser 2024-08-07 20:39:46 -06:00
parent c873b49700
commit a9112cf3da

View File

@ -19,7 +19,7 @@
""" """
Handles the main window Handles the main window
""" """
import json, threading, os, re, base64, sys, gettext, uuid, shutil, tarfile, tempfile, logging import json, threading, os, re, base64, sys, gettext, uuid, shutil, tarfile, tempfile, logging, random
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image
from pypdf import PdfReader from pypdf import PdfReader
@ -119,6 +119,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
model_list_box = Gtk.Template.Child() model_list_box = Gtk.Template.Child()
model_popover = Gtk.Template.Child() model_popover = Gtk.Template.Child()
model_selector_button = Gtk.Template.Child() model_selector_button = Gtk.Template.Child()
chat_welcome_screen : Adw.StatusPage = None
manage_models_dialog = Gtk.Template.Child() manage_models_dialog = Gtk.Template.Child()
pulling_model_list_box = Gtk.Template.Child() pulling_model_list_box = Gtk.Template.Child()
@ -142,7 +143,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
if self.loading_spinner: if self.loading_spinner:
self.chat_container.remove(self.loading_spinner) self.chat_container.remove(self.loading_spinner)
self.toggle_ui_sensitive(True) self.toggle_ui_sensitive(True)
self.switch_send_stop_button() self.switch_send_stop_button(True)
self.bot_message = None self.bot_message = None
self.bot_message_box = None self.bot_message_box = None
self.bot_message_view = None self.bot_message_view = None
@ -164,8 +165,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.save_history() self.save_history()
self.show_toast(_("Message edited successfully"), self.main_overlay) 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): 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 return
current_chat_row = self.chat_list_box.get_selected_row() current_chat_row = self.chat_list_box.get_selected_row()
@ -217,7 +216,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
"options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]}, "options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]},
"keep_alive": f"{self.model_tweaks['keep_alive']}m" "keep_alive": f"{self.model_tweaks['keep_alive']}m"
} }
self.switch_send_stop_button() self.switch_send_stop_button(False)
self.toggle_ui_sensitive(False) self.toggle_ui_sensitive(False)
#self.attachments[name] = {"path": file_path, "type": file_type, "content": content} #self.attachments[name] = {"path": file_path, "type": file_type, "content": content}
@ -230,6 +229,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
bot_id=self.generate_uuid() bot_id=self.generate_uuid()
self.show_message("", True, message_id=bot_id) self.show_message("", True, message_id=bot_id)
if self.chat_welcome_screen:
self.chat_container.remove(self.chat_welcome_screen)
thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], bot_id)) thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], bot_id))
thread.start() thread.start()
if len(data['messages']) == 1: if len(data['messages']) == 1:
@ -271,12 +273,14 @@ class AlpacaWindow(Adw.ApplicationWindow):
if row and row.get_child().get_name() != self.chats["selected_chat"]: if row and row.get_child().get_name() != self.chats["selected_chat"]:
self.chats["selected_chat"] = row.get_child().get_name() self.chats["selected_chat"] = row.get_child().get_name()
self.load_history_into_chat() self.load_history_into_chat()
if len(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()) > 0: if len(self.chats["chats"][self.chats["selected_chat"]]["messages"]) > 0:
last_model_used = self.chats["chats"][self.chats["selected_chat"]]["messages"][list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys())[-1]]["model"] last_model_used = self.chats["chats"][self.chats["selected_chat"]]["messages"][list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys())[-1]]["model"]
for i, m in enumerate(self.local_models): for i, m in enumerate(self.local_models):
if m == last_model_used: if m == last_model_used:
self.model_list_box.select_row(self.model_list_box.get_row_at_index(i)) self.model_list_box.select_row(self.model_list_box.get_row_at_index(i))
break break
else:
self.load_history_into_chat()
self.save_history() self.save_history()
@Gtk.Template.Callback() @Gtk.Template.Callback()
@ -536,6 +540,8 @@ class AlpacaWindow(Adw.ApplicationWindow):
if os.path.exists(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_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)) shutil.rmtree(os.path.join(self.data_dir, "chats", self.chats['selected_chat'], message_id))
self.save_history() self.save_history()
if len(self.chats["chats"][self.chats["selected_chat"]]["messages"]) == 0:
self.load_history_into_chat()
def copy_message(self, message_element): def copy_message(self, message_element):
logger.debug("Copying message") logger.debug("Copying message")
@ -594,7 +600,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.file_preview_text_view.set_visible(True) self.file_preview_text_view.set_visible(True)
buffer = self.file_preview_text_view.get_buffer() buffer = self.file_preview_text_view.get_buffer()
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter()) buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
buffer.insert(buffer.get_start_iter(), content, len(content)) buffer.insert(buffer.get_start_iter(), content, len(content.encode('utf-8')))
if file_type == 'youtube': if file_type == 'youtube':
self.file_preview_dialog.set_title(content.split('\n')[0]) self.file_preview_dialog.set_title(content.split('\n')[0])
self.file_preview_open_button.set_name(content.split('\n')[2]) self.file_preview_open_button.set_name(content.split('\n')[2])
@ -1055,9 +1061,9 @@ Generate a title following these rules:
for element in [self.chat_list_box, self.add_chat_button, self.secondary_menu_button]: for element in [self.chat_list_box, self.add_chat_button, self.secondary_menu_button]:
element.set_sensitive(status) element.set_sensitive(status)
def switch_send_stop_button(self): def switch_send_stop_button(self, send:bool):
self.stop_button.set_visible(self.send_button.get_visible()) self.stop_button.set_visible(not send)
self.send_button.set_visible(not self.send_button.get_visible()) self.send_button.set_visible(send)
def run_message(self, messages, model, message_id): def run_message(self, messages, model, message_id):
logger.debug("Running message") logger.debug("Running message")
@ -1088,7 +1094,7 @@ Generate a title following these rules:
GLib.idle_add(self.chat_container.append, self.regenerate_button) GLib.idle_add(self.chat_container.append, self.regenerate_button)
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)) 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: finally:
GLib.idle_add(self.switch_send_stop_button) GLib.idle_add(self.switch_send_stop_button, True)
GLib.idle_add(self.toggle_ui_sensitive, True) GLib.idle_add(self.toggle_ui_sensitive, True)
if self.loading_spinner: if self.loading_spinner:
GLib.idle_add(self.chat_container.remove, self.loading_spinner) GLib.idle_add(self.chat_container.remove, self.loading_spinner)
@ -1118,7 +1124,7 @@ Generate a title following these rules:
"options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]}, "options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]},
"keep_alive": f"{self.model_tweaks['keep_alive']}m" "keep_alive": f"{self.model_tweaks['keep_alive']}m"
} }
self.switch_send_stop_button() self.switch_send_stop_button(False)
self.toggle_ui_sensitive(False) self.toggle_ui_sensitive(False)
thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], message_id)) thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], message_id))
thread.start() thread.start()
@ -1267,17 +1273,51 @@ Generate a title following these rules:
with open(os.path.join(self.data_dir, "chats", "chats.json"), "w+", encoding="utf-8") as f: with open(os.path.join(self.data_dir, "chats", "chats.json"), "w+", encoding="utf-8") as f:
json.dump(self.chats, f, indent=4) json.dump(self.chats, f, indent=4)
def send_sample_prompt(self, prompt):
buffer = self.message_text_view.get_buffer()
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
buffer.insert(buffer.get_start_iter(), prompt, len(prompt.encode('utf-8')))
self.send_message()
def load_history_into_chat(self): def load_history_into_chat(self):
for widget in list(self.chat_container): self.chat_container.remove(widget) for widget in list(self.chat_container): self.chat_container.remove(widget)
for key, message in self.chats['chats'][self.chats["selected_chat"]]['messages'].items(): self.chat_welcome_screen = None
if message: if len(self.chats['chats'][self.chats["selected_chat"]]['messages']) > 0:
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'))) for key, message in self.chats['chats'][self.chats["selected_chat"]]['messages'].items():
if message['role'] == 'user': if message:
self.show_message(message['content'], False, f"\n\n<small>{formated_date}</small>", message['images'] if 'images' in message else None, message['files'] if 'files' in message else None, message_id=key) 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')))
else: if message['role'] == 'user':
self.show_message(message['content'], True, f"\n\n{self.convert_model_name(message['model'], 0)}\n<small>{formated_date}</small>", message_id=key) self.show_message(message['content'], False, f"\n\n<small>{formated_date}</small>", message['images'] if 'images' in message else None, message['files'] if 'files' in message else None, message_id=key)
self.add_code_blocks() else:
self.bot_message = None self.show_message(message['content'], True, f"\n\n{self.convert_model_name(message['model'], 0)}\n<small>{formated_date}</small>", message_id=key)
self.add_code_blocks()
self.bot_message = None
else:
possible_prompts = [
"What can you do?",
"Give me a pancake recipe",
"Why is the sky blue?"
]
prompt_container = Gtk.Box(
orientation = 1,
spacing = 10,
halign = 3
)
for prompt in random.sample(possible_prompts, 3):
prompt_button = Gtk.Button(
label=prompt
)
prompt_button.connect('clicked', lambda *_, prompt=prompt : self.send_sample_prompt(prompt))
prompt_container.append(prompt_button)
self.chat_welcome_screen = Adw.StatusPage(
icon_name="com.jeffser.Alpaca",
title="Alpaca",
description="Try one of these prompts",
child=prompt_container,
vexpand=True
)
self.chat_container.append(self.chat_welcome_screen)
def load_history(self): def load_history(self):
logger.debug("Loading history") logger.debug("Loading history")