Remade model selector
This commit is contained in:
140
src/window.py
140
src/window.py
@@ -107,8 +107,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
file_filter_gguf = Gtk.Template.Child()
|
||||
file_filter_attachments = Gtk.Template.Child()
|
||||
attachment_button = Gtk.Template.Child()
|
||||
model_drop_down = Gtk.Template.Child()
|
||||
model_string_list = Gtk.Template.Child()
|
||||
chat_right_click_menu = Gtk.Template.Child()
|
||||
model_tag_list_box = Gtk.Template.Child()
|
||||
navigation_view_manage_models = Gtk.Template.Child()
|
||||
@@ -118,6 +116,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
model_searchbar = Gtk.Template.Child()
|
||||
no_results_page = Gtk.Template.Child()
|
||||
model_link_button = Gtk.Template.Child()
|
||||
model_list_box = Gtk.Template.Child()
|
||||
model_popover = Gtk.Template.Child()
|
||||
model_selector_button = Gtk.Template.Child()
|
||||
|
||||
manage_models_dialog = Gtk.Template.Child()
|
||||
pulling_model_list_box = Gtk.Template.Child()
|
||||
@@ -136,22 +137,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
|
||||
style_manager = Adw.StyleManager()
|
||||
|
||||
@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
|
||||
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():
|
||||
if content['type'] == 'image':
|
||||
content['button'].set_css_classes(["flat"])
|
||||
return True
|
||||
for name, content in self.attachments.items():
|
||||
if content['type'] == 'image':
|
||||
content['button'].set_css_classes(["flat", "error"])
|
||||
return False
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def stop_message(self, button=None):
|
||||
if self.loading_spinner:
|
||||
@@ -191,7 +176,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
self.chats['order'].remove(self.chats['selected_chat'])
|
||||
self.chats['order'].insert(0, self.chats['selected_chat'])
|
||||
self.save_history()
|
||||
current_model = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1)
|
||||
current_model = self.get_current_model(1)
|
||||
if current_model is None:
|
||||
self.show_toast(_("Please select a model before chatting"), self.main_overlay)
|
||||
return
|
||||
@@ -288,10 +273,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
self.load_history_into_chat()
|
||||
if len(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()) > 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.convert_model_name(last_model_used, 0)
|
||||
for i in range(self.model_string_list.get_n_items()):
|
||||
if self.model_string_list.get_string(i) == last_model_used:
|
||||
self.model_drop_down.set_selected(i)
|
||||
for i, m in enumerate(self.local_models):
|
||||
if m == last_model_used:
|
||||
self.model_list_box.select_row(self.model_list_box.get_row_at_index(i))
|
||||
break
|
||||
self.save_history()
|
||||
|
||||
@@ -427,11 +411,69 @@ class AlpacaWindow(Adw.ApplicationWindow):
|
||||
self.available_model_list_box.set_visible(True)
|
||||
self.no_results_page.set_visible(False)
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def close_model_popup(self, *_):
|
||||
self.model_popover.hide()
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def change_model(self, listbox=None, row=None):
|
||||
if not row:
|
||||
current_model = self.convert_model_name(self.model_selector_button.get_child().get_label(), 1)
|
||||
print("c ", current_model)
|
||||
for i, m in enumerate(self.local_models):
|
||||
if m == current_model:
|
||||
self.model_list_box.select_row(self.model_list_box.get_row_at_index(i))
|
||||
return
|
||||
self.model_list_box.select_row(self.model_list_box.get_row_at_index(0))
|
||||
return
|
||||
button_content = Gtk.Box(
|
||||
spacing=10
|
||||
)
|
||||
button_content.append(
|
||||
Gtk.Label(
|
||||
label=row.get_child().get_label(),
|
||||
ellipsize=2
|
||||
)
|
||||
)
|
||||
button_content.append(
|
||||
Gtk.Image.new_from_icon_name("down-symbolic")
|
||||
)
|
||||
self.model_selector_button.set_child(button_content)
|
||||
self.close_model_popup()
|
||||
self.verify_if_image_can_be_used()
|
||||
|
||||
def verify_if_image_can_be_used(self):
|
||||
logger.debug("Verifying if image can be used")
|
||||
selected = self.get_current_model(1)
|
||||
if selected == None:
|
||||
return True
|
||||
selected = selected.split(":")[0]
|
||||
if selected in [key for key, value in self.available_models.items() if value["image"]]:
|
||||
for name, content in self.attachments.items():
|
||||
if content['type'] == 'image':
|
||||
content['button'].set_css_classes(["flat"])
|
||||
return True
|
||||
for name, content in self.attachments.items():
|
||||
if content['type'] == 'image':
|
||||
content['button'].set_css_classes(["flat", "error"])
|
||||
return False
|
||||
|
||||
def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag
|
||||
try:
|
||||
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])
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def get_current_model(self, mode:int) -> str:
|
||||
if not self.model_list_box.get_selected_row():
|
||||
return None
|
||||
if mode == 0:
|
||||
return "{} ({})".format(name.split(":")[0].replace("-", " ").title(), name.split(":")[1])
|
||||
return self.model_list_box.get_selected_row().get_child().get_label()
|
||||
if mode == 1:
|
||||
return "{}:{}".format(name.split(" (")[0].replace(" ", "-").lower(), name.split(" (")[1][:-1])
|
||||
return self.model_list_box.get_selected_row().get_name()
|
||||
|
||||
def check_alphanumeric(self, editable, text, length, position):
|
||||
new_text = ''.join([char for char in text if char.isalnum() or char in ['-', '.', ':', '_']])
|
||||
@@ -593,7 +635,7 @@ Generate a title following these rules:
|
||||
```PROMPT
|
||||
{message['content']}
|
||||
```"""
|
||||
current_model = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1)
|
||||
current_model = self.get_current_model(1)
|
||||
data = {"model": current_model, "prompt": prompt, "stream": False}
|
||||
if 'images' in message:
|
||||
data["images"] = message['images']
|
||||
@@ -776,8 +818,7 @@ Generate a title following these rules:
|
||||
logger.debug("Updating list of local models")
|
||||
self.local_models = []
|
||||
response = connection_handler.simple_get(f"{connection_handler.url}/api/tags")
|
||||
for i in range(self.model_string_list.get_n_items() -1, -1, -1):
|
||||
self.model_string_list.remove(i)
|
||||
self.model_list_box.remove_all()
|
||||
if response.status_code == 200:
|
||||
self.local_model_list_box.remove_all()
|
||||
if len(json.loads(response.text)['models']) == 0:
|
||||
@@ -801,9 +842,17 @@ Generate a title following these rules:
|
||||
model_row.add_suffix(button)
|
||||
self.local_model_list_box.append(model_row)
|
||||
|
||||
self.model_string_list.append(model_name)
|
||||
selector_row = Gtk.ListBoxRow(
|
||||
child = Gtk.Label(
|
||||
label=model_name, halign=1, hexpand=True
|
||||
),
|
||||
halign=0,
|
||||
hexpand=True,
|
||||
name=model["name"],
|
||||
tooltip_text=model_name
|
||||
)
|
||||
self.model_list_box.append(selector_row)
|
||||
self.local_models.append(model["name"])
|
||||
#self.verify_if_image_can_be_used()
|
||||
else:
|
||||
self.connection_error()
|
||||
|
||||
@@ -1058,7 +1107,7 @@ Generate a title following these rules:
|
||||
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),
|
||||
"model": self.get_current_model(1),
|
||||
"messages": history,
|
||||
"options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]},
|
||||
"keep_alive": f"{self.model_tweaks['keep_alive']}m"
|
||||
@@ -1091,6 +1140,7 @@ Generate a title following these rules:
|
||||
data = {"name": model}
|
||||
response = connection_handler.stream_post(f"{connection_handler.url}/api/pull", data=json.dumps(data), callback=lambda data, model_name=model: self.pull_model_update(data, model_name))
|
||||
GLib.idle_add(self.update_list_local_models)
|
||||
GLib.idle_add(self.change_model)
|
||||
|
||||
if response.status_code == 200 and 'error' not in self.pulling_models[model]:
|
||||
GLib.idle_add(self.show_notification, _("Task Complete"), _("Model '{}' pulled successfully.").format(model), Gio.ThemedIcon.new("emblem-ok-symbolic"))
|
||||
@@ -1239,10 +1289,9 @@ Generate a title following these rules:
|
||||
self.chats["order"].append(chat_name)
|
||||
if len(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()) > 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.convert_model_name(last_model_used, 0)
|
||||
for i in range(self.model_string_list.get_n_items()):
|
||||
if self.model_string_list.get_string(i) == last_model_used:
|
||||
self.model_drop_down.set_selected(i)
|
||||
for i, m in enumerate(self.local_models):
|
||||
if m == last_model_used:
|
||||
self.model_list_box.select_row(self.model_list_box.get_row_at_index(i))
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
@@ -1322,6 +1371,7 @@ Generate a title following these rules:
|
||||
self.update_list_local_models()
|
||||
if response.status_code == 200:
|
||||
self.show_toast(_("Model deleted successfully"), self.manage_models_overlay)
|
||||
self.change_model()
|
||||
else:
|
||||
self.manage_models_dialog.close()
|
||||
self.connection_error()
|
||||
@@ -1644,25 +1694,6 @@ Generate a title following these rules:
|
||||
clipboard.read_text_async(None, self.cb_text_received)
|
||||
clipboard.read_texture_async(None, self.cb_image_received)
|
||||
|
||||
|
||||
def on_model_dropdown_setup(self, factory, list_item):
|
||||
label = Gtk.Label()
|
||||
label.set_ellipsize(2)
|
||||
label.set_xalign(0)
|
||||
list_item.set_child(label)
|
||||
|
||||
def on_model_dropdown_bind(self, factory, list_item):
|
||||
label = list_item.get_child()
|
||||
item = list_item.get_item()
|
||||
label.set_text(item.get_string())
|
||||
label.set_tooltip_text(item.get_string())
|
||||
|
||||
def setup_model_dropdown(self):
|
||||
factory = Gtk.SignalListItemFactory()
|
||||
factory.connect("setup", self.on_model_dropdown_setup)
|
||||
factory.connect("bind", self.on_model_dropdown_bind)
|
||||
self.model_drop_down.set_factory(factory)
|
||||
|
||||
def handle_enter_key(self):
|
||||
self.send_message()
|
||||
return True
|
||||
@@ -1701,7 +1732,6 @@ Generate a title following these rules:
|
||||
self.remote_connection_entry.connect("entry-activated", lambda entry : entry.set_css_classes([]))
|
||||
self.remote_connection_switch.connect("notify", lambda pspec, user_data : self.connection_switched())
|
||||
self.background_switch.connect("notify", lambda pspec, user_data : self.switch_run_on_background())
|
||||
self.setup_model_dropdown()
|
||||
if os.path.exists(os.path.join(self.config_dir, "server.json")):
|
||||
with open(os.path.join(self.config_dir, "server.json"), "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
Reference in New Issue
Block a user