8 Commits
0.9.2 ... 0.9.3

Author SHA1 Message Date
jeffser
3fe9b6e121 Changed sha256 for the new ones 2024-06-01 00:29:45 -06:00
jeffser
6979d1a775 Last minute fix to width of new model creation dialog 2024-06-01 00:24:56 -06:00
jeffser
90385ce461 Preparing for 0.9.3 2024-06-01 00:16:11 -06:00
jeffser
c579e6ec99 Custom models support! 2024-06-01 00:07:34 -06:00
jeffser
b8d93cfd17 New icon (document-open-symbolic) 2024-05-31 10:29:18 -06:00
jeffser
359f28f5c1 Manually added all icons so that they work on desktops that don't use Adwaita 2024-05-31 10:17:10 -06:00
jeffser
6e8bff8493 Disabled Gnome Search (for now) 2024-05-31 09:59:04 -06:00
jeffser
ad25d5a50f Fixed: Ollama instance wasn't shutting down 2024-05-30 19:15:19 -06:00
35 changed files with 2539 additions and 1634 deletions

View File

@@ -80,16 +80,16 @@
"sources": [
{
"type": "file",
"url": "https://github.com/ollama/ollama/releases/download/v0.1.38/ollama-linux-amd64",
"sha256": "c3360812503a9756a507ebb9d78667e2b21800a760b45046bc48a8f3b81972f4",
"url": "https://github.com/ollama/ollama/releases/download/v0.1.39/ollama-linux-amd64",
"sha256": "4d19be355842a6297c93ab5ada139fe396126736bf3c3882a879dc245dffe3af",
"only-arches": [
"x86_64"
]
},
{
"type": "file",
"url": "https://github.com/ollama/ollama/releases/download/v0.1.38/ollama-linux-arm64",
"sha256": "f2d091afe665b2d5ba8b68e2473d36cdfaf80c61c7d2844a0a8f533c4e62f547",
"url": "https://github.com/ollama/ollama/releases/download/v0.1.39/ollama-linux-arm64",
"sha256": "60ec2d36928c11d6c6d84fe91451308a46aafaedbdba44664e5a6080009ce097",
"only-arches": [
"aarch64"
]

View File

@@ -63,6 +63,18 @@
<url type="homepage">https://github.com/Jeffser/Alpaca</url>
<url type="donation">https://github.com/sponsors/Jeffser</url>
<releases>
<release version="0.9.3" date="2024-06-01">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/0.9.3</url>
<description>
<p>Big Update</p>
<ul>
<li>Added: Support for GGUF models (experimental)</li>
<li>Added: Support for customization and creation of models</li>
<li>Fixed: Icons don't appear on non Gnome systems</li>
<li>Update Ollama to v0.1.39</li>
</ul>
</description>
</release>
<release version="0.9.2" date="2024-05-30">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/0.9.2</url>
<description>

View File

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

File diff suppressed because it is too large Load Diff

447
po/es.po

File diff suppressed because it is too large Load Diff

465
po/es.po~

File diff suppressed because it is too large Load Diff

438
po/fr.po

File diff suppressed because it is too large Load Diff

940
po/fr.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

View File

@@ -6,7 +6,21 @@
<file alias="icons/scalable/status/library-symbolic.svg">icons/library-symbolic.svg</file>
<file alias="icons/scalable/status/paper-plane-symbolic.svg">icons/paper-plane-symbolic.svg</file>
<file alias="icons/scalable/status/globe-symbolic.svg">icons/globe-symbolic.svg</file>
<file alias="icons/scalable/status/controls-big-symbolic.svg">icons/controls-big-symbolic.svg</file>
<file alias="icons/scalable/status/chat-message-new-symbolic.svg">icons/chat-message-new-symbolic.svg</file>
<file alias="icons/scalable/status/dialog-warning-symbolic.svg">icons/dialog-warning-symbolic.svg</file>
<file alias="icons/scalable/status/document-edit-symbolic.svg">icons/document-edit-symbolic.svg</file>
<file alias="icons/scalable/status/edit-copy-symbolic.svg">icons/edit-copy-symbolic.svg</file>
<file alias="icons/scalable/status/folder-download-symbolic.svg">icons/folder-download-symbolic.svg</file>
<file alias="icons/scalable/status/image-x-generic-symbolic.svg">icons/image-x-generic-symbolic.svg</file>
<file alias="icons/scalable/status/media-playback-stop-symbolic.svg">icons/media-playback-stop-symbolic.svg</file>
<file alias="icons/scalable/status/open-menu-symbolicsvg">icons/open-menu-symbolic.svg</file>
<file alias="icons/scalable/status/preferences-other-symbolic.svg">icons/preferences-other-symbolic.svg</file>
<file alias="icons/scalable/status/preferences-system-symbolic.svg">icons/preferences-system-symbolic.svg</file>
<file alias="icons/scalable/status/sidebar-show-symbolic.svg">icons/sidebar-show-symbolic.svg</file>
<file alias="icons/scalable/status/user-trash-symbolic.svg">icons/user-trash-symbolic.svg</file>
<file alias="icons/scalable/status/view-more-symbolic.svg">icons/view-more-symbolic.svg</file>
<file alias="icons/scalable/status/document-open-symbolic.svg">icons/document-open-symbolic.svg</file>
<file alias="icons/scalable/status/list-add-symbolic.svg">icons/list-add-symbolic.svg</file>
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
</gresource>

View File

@@ -16,9 +16,15 @@ class SearchProvider:
return
print("ALPACA D-Bus connection obtained")
interface_info = self.get_interface_info()
self.registration_id = self.connection.register_object(DBUS_OBJECT_PATH, interface_info, self.handle_method_call, None)
self.registration_id = self.connection.register_object(
DBUS_OBJECT_PATH,
interface_info,
self.handle_method_call,
None,
None
)
if self.registration_id > 0:
print(f"ALPACA Object registered with ID: {self.registration_id}")
@@ -28,28 +34,38 @@ class SearchProvider:
def get_interface_info(self):
print("ALPACA get_interface_info")
xml = """
<node>
<interface name='org.gnome.Shell.SearchProvider2'>
<method name='GetInitialResultSet'>
<arg type='as' name='terms' direction='in'/>
<arg type='as' name='results' direction='out'/>
</method>
<method name='GetSubsearchResultSet'>
<arg type='as' name='previous_results' direction='in'/>
<arg type='as' name='terms' direction='in'/>
<arg type='as' name='results' direction='out'/>
</method>
<method name='GetResultMetas'>
<arg type='as' name='identifiers' direction='in'/>
<arg type='a{sv}' name='metas' direction='out'/>
</method>
<method name='ActivateResult'>
<arg type='s' name='identifier' direction='in'/>
<arg type='as' name='terms' direction='in'/>
<arg type='i' name='timestamp' direction='in'/>
</method>
</interface>
</node>
<node>
<interface name="org.gnome.Shell.SearchProvider2">
<method name="GetInitialResultSet">
<arg type="as" name="terms" direction="in" />
<arg type="as" name="results" direction="out" />
</method>
<method name="GetSubsearchResultSet">
<arg type="as" name="previous_results" direction="in" />
<arg type="as" name="terms" direction="in" />
<arg type="as" name="results" direction="out" />
</method>
<method name="GetResultMetas">
<arg type="as" name="identifiers" direction="in" />
<arg type="aa{sv}" name="metas" direction="out" />
</method>
<method name="ActivateResult">
<arg type="s" name="identifier" direction="in" />
<arg type="as" name="terms" direction="in" />
<arg type="u" name="timestamp" direction="in" />
</method>
<method name="LaunchSearch">
<arg type="as" name="terms" direction="in" />
<arg type="u" name="timestamp" direction="in" />
</method>
</interface>
</node>
"""
return Gio.DBusNodeInfo.new_for_xml(xml).interfaces[0]

View File

@@ -13,6 +13,19 @@ def simple_get(connection_url:str) -> dict:
except Exception as e:
return {"status": "error", "status_code": 0}
def simple_post(connection_url:str, data) -> dict:
try:
headers = {
"Content-Type": "application/json"
}
response = requests.post(connection_url, headers=headers, data=data, stream=False)
if response.status_code == 200:
return {"status": "ok", "text": response.text, "status_code": response.status_code}
else:
return {"status": "error", "status_code": response.status_code}
except Exception as e:
return {"status": "error", "status_code": 0}
def simple_delete(connection_url:str, data) -> dict:
try:
response = requests.delete(connection_url, json=data)
@@ -38,4 +51,3 @@ def stream_post(connection_url:str, data, callback:callable) -> dict:
return {"status": "error", "status_code": response.status_code}
except Exception as e:
return {"status": "error", "status_code": 0}

View File

@@ -196,7 +196,7 @@ def remove_image(self):
callback = lambda dialog, task: remove_image_response(self, dialog, task)
)
# RECONNECT REMOTE |
# RECONNECT REMOTE | WORKS
def reconnect_remote_response(self, dialog, task, entry):
response = dialog.choose_finish(task)
@@ -227,3 +227,43 @@ def reconnect_remote(self, current_url):
cancellable = None,
callback = lambda dialog, task, entry=entry: reconnect_remote_response(self, dialog, task, entry)
)
# CREATE MODEL |
def create_model_from_existing_response(self, dialog, task, dropdown):
model = dropdown.get_selected_item().get_string()
if dialog.choose_finish(task) == 'accept' and model:
self.create_model(model, False)
def create_model_from_existing(self):
string_list = Gtk.StringList()
for model in self.local_models:
string_list.append(model)
dropdown = Gtk.DropDown()
dropdown.set_model(string_list)
dialog = Adw.AlertDialog(
heading=_("Select Model"),
body=_("This model will be used as the base for the new model"),
extra_child=dropdown
)
dialog.add_response("cancel", _("Cancel"))
dialog.add_response("accept", _("Accept"))
dialog.set_response_appearance("accept", Adw.ResponseAppearance.SUGGESTED)
dialog.choose(
parent = self,
cancellable = None,
callback = lambda dialog, task, dropdown=dropdown: create_model_from_existing_response(self, dialog, task, dropdown)
)
def create_model_from_file_response(self, file_dialog, result):
try: file = file_dialog.open_finish(result)
except: return
try:
self.create_model(file.get_path(), True)
except Exception as e:
self.show_toast("error", 5, self.main_overlay) ##TODO NEW ERROR MESSAGE
def create_model_from_file(self):
file_dialog = Gtk.FileDialog(default_filter=self.file_filter_gguf)
file_dialog.open(self, None, lambda file_dialog, result: create_model_from_file_response(self, file_dialog, result))

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 6 c 0 1.644531 1.355469 3 3 3 h 1 v 3 l 3 -3 v -1 c 0 -0.550781 -0.449219 -1 -1 -1 h -3 c -0.570312 0 -1 -0.429688 -1 -1 v -6 c 0 -0.554688 0.445312 -1 1 -1 h 10 c 0.554688 0 1 0.445312 1 1 v 4 c 0 0.550781 0.449219 1 1 1 s 1 -0.449219 1 -1 v -4 c 0 -1.644531 -1.355469 -3 -3 -3 z m 8 7 v 3 h -3 v 2 h 3 v 3 h 2 v -3 h 3 v -2 h -3 v -3 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><g fill="#222222"><path d="m 4.550781 1 c -1.9375 0 -3.5 1.5625 -3.5 3.5 s 1.5625 3.5 3.5 3.5 h 7 c 1.941407 0 3.5 -1.5625 3.5 -3.5 s -1.558593 -3.5 -3.5 -3.5 z m 7 1 c 1.386719 0 2.5 1.113281 2.5 2.5 c 0 1.382812 -1.113281 2.5 -2.5 2.5 c -1.382812 0 -2.5 -1.117188 -2.5 -2.5 c 0 -1.386719 1.117188 -2.5 2.5 -2.5 z m 0 0"/><path d="m 4.550781 9 c -1.9375 0 -3.5 1.5625 -3.5 3.5 s 1.5625 3.5 3.5 3.5 h 7 c 1.941407 0 3.5 -1.5625 3.5 -3.5 s -1.558593 -3.5 -3.5 -3.5 z m 0 1 c 1.386719 0 2.5 1.113281 2.5 2.5 c 0 1.382812 -1.113281 2.5 -2.5 2.5 c -1.382812 0 -2.5 -1.117188 -2.5 -2.5 c 0 -1.386719 1.117188 -2.5 2.5 -2.5 z m 0 0" fill-opacity="0.35"/></g></svg>

Before

Width:  |  Height:  |  Size: 785 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 7.90625 0.09375 c -0.527344 -0.0273438 -1.039062 0.28125 -1.4375 0.96875 l -6.25 11.59375 c -0.535156 0.964844 0.046875 2.34375 1.09375 2.34375 h 13.15625 c 0.980469 0 1.902344 -1.160156 1.21875 -2.34375 l -6.3125 -11.53125 c -0.398438 -0.644531 -0.941406 -1.003906 -1.46875 -1.03125 z m 1.09375 3.90625 v 5 c 0.007812 0.527344 -0.472656 1 -1 1 s -1.007812 -0.472656 -1 -1 v -5 z m -1 7 c 0.550781 0 1 0.449219 1 1 s -0.449219 1 -1 1 s -1 -0.449219 -1 -1 s 0.449219 -1 1 -1 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 12.277344 0.832031 c -0.578125 0.007813 -1.167969 0.230469 -1.691406 0.753907 l -9 9 c -0.375 0.375 -0.585938 0.882812 -0.585938 1.414062 v 3 h 3 c 0.53125 0 1.039062 -0.210938 1.414062 -0.585938 l 9 -9 c 1.789063 -1.789062 0.082032 -4.390624 -1.890624 -4.570312 c -0.082032 -0.011719 -0.164063 -0.011719 -0.246094 -0.011719 z m -1.777344 3.605469 l 1.0625 1.0625 l -7.0625 7.0625 l -1.0625 -1.0625 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#2e3436">
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 0 3 c 0 -1.644531 1.355469 -3 3 -3 h 5 c 1.644531 0 3 1.355469 3 3 c 0 0.550781 -0.449219 1 -1 1 s -1 -0.449219 -1 -1 c 0 -0.570312 -0.429688 -1 -1 -1 h -5 c -0.570312 0 -1 0.429688 -1 1 v 5 c 0 0.570312 0.429688 1 1 1 c 0.550781 0 1 0.449219 1 1 s -0.449219 1 -1 1 c -1.644531 0 -3 -1.355469 -3 -3 z m 5 5 c 0 -1.644531 1.355469 -3 3 -3 h 5 c 1.644531 0 3 1.355469 3 3 v 5 c 0 1.644531 -1.355469 3 -3 3 h -5 c -1.644531 0 -3 -1.355469 -3 -3 z m 2 0 v 5 c 0 0.570312 0.429688 1 1 1 h 5 c 0.570312 0 1 -0.429688 1 -1 v -5 c 0 -0.570312 -0.429688 -1 -1 -1 h -5 c -0.570312 0 -1 0.429688 -1 1 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 765 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 8 0 c -0.550781 0 -1 0.449219 -1 1 v 8.585938 l -2.292969 -2.292969 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 s -0.519531 0.105469 -0.707031 0.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 l 4 4 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 l 4 -4 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 s -1.023437 -0.390625 -1.414062 0 l -2.292969 2.292969 v -8.585938 c 0 -0.550781 -0.449219 -1 -1 -1 z m -6 14 v 2 h 12 v -2 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 630 B

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#2e3436">
<path d="m 6 5 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 s 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 3.5 3 l -2 2 l -1.5 -1 l -2 2 v 0.5 c 0 0.5 0.5 0.5 0.5 0.5 h 7 s 0.472656 -0.035156 0.5 -0.5 v -1 z m 0 0"/>
<path d="m 4 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8 c 1.644531 0 3 -1.355469 3 -3 v -8 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 2 h 8 c 0.570312 0 1 0.429688 1 1 v 8 c 0 0.570312 -0.429688 1 -1 1 h -8 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.429688 -1 1 -1 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 708 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 7 1 v 6 h -6 v 2 h 6 v 6 h 2 v -6 h 6 v -2 h -6 v -6 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 3.5 2 h 9 c 0.828125 0 1.5 0.671875 1.5 1.5 v 9 c 0 0.828125 -0.671875 1.5 -1.5 1.5 h -9 c -0.828125 0 -1.5 -0.671875 -1.5 -1.5 v -9 c 0 -0.828125 0.671875 -1.5 1.5 -1.5 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 345 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#2e3436">
<path d="m 1 2 h 14 v 2 h -14 z m 0 0"/>
<path d="m 1 7 h 14 v 2 h -14 z m 0 0"/>
<path d="m 1 12 h 14 v 2 h -14 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 314 B

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 12.5 0.0234375 c -0.292969 -0.0039063 -0.59375 0.0195313 -0.882812 0.0937505 c -1.867188 0.488281 -2.984376 2.382812 -2.496094 4.234374 c 0.101562 0.386719 0.289062 0.742188 0.5 1.054688 c -0.109375 0.015625 -1.625 2.59375 -1.625 2.59375 l 3.410156 0.023438 l 0.800781 -1.117188 c 0.378907 0.03125 0.78125 0.023438 1.171875 -0.078125 c 1.863282 -0.484375 2.980469 -2.382813 2.496094 -4.234375 c -0.105469 -0.386719 -0.292969 -0.738281 -0.503906 -1.054688 l -1.359375 2.304688 c -0.28125 0.476562 -0.882813 0.632812 -1.355469 0.355469 l -0.875 -0.507813 c -0.476562 -0.277344 -0.636719 -0.875 -0.355469 -1.347656 l 1.363281 -2.3085938 c -0.097656 -0.0039062 -0.195312 -0.0117187 -0.289062 -0.0117187 z m -8.875 0.6914065 c -0.011719 0 -0.019531 0 -0.027344 0.003906 c -0.230468 0.046875 -0.445312 0.132812 -0.65625 0.21875 c -0.019531 0.625 0.085938 1.441406 -0.15625 1.65625 c -0.242187 0.210938 -1.039062 0.035156 -1.652344 -0.03125 c -0.132812 0.238281 -0.238281 0.484375 -0.3125 0.75 c 0.476563 0.394531 1.136719 0.839844 1.152344 1.15625 c 0.015625 0.320312 -0.625 0.804688 -1.058594 1.25 c 0.101563 0.257812 0.25 0.492188 0.40625 0.71875 c 0.605469 -0.125 1.359376 -0.375 1.621094 -0.1875 c 0.261719 0.1875 0.261719 1.003906 0.34375 1.625 c 0.246094 0.074219 0.507813 0.105469 0.777344 0.125 c 0.28125 -0.554688 0.566406 -1.320312 0.875 -1.40625 c 0.316406 -0.089844 0.960938 0.457031 1.5 0.78125 c 0.214844 -0.152344 0.410156 -0.335938 0.589844 -0.53125 c -0.253906 -0.574219 -0.71875 -1.292969 -0.589844 -1.59375 c 0.125 -0.300781 0.96875 -0.46875 1.558594 -0.6875 c 0.003906 -0.074219 0.03125 -0.144531 0.03125 -0.21875 c 0 -0.191406 -0.035156 -0.378906 -0.0625 -0.5625 c -0.605469 -0.160156 -1.464844 -0.242188 -1.621094 -0.53125 c -0.160156 -0.289062 0.238281 -1.0625 0.433594 -1.65625 c -0.199219 -0.179688 -0.417969 -0.335938 -0.652344 -0.46875 c -0.503906 0.375 -1.085938 0.996094 -1.40625 0.9375 c -0.316406 -0.054688 -0.660156 -0.820312 -0.996094 -1.34375 c -0.03125 0.003906 -0.066406 0 -0.097656 -0.003906 z m 0.59375 1.878906 c 0.929688 0 1.6875 0.753906 1.6875 1.6875 s -0.757812 1.6875 -1.6875 1.6875 s -1.683594 -0.753906 -1.683594 -1.6875 s 0.753906 -1.6875 1.683594 -1.6875 z m 8.621094 6.332031 c -0.144532 0 -0.273438 0.023438 -0.359375 0.074219 h -9.050781 c -0.246094 -0.105469 -0.746094 -0.046875 -0.964844 0.179688 l -2.160156 2.113281 c -0.191407 0.175781 -0.30078175 0.484375 -0.304688 0.707031 c -0.0546875 0.886719 1 1.320312 1.636719 0.792969 l 1.363281 -1.332031 l 0.003906 3.539062 c 0 0.570312 0.457032 1 0.996094 1 h 7.992188 c 0.523437 0 0.996093 -0.445312 0.996093 -0.9375 l -0.003906 -3.601562 l 1.335937 1.308593 c 0.636719 0.527344 1.6875 0.09375 1.636719 -0.792969 c -0.003906 -0.222656 -0.113281 -0.53125 -0.300781 -0.703124 l -2.164062 -2.117188 c -0.144532 -0.152344 -0.417969 -0.226562 -0.652344 -0.230469 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#2e3436">
<path d="m 6.5 14 v -12 h -5 v 12 z m 0 0" fill-opacity="0.34902"/>
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -8 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 2 h 10 c 0.570312 0 1 0.429688 1 1 v 8 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.429688 -1 1 -1 z m 0 0"/>
<path d="m 6 2 h 1 v 12 h -1 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 610 B

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#2e3436">
<path d="m 1 3 h 14 c 0.550781 0 1 0.449219 1 1 s -0.449219 1 -1 1 h -14 c -0.550781 0 -1 -0.449219 -1 -1 s 0.449219 -1 1 -1 z m 0 0"/>
<path d="m 4 4 v -1.5 c 0 -1.386719 1.113281 -2.5 2.5 -2.5 h 2.980469 c 1.382812 0 2.5 1.113281 2.5 2.5 v 1.5 h -2 v -1.5 c 0 -0.269531 -0.230469 -0.5 -0.5 -0.5 h -2.980469 c -0.269531 0 -0.5 0.230469 -0.5 0.5 v 1.5 z m 0 0"/>
<path d="m 4 4 v 9 c 0 0.546875 0.453125 1 1 1 h 6 c 0.546875 0 1 -0.453125 1 -1 v -9 h 2 v 9 c 0 1.660156 -1.339844 3 -3 3 h -6 c -1.660156 0 -3 -1.339844 -3 -3 v -9 z m 0 0"/>
<path d="m 7 7 v 5 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s -0.5 -0.222656 -0.5 -0.5 v -5 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 s 0.5 0.222656 0.5 0.5 z m 0 0"/>
<path d="m 10 7 v 5 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s -0.5 -0.222656 -0.5 -0.5 v -5 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 s 0.5 0.222656 0.5 0.5 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 7.996094 0 c -1.105469 0 -2 0.894531 -2 2 s 0.894531 2 2 2 c 1.101562 0 2 -0.894531 2 -2 s -0.898438 -2 -2 -2 z m 0 6 c -1.105469 0 -2 0.894531 -2 2 s 0.894531 2 2 2 c 1.101562 0 2 -0.894531 2 -2 s -0.898438 -2 -2 -2 z m 0 6 c -1.105469 0 -2 0.894531 -2 2 s 0.894531 2 2 2 c 1.101562 0 2 -0.894531 2 -2 s -0.898438 -2 -2 -2 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 499 B

View File

@@ -7,14 +7,19 @@ port = 11435
data_dir = os.getenv("XDG_DATA_HOME")
def start():
global instance
instance = subprocess.Popen(["/app/bin/ollama", "serve"], env={**os.environ, 'OLLAMA_HOST': f"127.0.0.1:{port}", "HOME": data_dir}, stderr=subprocess.PIPE, text=True)
print("Starting Alpaca's Ollama instance...")
sleep(1)
print("Started Alpaca's Ollama instance")
def stop():
if instance: instance.kill()
print("Stopped Alpaca's Ollama instance")
global instance
if instance:
instance.kill()
instance.wait()
instance = None
print("Stopped Alpaca's Ollama instance")
def reset():
stop()

View File

@@ -47,7 +47,7 @@ class AlpacaApplication(Adw.Application):
application_name='Alpaca',
application_icon='com.jeffser.Alpaca',
developer_name='Jeffry Samuel Eduarte Rojas',
version='0.9.2',
version='0.9.3',
developers=['Jeffser https://jeffser.com'],
designers=['Jeffser https://jeffser.com'],
translator_credits='Alex K (Russian) https://github.com/alexkdeveloper\nJeffser (Spanish) https://jeffser.com\nDaimar Stein (Brazilian Portuguese) https://github.com/not-a-dev-stein\nLouis Chauvet-Villaret (French) https://github.com/loulou64490',

View File

@@ -26,14 +26,14 @@ configure_file(
install_mode: 'r-xr-xr-x'
)
configure_file(
input: 'alpaca_search_provider.in',
output: 'alpaca_search_provider',
configuration: conf,
install: true,
install_dir: get_option('bindir'),
install_mode: 'r-xr-xr-x'
)
#configure_file(
#input: 'alpaca_search_provider.in',
#output: 'alpaca_search_provider',
#configuration: conf,
#install: true,
#install_dir: get_option('bindir'),
#install_mode: 'r-xr-xr-x'
#)
alpaca_sources = [
'__init__.py',

View File

@@ -33,6 +33,7 @@ from . import dialogs, local_instance, connection_handler
class AlpacaWindow(Adw.ApplicationWindow):
config_dir = os.getenv("XDG_CONFIG_HOME")
app_dir = os.getenv("FLATPAK_DEST")
cache_dir = os.getenv("XDG_CACHE_HOME")
__gtype_name__ = 'AlpacaWindow'
@@ -54,6 +55,11 @@ class AlpacaWindow(Adw.ApplicationWindow):
attached_image = {"path": None, "base64": None}
#Elements
create_model_base = Gtk.Template.Child()
create_model_name = Gtk.Template.Child()
create_model_system = Gtk.Template.Child()
create_model_template = Gtk.Template.Child()
create_model_dialog = Gtk.Template.Child()
temperature_spin = Gtk.Template.Child()
seed_spin = Gtk.Template.Child()
keep_alive_spin = Gtk.Template.Child()
@@ -76,6 +82,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
image_button = Gtk.Template.Child()
file_filter_image = Gtk.Template.Child()
file_filter_json = Gtk.Template.Child()
file_filter_gguf = Gtk.Template.Child()
model_drop_down = Gtk.Template.Child()
model_string_list = Gtk.Template.Child()
@@ -163,9 +170,12 @@ class AlpacaWindow(Adw.ApplicationWindow):
"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)
})
messages_to_send = []
for message in self.chats["chats"][self.chats["selected_chat"]]["messages"]:
if message: messages_to_send.append(message)
data = {
"model": current_model.get_string(),
"messages": self.chats["chats"][self.chats["selected_chat"]]["messages"],
"messages": messages_to_send,
"options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]},
"keep_alive": f"{self.model_tweaks['keep_alive']}m"
}
@@ -263,9 +273,80 @@ class AlpacaWindow(Adw.ApplicationWindow):
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
print(self.model_tweaks)
self.save_server_config()
@Gtk.Template.Callback()
def create_model_start(self, button):
base = self.create_model_base.get_subtitle()
name = self.create_model_name.get_text()
system = self.create_model_system.get_text()
template = self.create_model_template.get_text()
if "/" in base:
modelfile = f"FROM {base}\nSYSTEM {system}\nTEMPLATE {template}"
else:
modelfile = f"FROM {base}\nSYSTEM {system}"
self.pulling_model_list_box.set_visible(True)
model_row = Adw.ActionRow(
title = name
)
thread = threading.Thread(target=self.pull_model_process, kwargs={"model": name, "modelfile": modelfile})
overlay = Gtk.Overlay()
progress_bar = Gtk.ProgressBar(
valign = 2,
show_text = False,
margin_start = 10,
margin_end = 10,
css_classes = ["osd", "horizontal", "bottom"]
)
button = Gtk.Button(
icon_name = "media-playback-stop-symbolic",
vexpand = False,
valign = 3,
css_classes = ["error"]
)
button.connect("clicked", lambda button, model_name=name : dialogs.stop_pull_model(self, model_name))
model_row.add_suffix(button)
self.pulling_models[name] = {"row": model_row, "progress_bar": progress_bar, "overlay": overlay}
overlay.set_child(model_row)
overlay.add_overlay(progress_bar)
self.pulling_model_list_box.append(overlay)
self.create_model_dialog.close()
self.manage_models_dialog.present(self)
thread.start()
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")
def create_model(self, model:str, file:bool):
name = ""
system = ""
template = ""
if not file:
response = connection_handler.simple_post(f"{connection_handler.url}/api/show", json.dumps({"name": model}))
if 'text' in response:
data = json.loads(response['text'])
for line in data['modelfile'].split('\n'):
if line.startswith('SYSTEM'):
system = line[len('SYSTEM'):].strip()
elif line.startswith('TEMPLATE'):
template = line[len('TEMPLATE'):].strip()
self.create_model_template.set_sensitive(False)
name = model.split(':')[0]
else:
self.create_model_template.set_sensitive(True)
template = '"""{{ if .System }}<|start_header_id|>system<|end_header_id|>\n\n{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>\n\n{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>\n{{ .Response }}<|eot_id|>"""'
name = model.split("/")[-1].split(".")[0]
self.create_model_base.set_subtitle(model)
self.create_model_name.set_text(name)
self.create_model_system.set_text(system)
self.create_model_template.set_text(template)
self.manage_models_dialog.close()
self.create_model_dialog.present(self)
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"
@@ -292,7 +373,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
def copy_message(self, message_element):
message_index = int(message_element.get_name())
print(message_index)
clipboard = Gdk.Display().get_default().get_clipboard()
clipboard.set(self.chats["chats"][self.chats["selected_chat"]]["messages"][message_index]["content"])
self.show_toast("info", 5, self.main_overlay)
@@ -376,7 +456,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
def update_list_local_models(self):
self.local_models = []
response = connection_handler.simple_get(connection_handler.url + "/api/tags")
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)
if response['status'] == 'ok':
@@ -575,9 +655,11 @@ class AlpacaWindow(Adw.ApplicationWindow):
if self.verify_if_image_can_be_used(): GLib.idle_add(self.image_button.set_sensitive, True)
GLib.idle_add(self.image_button.set_css_classes, ["circular"])
self.attached_image = {"path": None, "base64": None}
if self.loading_spinner:
GLib.idle_add(self.chat_container.remove, self.loading_spinner)
self.loading_spinner = None
if response['status'] == 'error':
GLib.idle_add(self.connection_error)
print(response)
def pull_model_update(self, data, model_name):
if model_name in list(self.pulling_models.keys()):
@@ -588,9 +670,14 @@ class AlpacaWindow(Adw.ApplicationWindow):
if len(list(self.pulling_models.keys())) == 0:
GLib.idle_add(self.pulling_model_list_box.set_visible, False)
def pull_model_process(self, model):
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))
def pull_model_process(self, model, modelfile):
response = {}
if modelfile:
data = {"name": model, "modelfile": modelfile}
response = connection_handler.stream_post(f"{connection_handler.url}/api/create", data=json.dumps(data), callback=lambda data, model_name=model: self.pull_model_update(data, model_name))
else:
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)
if response['status'] == 'ok':
@@ -618,7 +705,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
model_row = Adw.ActionRow(
title = model
)
thread = threading.Thread(target=self.pull_model_process, kwargs={"model": model})
thread = threading.Thread(target=self.pull_model_process, kwargs={"model": model, "modelfile": None})
overlay = Gtk.Overlay()
progress_bar = Gtk.ProgressBar(
valign = 2,
@@ -634,7 +721,6 @@ class AlpacaWindow(Adw.ApplicationWindow):
css_classes = ["error"]
)
button.connect("clicked", lambda button, model_name=model : dialogs.stop_pull_model(self, model_name))
#model_row.add_suffix(progress_bar)
model_row.add_suffix(button)
self.pulling_models[model] = {"row": model_row, "progress_bar": progress_bar, "overlay": overlay}
overlay.set_child(model_row)
@@ -763,7 +849,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
del self.pulling_models[model_name]
def delete_model(self, model_name):
response = connection_handler.simple_delete(connection_handler.url + "/api/delete", data={"name": model_name})
response = connection_handler.simple_delete(f"{connection_handler.url}/api/delete", data={"name": model_name})
self.update_list_local_models()
if response['status'] == 'ok':
self.show_toast("good", 0, self.manage_models_overlay)
@@ -906,8 +992,11 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.get_application().create_action('send', lambda *_: self.send_message(self), ['Return'])
self.get_application().create_action('export_current_chat', lambda *_: self.export_current_chat())
self.get_application().create_action('import_chat', lambda *_: self.import_chat())
self.get_application().create_action('create_model_from_existing', lambda *_: dialogs.create_model_from_existing(self))
self.get_application().create_action('create_model_from_file', lambda *_: dialogs.create_model_from_file(self))
self.add_chat_button.connect("clicked", lambda button : self.new_chat())
self.create_model_name.get_delegate().connect("insert-text", self.check_alphanumeric)
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())

View File

@@ -24,6 +24,7 @@
<setter object="split_view_overlay" property="collapsed">true</setter>
<setter object="welcome_dialog" property="width-request">360</setter>
<setter object="manage_models_dialog" property="width-request">360</setter>
<setter object="create_model_dialog" property="width-request">360</setter>
<setter object="preferences_dialog" property="width-request">360</setter>
</object>
</child>
@@ -47,7 +48,7 @@
<object class="GtkMenuButton" id="chats_menu_button">
<property name="direction">1</property>
<property name="halign">3</property>
<property name="menu-model">chats_button_menu</property>
<property name="menu-model">chats_menu</property>
<property name="icon-name">view-more-symbolic</property>
</object>
</child>
@@ -359,6 +360,127 @@
</child>
</object>
<object class="AdwDialog" id="create_model_dialog">
<property name="can-close">true</property>
<property name="width-request">400</property>
<property name="height-request">600</property>
<child>
<object class="AdwToastOverlay" id="create_model_overlay">
<child>
<object class="AdwToolbarView">
<child type="bottom">
<object class="GtkActionBar">
<property name="revealed">true</property>
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">Create</property>
<signal name="clicked" handler="create_model_start"/>
<style>
<class name="suggested-action" />
</style>
</object>
</child>
</object>
</child>
<child type="top">
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title" translatable="yes">Create model</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">true</property>
<property name="hexpand">true</property>
<child>
<object class="GtkBox">
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="orientation">1</property>
<property name="spacing">12</property>
<child>
<object class="GtkListBox">
<style>
<class name="boxed-list"/>
<class name="card"/>
</style>
<property name="selection-mode">none</property>
<child>
<object class="AdwActionRow" id="create_model_base">
<property name="title" translatable="yes">Base</property>
<property name="subtitle"></property>
<style>
<class name="property"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox">
<style>
<class name="boxed-list"/>
<class name="card"/>
</style>
<property name="selection-mode">none</property>
<child>
<object class="AdwEntryRow" id="create_model_name">
<property name="title" translatable="yes">Name</property>
<property name="input-purpose">alpha</property>
</object>
</child>
<child>
<object class="AdwEntryRow" id="create_model_system">
<property name="title" translatable="yes">Context</property>
<property name="input-purpose">alpha</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox">
<style>
<class name="boxed-list"/>
<class name="card"/>
</style>
<property name="selection-mode">none</property>
<child>
<object class="AdwEntryRow" id="create_model_template">
<property name="title" translatable="yes">Template</property>
<property name="input-purpose">alpha</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Some models require a specific template. Please visit the model's website for more information if you're unsure.</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="halign">1</property>
<property name="wrap">true</property>
<style>
<class name="caption"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="AdwDialog" id="manage_models_dialog">
<property name="can-close">true</property>
<property name="width-request">400</property>
@@ -369,6 +491,14 @@
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<child type="start">
<object class="GtkMenuButton">
<property name="primary">True</property>
<property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text" translatable="yes">Create model</property>
<property name="menu-model">create_model_menu</property>
</object>
</child>
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title" translatable="yes">Manage models</property>
@@ -622,7 +752,7 @@
</item>
</section>
</menu>
<menu id="chats_button_menu">
<menu id="chats_menu">
<section>
<item>
<attribute name="label" translatable="yes">Export current chat</attribute>
@@ -634,6 +764,18 @@
</item>
</section>
</menu>
<menu id="create_model_menu">
<section>
<item>
<attribute name="label" translatable="yes">From existing model</attribute>
<attribute name="action">app.create_model_from_existing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">From GGUF file (Testing)</attribute>
<attribute name="action">app.create_model_from_file</attribute>
</item>
</section>
</menu>
<object class="GtkFileFilter" id="file_filter_image">
<mime-types>
<mime-type>image/svg+xml</mime-type>
@@ -648,6 +790,11 @@
<mime-type>application/json</mime-type>
</mime-types>
</object>
<object class="GtkFileFilter" id="file_filter_gguf">
<suffixes>
<suffix>gguf</suffix>
</suffixes>
</object>
<object class="GtkShortcutsWindow" id="shortcut_window">
<property name="modal">1</property>
<child>