24 Commits
2.6.0 ... 2.6.5

Author SHA1 Message Date
jeffser
3253e67680 Update to snap 2024-10-13 17:08:42 -06:00
jeffser
e189769f3f Updated spanish 2024-10-13 17:07:33 -06:00
jeffser
f6637493db Update languages 2024-10-13 17:03:00 -06:00
jeffser
063da38597 Preparing for 2.6.5 2024-10-13 16:24:20 -06:00
jeffser
7587b03828 Added Exception as e so it can catch everything 2024-10-13 15:21:39 -06:00
jeffser
8fffb64f79 the 2024-10-13 15:07:20 -06:00
aritra saha
735eae0d0e Update bn.po (#346)
* Update bn.po

* Update bn.po
2024-10-13 14:39:45 -06:00
jeffser
8c98be6ef6 Integrated instance indicator on preferences 2024-10-13 10:27:18 -06:00
jeffser
115e22e52c Added warning if model is too large for system 2024-10-13 10:00:43 -06:00
jeffser
792a81ad03 Restore Ollama logging 2024-10-13 09:57:52 -06:00
jeffser
2ea0ff6870 Removed webiste button in creation page 2024-10-12 18:47:20 -06:00
jeffser
6242087152 Replace model selector with button if there aren't any models download 2024-10-12 17:25:34 -06:00
aritra saha
1da6e31de1 Update hi.po (#345) 2024-10-12 17:07:09 -06:00
aritra saha
cb4979ab7c Update bn.po (#344)
* Update bn.po

* Update bn.po
2024-10-12 17:06:55 -06:00
jeffser
da653c754d Added create button to details and fixed some css 2024-10-12 17:01:54 -06:00
jeffser
c4907b81fd Fixed datetime bug 2024-10-12 13:29:54 -06:00
jeffser
4c104560d5 Chaged styling 2024-10-11 22:51:51 -06:00
jeffser
2253e378ac Updated spanish 2024-10-11 22:45:20 -06:00
jeffser
ba66ac40a3 Updated translations 2024-10-11 22:44:53 -06:00
jeffser
40d0d92498 Forgot one translation 2024-10-11 22:44:22 -06:00
jeffser
4ed6cf8e18 Updated spanish 2024-10-11 22:42:49 -06:00
jeffser
3fc1c74f51 Updated translations 2024-10-11 22:41:17 -06:00
jeffser
150e8779c7 New 'model details' page 2024-10-11 22:40:31 -06:00
Jeffry Samuel
5462248565 Update README.md 2024-10-11 19:08:35 -06:00
24 changed files with 8185 additions and 7001 deletions

View File

@@ -33,7 +33,7 @@ Alpaca is an [Ollama](https://github.com/ollama/ollama) client where you can man
Normal conversation | Image recognition | Code highlighting | YouTube transcription | Model management Normal conversation | Image recognition | Code highlighting | YouTube transcription | Model management
:------------------:|:-----------------:|:-----------------:|:---------------------:|:----------------: :------------------:|:-----------------:|:-----------------:|:---------------------:|:----------------:
![screenie1](https://jeffser.com/images/alpaca/screenie1.png) | ![screenie2](https://jeffser.com/images/alpaca/screenie2.png) | ![screenie3](https://jeffser.com/images/alpaca/screenie3.png) | ![screenie4](https://jeffser.com/images/alpaca/screenie4.png) | ![screenie5](https://jeffser.com/images/alpaca/screenie5.png) ![screenie1](https://jeffser.com/images/alpaca/screenie1.png) | ![screenie2](https://jeffser.com/images/alpaca/screenie2.png) | ![screenie3](https://jeffser.com/images/alpaca/screenie3.png) | ![screenie4](https://jeffser.com/images/alpaca/screenie5.png) | ![screenie5](https://jeffser.com/images/alpaca/screenie6.png)
## Installation ## Installation

View File

@@ -82,6 +82,18 @@
<url type="contribute">https://github.com/Jeffser/Alpaca/discussions/154</url> <url type="contribute">https://github.com/Jeffser/Alpaca/discussions/154</url>
<url type="vcs-browser">https://github.com/Jeffser/Alpaca</url> <url type="vcs-browser">https://github.com/Jeffser/Alpaca</url>
<releases> <releases>
<release version="2.6.5" date="2024-10-13">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/2.6.5</url>
<description>
<p>New</p>
<ul>
<li>Details page for models</li>
<li>Model selector gets replaced with 'manage models' button when there are no models downloaded</li>
<li>Added warning when model is too big for the device</li>
<li>Added AMD GPU indicator in preferences</li>
</ul>
</description>
</release>
<release version="2.6.0" date="2024-10-11"> <release version="2.6.0" date="2024-10-11">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/2.6.0</url> <url type="details">https://github.com/Jeffser/Alpaca/releases/tag/2.6.0</url>
<description> <description>

View File

@@ -1,5 +1,5 @@
project('Alpaca', 'c', project('Alpaca', 'c',
version: '2.6.0', version: '2.6.5',
meson_version: '>= 0.62.0', meson_version: '>= 0.62.0',
default_options: [ 'warning_level=2', 'werror=false', ], default_options: [ 'warning_level=2', 'werror=false', ],
) )

File diff suppressed because it is too large Load Diff

1093
po/bn.po

File diff suppressed because it is too large Load Diff

1062
po/de.po

File diff suppressed because it is too large Load Diff

1070
po/es.po

File diff suppressed because it is too large Load Diff

1062
po/fr.po

File diff suppressed because it is too large Load Diff

1062
po/he.po

File diff suppressed because it is too large Load Diff

1094
po/hi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1059
po/ru.po

File diff suppressed because it is too large Load Diff

1062
po/te.po

File diff suppressed because it is too large Load Diff

1062
po/tr.po

File diff suppressed because it is too large Load Diff

1062
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
name: alpaca name: jeffser-alpaca
base: core24 base: core24
adopt-info: alpaca adopt-info: alpaca
@@ -63,14 +63,15 @@ parts:
ollama: ollama:
plugin: dump plugin: dump
source: source:
- on amd64: https://github.com/ollama/ollama/releases/download/v0.3.10/ollama-linux-amd64.tgz - on amd64: https://github.com/ollama/ollama/releases/download/v0.3.12/ollama-linux-amd64.tgz
- on arm64: https://github.com/ollama/ollama/releases/download/v0.3.10/ollama-linux-arm64.tgz - on arm64: https://github.com/ollama/ollama/releases/download/v0.3.12/ollama-linux-arm64.tgz
# Alpaca app # Alpaca app
alpaca: alpaca:
plugin: meson plugin: meson
source-type: git source-type: git
source: https://github.com/Jeffser/Alpaca.git source: https://github.com/Jeffser/Alpaca.git
source-tag: 2.6.5
source-depth: 1 source-depth: 1
meson-parameters: meson-parameters:
- --prefix=/snap/alpaca/current/usr - --prefix=/snap/alpaca/current/usr

View File

@@ -33,6 +33,7 @@
<file alias="icons/scalable/status/chat-bubble-text-symbolic.svg">icons/chat-bubble-text-symbolic.svg</file> <file alias="icons/scalable/status/chat-bubble-text-symbolic.svg">icons/chat-bubble-text-symbolic.svg</file>
<file alias="icons/scalable/status/execute-from-symbolic.svg">icons/execute-from-symbolic.svg</file> <file alias="icons/scalable/status/execute-from-symbolic.svg">icons/execute-from-symbolic.svg</file>
<file alias="icons/scalable/status/cross-large-symbolic.svg">icons/cross-large-symbolic.svg</file> <file alias="icons/scalable/status/cross-large-symbolic.svg">icons/cross-large-symbolic.svg</file>
<file alias="icons/scalable/status/info-outline-symbolic.svg">icons/info-outline-symbolic.svg</file>
<file preprocess="xml-stripblanks">window.ui</file> <file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file> <file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
</gresource> </gresource>

View File

@@ -16,10 +16,18 @@ def log_output(pipe):
with pipe: with pipe:
try: try:
for line in iter(pipe.readline, ''): for line in iter(pipe.readline, ''):
#print(line, end='') print(line, end='')
f.write(line) f.write(line)
f.flush() f.flush()
except: if 'msg="model request too large for system"' in line:
window.show_toast(_("Model request too large for system"), window.main_overlay)
elif 'msg="amdgpu detected, but no compatible rocm library found.' in line:
window.ollama_information_label.set_label(_("AMD GPU detected but the extension is missing, Ollama will use CPU"))
window.ollama_information_label.set_css_classes(['dim-label', 'error'])
elif 'msg="amdgpu is supported"' in line:
window.ollama_information_label.set_label(_("Using AMD GPU type '{}'").format(line.split('=')[-1]))
window.ollama_information_label.set_css_classes(['dim-label', 'success'])
except Exception as e:
pass pass
class instance(): class instance():
@@ -116,6 +124,8 @@ class instance():
self.instance = instance self.instance = instance
if not self.idle_timer: if not self.idle_timer:
self.start_timer() self.start_timer()
window.ollama_information_label.set_label(_("Integrated Ollama instance is running"))
window.ollama_information_label.set_css_classes(['dim-label', 'success'])
else: else:
self.remote = True self.remote = True
window.remote_connection_switch.set_sensitive(True) window.remote_connection_switch.set_sensitive(True)
@@ -130,6 +140,8 @@ class instance():
self.instance.terminate() self.instance.terminate()
self.instance.wait() self.instance.wait()
self.instance = None self.instance = None
window.ollama_information_label.set_label(_("Integrated Ollama instance is not running"))
window.ollama_information_label.set_css_classes(['dim-label'])
logger.info("Stopped Alpaca's Ollama instance") logger.info("Stopped Alpaca's Ollama instance")
def reset(self): def reset(self):

View File

@@ -56,7 +56,7 @@ class model_selector_popup(Gtk.Popover):
class model_selector_row(Gtk.ListBoxRow): class model_selector_row(Gtk.ListBoxRow):
__gtype_name__ = 'AlpacaModelSelectorRow' __gtype_name__ = 'AlpacaModelSelectorRow'
def __init__(self, model_name:str, image_recognition:bool): def __init__(self, model_name:str, data:dict):
super().__init__( super().__init__(
child = Gtk.Label( child = Gtk.Label(
label=window.convert_model_name(model_name, 0), label=window.convert_model_name(model_name, 0),
@@ -68,7 +68,8 @@ class model_selector_row(Gtk.ListBoxRow):
name=model_name, name=model_name,
tooltip_text=window.convert_model_name(model_name, 0) tooltip_text=window.convert_model_name(model_name, 0)
) )
self.image_recognition = image_recognition self.data = data
self.image_recognition = 'projector_info' in self.data
class model_selector_button(Gtk.MenuButton): class model_selector_button(Gtk.MenuButton):
__gtype_name__ = 'AlpacaModelSelectorButton' __gtype_name__ = 'AlpacaModelSelectorButton'
@@ -81,11 +82,10 @@ class model_selector_button(Gtk.MenuButton):
orientation=0, orientation=0,
spacing=5 spacing=5
) )
self.label = Gtk.Label(label=_('Select a Model')) self.label = Gtk.Label()
container.append(self.label) container.append(self.label)
container.append(Gtk.Image.new_from_icon_name("down-symbolic")) container.append(Gtk.Image.new_from_icon_name("down-symbolic"))
super().__init__( super().__init__(
tooltip_text=_('Select a Model'),
child=container, child=container,
popover=self.popover, popover=self.popover,
halign=3 halign=3
@@ -104,27 +104,28 @@ class model_selector_button(Gtk.MenuButton):
self.label.set_label(window.convert_model_name(model_name, 0)) self.label.set_label(window.convert_model_name(model_name, 0))
self.set_tooltip_text(window.convert_model_name(model_name, 0)) self.set_tooltip_text(window.convert_model_name(model_name, 0))
elif len(list(listbox)) == 0: elif len(list(listbox)) == 0:
self.label.set_label(_("Select a Model")) window.title_stack.set_visible_child_name('no_models')
self.set_tooltip_text(_("Select a Model"))
window.model_manager.verify_if_image_can_be_used() window.model_manager.verify_if_image_can_be_used()
def add_model(self, model_name:str): def add_model(self, model_name:str):
vision = False data = None
response = window.ollama_instance.request("POST", "api/show", json.dumps({"name": model_name})) response = window.ollama_instance.request("POST", "api/show", json.dumps({"name": model_name}))
if response.status_code != 200: if response.status_code != 200:
logger.error(f"Status code was {response.status_code}") logger.error(f"Status code was {response.status_code}")
return return
try: try:
vision = 'projector_info' in json.loads(response.text) data = json.loads(response.text)
except Exception as e: except Exception as e:
logger.error(f"Error fetching vision info: {str(e)}") logger.error(f"Error fetching 'api - show' info: {str(e)}")
model_row = model_selector_row(model_name, vision) model_row = model_selector_row(model_name, data)
GLib.idle_add(self.get_popover().model_list_box.append, model_row) GLib.idle_add(self.get_popover().model_list_box.append, model_row)
GLib.idle_add(self.change_model, model_name) GLib.idle_add(self.change_model, model_name)
GLib.idle_add(window.title_stack.set_visible_child_name, 'model_selector')
def remove_model(self, model_name:str): def remove_model(self, model_name:str):
self.get_popover().model_list_box.remove(next((model for model in list(self.get_popover().model_list_box) if model.get_name() == model_name), None)) self.get_popover().model_list_box.remove(next((model for model in list(self.get_popover().model_list_box) if model.get_name() == model_name), None))
self.model_changed(self.get_popover().model_list_box) self.model_changed(self.get_popover().model_list_box)
window.title_stack.set_visible_child_name('model_selector' if len(window.model_manager.get_model_list()) > 0 else 'no_models')
def clear_list(self): def clear_list(self):
self.get_popover().model_list_box.remove_all() self.get_popover().model_list_box.remove_all()
@@ -248,6 +249,37 @@ class pulling_model_list(Gtk.ListBox):
visible=False visible=False
) )
class information_bow(Gtk.Box):
__gtype_name__ = 'AlpacaModelInformationBow'
def __init__(self, title:str, subtitle:str):
self.title = title
self.subtitle = subtitle
title_label = Gtk.Label(
label=self.title,
css_classes=['subtitle', 'caption', 'dim-label'],
hexpand=True,
margin_top=10,
margin_start=0,
margin_end=0
)
subtitle_label = Gtk.Label(
label=self.subtitle if self.subtitle else '(none)',
css_classes=['heading'],
hexpand=True,
margin_bottom=10,
margin_start=0,
margin_end=0
)
super().__init__(
spacing=5,
orientation=1,
css_classes=['card']
)
self.append(title_label)
self.append(subtitle_label)
class local_model(Gtk.ListBoxRow): class local_model(Gtk.ListBoxRow):
__gtype_name__ = 'AlpacaLocalModel' __gtype_name__ = 'AlpacaLocalModel'
@@ -275,6 +307,16 @@ class local_model(Gtk.ListBoxRow):
description_box.append(model_label) description_box.append(model_label)
description_box.append(tag_label) description_box.append(tag_label)
info_button = Gtk.Button(
icon_name = "info-outline-symbolic",
vexpand = False,
valign = 3,
css_classes = ["circular"],
tooltip_text = _("Details")
)
info_button.connect('clicked', self.show_information)
delete_button = Gtk.Button( delete_button = Gtk.Button(
icon_name = "user-trash-symbolic", icon_name = "user-trash-symbolic",
vexpand = False, vexpand = False,
@@ -302,6 +344,7 @@ class local_model(Gtk.ListBoxRow):
margin_end=10 margin_end=10
) )
container_box.append(description_box) container_box.append(description_box)
container_box.append(info_button)
container_box.append(delete_button) container_box.append(delete_button)
super().__init__( super().__init__(
@@ -309,6 +352,53 @@ class local_model(Gtk.ListBoxRow):
name=model_name name=model_name
) )
def show_information(self, button):
model = next((element for element in list(window.model_manager.model_selector.get_popover().model_list_box) if element.get_name() == self.get_name()), None)
model_name = model.get_child().get_label()
window.model_detail_page.set_title(' ('.join(model_name.split(' (')[:-1]))
window.model_detail_page.set_description(' ('.join(model_name.split(' (')[-1:])[:-1])
window.model_detail_create_button.set_name(model_name)
window.model_detail_create_button.set_tooltip_text(_("Create Model Based on '{}'").format(model_name))
details_flow_box = Gtk.FlowBox(
valign=1,
hexpand=True,
vexpand=False,
selection_mode=0,
max_children_per_line=2,
min_children_per_line=1,
margin_top=12,
margin_bottom=12,
margin_start=12,
margin_end=12
)
translation_strings={
'modified_at': _('Modified At'),
'parent_model': _('Parent Model'),
'format': _('Format'),
'family': _('Family'),
'parameter_size': _('Parameter Size'),
'quantization_level': _('Quantization Level')
}
if 'modified_at' in model.data and model.data['modified_at']:
details_flow_box.append(information_bow(
title=translation_strings['modified_at'],
subtitle=datetime.datetime.strptime(':'.join(model.data['modified_at'].split(':')[:2]), '%Y-%m-%dT%H:%M').strftime('%Y-%m-%d %H:%M')
))
for name, value in model.data['details'].items():
if isinstance(value, str):
details_flow_box.append(information_bow(
title=translation_strings[name] if name in translation_strings else name.replace('_', ' ').title(),
subtitle=value
))
window.model_detail_page.set_child(details_flow_box)
window.navigation_view_manage_models.push_by_tag('model_information')
class local_model_list(Gtk.ListBox): class local_model_list(Gtk.ListBox):
__gtype_name__ = 'AlpacaLocalModelList' __gtype_name__ = 'AlpacaLocalModelList'
@@ -521,7 +611,8 @@ class model_manager_container(Gtk.Box):
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
window.connection_error() window.connection_error()
window.title_stack.set_visible_child_name('model_selector') window.title_stack.set_visible_child_name('model_selector' if len(window.model_manager.get_model_list()) > 0 else 'no_models')
#window.title_stack.set_visible_child_name('model_selector')
window.chat_list_box.update_welcome_screens(len(self.get_model_list()) > 0) window.chat_list_box.update_welcome_screens(len(self.get_model_list()) > 0)
#Should only be called when the app starts #Should only be called when the app starts

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m 0 1.875 c -0.621094 0 -1.125 0.503906 -1.125 1.125 s 0.503906 1.125 1.125 1.125 s 1.125 -0.503906 1.125 -1.125 s -0.503906 -1.125 -1.125 -1.125 z m -1.523438 3.125 c -0.265624 0.011719 -0.476562 0.230469 -0.476562 0.5 c 0 0.277344 0.222656 0.5 0.5 0.5 h 0.5 v 3 h -0.5 c -0.277344 0 -0.5 0.222656 -0.5 0.5 s 0.222656 0.5 0.5 0.5 h 3 c 0.277344 0 0.5 -0.222656 0.5 -0.5 s -0.222656 -0.5 -0.5 -0.5 h -0.5 v -4 h -2.5 c -0.007812 0 -0.015625 0 -0.023438 0 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 813 B

View File

@@ -102,6 +102,9 @@ class AlpacaWindow(Adw.ApplicationWindow):
title_stack = Gtk.Template.Child() title_stack = Gtk.Template.Child()
manage_models_dialog = Gtk.Template.Child() manage_models_dialog = Gtk.Template.Child()
model_scroller = Gtk.Template.Child() model_scroller = Gtk.Template.Child()
model_detail_page = Gtk.Template.Child()
model_detail_create_button = Gtk.Template.Child()
ollama_information_label = Gtk.Template.Child()
chat_list_container = Gtk.Template.Child() chat_list_container = Gtk.Template.Child()
chat_list_box = None chat_list_box = None
@@ -332,6 +335,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
clipboard.read_text_async(None, self.cb_text_received) clipboard.read_text_async(None, self.cb_text_received)
clipboard.read_texture_async(None, self.cb_image_received) clipboard.read_texture_async(None, self.cb_image_received)
@Gtk.Template.Callback()
def model_detail_create_button_clicked(self, button):
self.create_model(button.get_name(), False)
def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag
try: try:
if mode == 0: if mode == 0:
@@ -351,20 +358,15 @@ class AlpacaWindow(Adw.ApplicationWindow):
modelfile_buffer.delete(modelfile_buffer.get_start_iter(), modelfile_buffer.get_end_iter()) modelfile_buffer.delete(modelfile_buffer.get_start_iter(), modelfile_buffer.get_end_iter())
self.create_model_system.set_text('') self.create_model_system.set_text('')
if not file: if not file:
response = self.ollama_instance.request("POST", "api/show", json.dumps({"name": self.convert_model_name(model, 1)})) data = next((element for element in list(self.model_manager.model_selector.get_popover().model_list_box) if element.get_name() == self.convert_model_name(model, 1)), None).data
if response.status_code == 200: modelfile = []
data = json.loads(response.text) for line in data['modelfile'].split('\n'):
modelfile = [] if line.startswith('SYSTEM'):
for line in data['modelfile'].split('\n'): self.create_model_system.set_text(line[len('SYSTEM'):].strip())
if line.startswith('SYSTEM'): if not line.startswith('SYSTEM') and not line.startswith('FROM') and not line.startswith('#'):
self.create_model_system.set_text(line[len('SYSTEM'):].strip()) modelfile.append(line)
if not line.startswith('SYSTEM') and not line.startswith('FROM') and not line.startswith('#'): self.create_model_name.set_text(self.convert_model_name(model, 1).split(':')[0] + "-custom")
modelfile.append(line) modelfile_buffer.insert(modelfile_buffer.get_start_iter(), '\n'.join(modelfile), len('\n'.join(modelfile).encode('utf-8')))
self.create_model_name.set_text(self.convert_model_name(model, 1).split(':')[0] + "-custom")
modelfile_buffer.insert(modelfile_buffer.get_start_iter(), '\n'.join(modelfile), len('\n'.join(modelfile).encode('utf-8')))
else:
##TODO ERROR MESSAGE
return
self.create_model_base.set_subtitle(self.convert_model_name(model, 1)) self.create_model_base.set_subtitle(self.convert_model_name(model, 1))
else: else:
self.create_model_name.set_text(os.path.splitext(os.path.basename(model))[0]) self.create_model_name.set_text(os.path.splitext(os.path.basename(model))[0])
@@ -607,6 +609,7 @@ Generate a title following these rules:
self.chat_list_box.prepend_chat(_("New Chat")) self.chat_list_box.prepend_chat(_("New Chat"))
def generate_numbered_name(self, chat_name:str, compare_list:list) -> str: def generate_numbered_name(self, chat_name:str, compare_list:list) -> str:
if chat_name in compare_list: if chat_name in compare_list:
for i in range(len(compare_list)): for i in range(len(compare_list)):
@@ -829,7 +832,7 @@ Generate a title following these rules:
[element.set_sensitive(True) for element in sensitive_elements] [element.set_sensitive(True) for element in sensitive_elements]
self.get_application().lookup_action('manage_models').set_enabled(True) self.get_application().lookup_action('manage_models').set_enabled(True)
self.title_stack.set_visible_child_name('model_selector') self.title_stack.set_visible_child_name('model_selector' if len(self.model_manager.get_model_list()) > 0 else 'no_models')
if state: if state:
options = { options = {

View File

@@ -6,7 +6,7 @@
<signal name="close-request" handler="closing_app"/> <signal name="close-request" handler="closing_app"/>
<property name="resizable">True</property> <property name="resizable">True</property>
<property name="width-request">400</property> <property name="width-request">400</property>
<property name="height-request">400</property> <property name="height-request">600</property>
<property name="default-width">1300</property> <property name="default-width">1300</property>
<property name="default-height">800</property> <property name="default-height">800</property>
<property name="title">Alpaca</property> <property name="title">Alpaca</property>
@@ -97,6 +97,18 @@
</property> </property>
</object> </object>
</child> </child>
<child>
<object class="GtkStackPage">
<property name="name">no_models</property>
<property name="child">
<object class="GtkButton">
<property name="label" translatable="yes">Manage Models</property>
<property name="tooltip-text" translatable="yes">Manage Models</property>
<property name="action-name">app.manage_models</property>
</object>
</property>
</object>
</child>
</object> </object>
</child> </child>
<child type="end"> <child type="end">
@@ -212,6 +224,7 @@
<signal name="paste-clipboard" handler="on_clipboard_paste"/> <signal name="paste-clipboard" handler="on_clipboard_paste"/>
<style> <style>
<class name="message_text_view"/> <class name="message_text_view"/>
<class name="undershoot-bottom"/>
</style> </style>
<property name="wrap-mode">word</property> <property name="wrap-mode">word</property>
<property name="top-margin">10</property> <property name="top-margin">10</property>
@@ -457,6 +470,19 @@
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="GtkLabel" id="ollama_information_label">
<property name="wrap">true</property>
<property name="label" translatable="yes">Integrated Ollama instance is not running</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
@@ -639,20 +665,48 @@
</child> </child>
<child> <child>
<object class="AdwNavigationPage"> <object class="AdwNavigationPage">
<property name="title" translatable="yes">Create Model</property> <property name="title" translatable="yes">Model Details</property>
<property name="tag">model_create_page</property> <property name="tag">model_information</property>
<property name="child"> <property name="child">
<object class="AdwToolbarView"> <object class="AdwToolbarView">
<child type="top"> <child type="top">
<object class="AdwHeaderBar"> <object class="AdwHeaderBar">
<child type="start"> <child type="start">
<object class="GtkButton"> <object class="GtkButton" id="model_detail_create_button">
<signal name="clicked" handler="link_button_handler"/> <signal name="clicked" handler="model_detail_create_button_clicked"/>
<property name="icon-name">globe-symbolic</property> <property name="icon-name">edit-copy-symbolic</property>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<property name="content">
<object class="GtkScrolledWindow">
<property name="vexpand">true</property>
<property name="hexpand">true</property>
<child>
<object class="AdwStatusPage" id="model_detail_page">
<property name="icon-name">brain-augemnted-symbolic</property>
<property name="description">text</property>
<style>
<class name="compact"/>
</style>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</child>
<child>
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Create Model</property>
<property name="tag">model_create_page</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<property name="content"> <property name="content">
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
@@ -726,6 +780,9 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="margin-start">10</property> <property name="margin-start">10</property>
<property name="margin-end">10</property> <property name="margin-end">10</property>
<style>
<class name="undershoot-bottom"/>
</style>
<child> <child>
<object class="GtkTextView" id="create_model_modelfile"> <object class="GtkTextView" id="create_model_modelfile">
<style> <style>