16 Commits
1.0.4 ... 1.0.5

Author SHA1 Message Date
jeffser
8c0ec3957f Preparing for 1.0.5 2024-08-02 23:56:17 -06:00
jeffser
72063a15d9 Better check for message finishing 2024-08-02 23:48:03 -06:00
jeffser
0d1b15aafc New feature: Regenerate response 2024-08-02 23:42:35 -06:00
jeffser
ca10369bdc Added message to support dialog 2024-08-02 21:44:19 -06:00
jeffser
42af75d8d2 typo 2024-08-02 20:53:19 -06:00
jeffser
a02871dd28 'S fixed again :3 2024-08-02 20:50:04 -06:00
jeffser
e65a8bc648 Proper GGUF / name Model pulling 2024-08-02 20:47:04 -06:00
jeffser
b373b6a34f Sidebar button 2024-08-02 16:44:24 -06:00
jeffser
6d6a0255e2 Better model name handling internally 2024-08-02 16:00:47 -06:00
jeffser
003d6a3d5f Restore last model used 2024-08-02 15:30:03 -06:00
jeffser
77a2c60fe5 Fixed message entry shadow 2024-08-02 15:19:28 -06:00
jeffser
ac3bd699ee Changed width request for model dropdown 2024-08-02 14:51:08 -06:00
jeffser
596498c81e Fixed 'S problem with title generation 2024-08-02 14:42:11 -06:00
jeffser
c95f764c77 Merge branch 'main' of github.com-jeffser:Jeffser/Alpaca 2024-08-02 14:39:26 -06:00
jeffser
5c5be05843 Reverted back to standard styles 2024-08-02 14:39:19 -06:00
aritra saha
3fb26ec49e updated translation (#180)
* Update bn.po

* Update bn.po

* Update bn.po

* Update bn.po

* Update zh_CN.po
2024-08-02 11:19:23 -06:00
10 changed files with 420 additions and 284 deletions

View File

@@ -80,6 +80,27 @@
<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="1.0.5" date="2024-08-02">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/1.0.5</url>
<description>
<p>New</p>
<ul>
<li>Regenerate any response, even if they are incomplete</li>
<li>Support for pulling models by name:tag</li>
<li>Stable support for GGUF model files</li>
<li>Restored sidebar toggle button</li>
</ul>
<p>Fixes</p>
<ul>
<li>Reverted back to standard styles</li>
<li>Fixed generated titles having "'S" for some reason</li>
<li>Changed min width for model dropdown</li>
<li>Changed message entry shadow</li>
<li>The last model used is now restored when the user changes chat</li>
<li>Better check for message finishing</li>
</ul>
</description>
</release>
<release version="1.0.4" date="2024-08-01"> <release version="1.0.4" date="2024-08-01">
<url type="details">https://github.com/Jeffser/Alpaca/releases/tag/1.0.4</url> <url type="details">https://github.com/Jeffser/Alpaca/releases/tag/1.0.4</url>
<description> <description>

View File

@@ -1,5 +1,5 @@
project('Alpaca', 'c', project('Alpaca', 'c',
version: '1.0.4', version: '1.0.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', ],
) )

159
po/bn.po
View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 1.0.0\n" "Project-Id-Version: 1.0.4\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 14:36-0600\n" "POT-Creation-Date: 2024-08-01 14:36-0600\n"
"PO-Revision-Date: 2024-07-18 15:12-0600\n" "PO-Revision-Date: 2024-07-18 15:12-0600\n"
@@ -67,15 +67,15 @@ msgstr "আমদানি এবং রপ্তানি চ্যাট"
#: data/com.jeffser.Alpaca.metainfo.xml.in:20 #: data/com.jeffser.Alpaca.metainfo.xml.in:20
msgid "Append YouTube transcripts to the prompt" msgid "Append YouTube transcripts to the prompt"
msgstr "" msgstr "প্রোম্পটে ইউটিউব ট্রান্সক্রিপ্ট যোগ করুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:21 #: data/com.jeffser.Alpaca.metainfo.xml.in:21
msgid "Append text from a website to the prompt" msgid "Append text from a website to the prompt"
msgstr "" msgstr "ওয়েবসাইট থেকে টেক্সট প্রোম্পটে যোগ করুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:22 #: data/com.jeffser.Alpaca.metainfo.xml.in:22
msgid "PDF recognition" msgid "PDF recognition"
msgstr "" msgstr "পিডিএফ স্বীকৃতি"
#: data/com.jeffser.Alpaca.metainfo.xml.in:24 src/window.ui:883 #: data/com.jeffser.Alpaca.metainfo.xml.in:24 src/window.ui:883
msgid "Disclaimer" msgid "Disclaimer"
@@ -96,304 +96,310 @@ msgstr "জেফরি স্যামুয়েল এডুয়ার্
#: data/com.jeffser.Alpaca.metainfo.xml.in:54 #: data/com.jeffser.Alpaca.metainfo.xml.in:54
msgid "A normal conversation with an AI Model" msgid "A normal conversation with an AI Model"
msgstr "" msgstr "এআই মডেলের সাথে একটি সাধারণ কথোপকথন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:58 #: data/com.jeffser.Alpaca.metainfo.xml.in:58
msgid "A conversation involving image recognition" msgid "A conversation involving image recognition"
msgstr "" msgstr "চিত্র স্বীকৃতি জড়িত একটি কথোপকথন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:62 #: data/com.jeffser.Alpaca.metainfo.xml.in:62
msgid "A conversation showing code highlighting" msgid "A conversation showing code highlighting"
msgstr "" msgstr "কোড হাইলাইটিং দেখানো একটি কথোপকথন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:66 #: data/com.jeffser.Alpaca.metainfo.xml.in:66
msgid "A conversation involving a YouTube video transcript" msgid "A conversation involving a YouTube video transcript"
msgstr "" msgstr "ইউটিউব ভিডিও ট্রান্সক্রিপ্ট জড়িত একটি কথোপকথন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:70 #: data/com.jeffser.Alpaca.metainfo.xml.in:70
msgid "Multiple models being downloaded" msgid "Multiple models being downloaded"
msgstr "" msgstr "একাধিক মডেল ডাউনলোড হচ্ছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:86 #: data/com.jeffser.Alpaca.metainfo.xml.in:86
#: data/com.jeffser.Alpaca.metainfo.xml.in:99 #: data/com.jeffser.Alpaca.metainfo.xml.in:99
#: data/com.jeffser.Alpaca.metainfo.xml.in:124 #: data/com.jeffser.Alpaca.metainfo.xml.in:124
msgid "New" msgid "New"
msgstr "" msgstr "নতুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:88 #: data/com.jeffser.Alpaca.metainfo.xml.in:88
msgid "Added table rendering (Thanks Nokse)" msgid "Added table rendering (Thanks Nokse)"
msgstr "" msgstr "নকসের ধন্যবাদ, টেবিল রেন্ডারিং যোগ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:90 #: data/com.jeffser.Alpaca.metainfo.xml.in:90
#: data/com.jeffser.Alpaca.metainfo.xml.in:106 #: data/com.jeffser.Alpaca.metainfo.xml.in:106
#: data/com.jeffser.Alpaca.metainfo.xml.in:118 #: data/com.jeffser.Alpaca.metainfo.xml.in:118
#: data/com.jeffser.Alpaca.metainfo.xml.in:134 #: data/com.jeffser.Alpaca.metainfo.xml.in:134
msgid "Fixes" msgid "Fixes"
msgstr "" msgstr "সংশোধন করে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:92 #: data/com.jeffser.Alpaca.metainfo.xml.in:92
msgid "Made support dialog more common" msgid "Made support dialog more common"
msgstr "" msgstr "সাপোর্ট ডায়ালগকে আরও সাধারণ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:101 #: data/com.jeffser.Alpaca.metainfo.xml.in:101
msgid "Bearer Token entry on connection error dialog" msgid "Bearer Token entry on connection error dialog"
msgstr "" msgstr "কনেকশন এরর ডায়ালগে বিয়ারার টোকেন এন্ট্রি"
#: data/com.jeffser.Alpaca.metainfo.xml.in:102 #: data/com.jeffser.Alpaca.metainfo.xml.in:102
msgid "Small appearance changes" msgid "Small appearance changes"
msgstr "" msgstr "ছোট আকারের পরিবর্তন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:103 #: data/com.jeffser.Alpaca.metainfo.xml.in:103
msgid "Compatibility with code blocks without explicit language" msgid "Compatibility with code blocks without explicit language"
msgstr "" msgstr "স্পষ্ট ভাষা ছাড়া কোড ব্লকগুলির সাথে সামঞ্জস্য"
#: data/com.jeffser.Alpaca.metainfo.xml.in:104 #: data/com.jeffser.Alpaca.metainfo.xml.in:104
msgid "Rare, optional and dismissible support dialog" msgid "Rare, optional and dismissible support dialog"
msgstr "" msgstr "বিরল, ঐচ্ছিক এবং বাতিলযোগ্য সাপোর্ট ডায়ালগ"
#: data/com.jeffser.Alpaca.metainfo.xml.in:108 #: data/com.jeffser.Alpaca.metainfo.xml.in:108
msgid "Date format for Simplified Chinese translation" msgid "Date format for Simplified Chinese translation"
msgstr "" msgstr "সরলীকৃত চাইনিজ অনুবাদের জন্য তারিখ ফরম্যাট"
#: data/com.jeffser.Alpaca.metainfo.xml.in:109 #: data/com.jeffser.Alpaca.metainfo.xml.in:109
msgid "Bug with unsupported localizations" msgid "Bug with unsupported localizations"
msgstr "" msgstr "অসমর্থিত স্থানীয়করণের সাথে বাগ"
#: data/com.jeffser.Alpaca.metainfo.xml.in:110 #: data/com.jeffser.Alpaca.metainfo.xml.in:110
msgid "Min height being too large to be used on mobile" msgid "Min height being too large to be used on mobile"
msgstr "" msgstr "মোবাইলে ব্যবহারের জন্য ন্যূনতম উচ্চতা খুব বড়"
#: data/com.jeffser.Alpaca.metainfo.xml.in:111 #: data/com.jeffser.Alpaca.metainfo.xml.in:111
msgid "Remote connection checker bug" msgid "Remote connection checker bug"
msgstr "" msgstr "রিমোট কনেকশন চেকার বাগ"
#: data/com.jeffser.Alpaca.metainfo.xml.in:120 #: data/com.jeffser.Alpaca.metainfo.xml.in:120
msgid "Models with capital letters on their tag don't work" msgid "Models with capital letters on their tag don't work"
msgstr "" msgstr "তাদের ট্যাগে বড় হাতের অক্ষর থাকা মডেলগুলি কাজ করে না"
#: data/com.jeffser.Alpaca.metainfo.xml.in:121 #: data/com.jeffser.Alpaca.metainfo.xml.in:121
msgid "Ollama fails to launch on some systems" msgid "Ollama fails to launch on some systems"
msgstr "" msgstr "কিছু সিস্টেমে Ollama চালু করতে ব্যর্থ হয়"
#: data/com.jeffser.Alpaca.metainfo.xml.in:122 #: data/com.jeffser.Alpaca.metainfo.xml.in:122
msgid "YouTube transcripts are not being saved in the right TMP directory" msgid "YouTube transcripts are not being saved in the right TMP directory"
msgstr "" msgstr "ইউটিউব ট্রান্সক্রিপ্টগুলি সঠিক TMP ডিরেক্টরিতে সংরক্ষিত হচ্ছে না"
#: data/com.jeffser.Alpaca.metainfo.xml.in:126 #: data/com.jeffser.Alpaca.metainfo.xml.in:126
msgid "Debug messages are now shown on the 'About Alpaca' dialog" msgid "Debug messages are now shown on the 'About Alpaca' dialog"
msgstr "" msgstr "ডিবাগ বার্তাগুলি এখন 'About Alpaca' ডায়ালগে দেখানো হচ্ছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:127 #: data/com.jeffser.Alpaca.metainfo.xml.in:127
msgid "Updated Ollama to v0.3.0 (new models)" msgid "Updated Ollama to v0.3.0 (new models)"
msgstr "" msgstr "Ollama আপডেট করা হয়েছে v0.3.0 (নতুন মডেল)"
#: data/com.jeffser.Alpaca.metainfo.xml.in:136 #: data/com.jeffser.Alpaca.metainfo.xml.in:136
msgid "Models with '-' in their names didn't work properly, this is now fixed" msgid "Models with '-' in their names didn't work properly, this is now fixed"
msgstr "" msgstr "তাদের নামে '-' থাকা মডেলগুলি সঠিকভাবে কাজ করে না, এটি এখন সংশোধন করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:137 #: data/com.jeffser.Alpaca.metainfo.xml.in:137
msgid "Better connection check for Ollama" msgid "Better connection check for Ollama"
msgstr "" msgstr "ওল্লামা এর জন্য ভাল কনেকশন চেক"
#: data/com.jeffser.Alpaca.metainfo.xml.in:144 #: data/com.jeffser.Alpaca.metainfo.xml.in:144
msgid "Stable Release" msgid "Stable Release"
msgstr "" msgstr "স্থিতিশীল রিলিজ"
#: data/com.jeffser.Alpaca.metainfo.xml.in:145 #: data/com.jeffser.Alpaca.metainfo.xml.in:145
msgid "" msgid ""
"The new icon was made by Tobias Bernard over the Gnome Gitlab, thanks for " "The new icon was made by Tobias Bernard over the Gnome Gitlab, thanks for "
"the great icon!" "the great icon!"
msgstr "" msgstr ""
"টোবিয়াস বার্নার্ড দ্বারা নতুন আইকনটি জিনোম গিটল্যাব এর উপরে তৈরি করা হয়েছে, "
"দুর্দান্ত আইকনের জন্য ধন্যবাদ!"
#: data/com.jeffser.Alpaca.metainfo.xml.in:146 #: data/com.jeffser.Alpaca.metainfo.xml.in:146
msgid "Features and fixes" msgid "Features and fixes"
msgstr "" msgstr "বৈশিষ্ট্য এবং সংশোধন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:148 #: data/com.jeffser.Alpaca.metainfo.xml.in:148
msgid "Updated Ollama instance to 0.2.8" msgid "Updated Ollama instance to 0.2.8"
msgstr "" msgstr "অল্লামা ইনস্ট্যান্স .২.৮ এ আপডেট করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:149 #: data/com.jeffser.Alpaca.metainfo.xml.in:149
msgid "Better model selector" msgid "Better model selector"
msgstr "" msgstr "আরও ভালো মডেল নির্বাচক"
#: data/com.jeffser.Alpaca.metainfo.xml.in:150 #: data/com.jeffser.Alpaca.metainfo.xml.in:150
msgid "Model manager redesign" msgid "Model manager redesign"
msgstr "" msgstr "মডেল ম্যানেজার পুনঃনকশা"
#: data/com.jeffser.Alpaca.metainfo.xml.in:151 #: data/com.jeffser.Alpaca.metainfo.xml.in:151
msgid "Better tag selector when pulling a model" msgid "Better tag selector when pulling a model"
msgstr "" msgstr "মডেল টানার সময় আরও ভালো ট্যাগ নির্বাচক"
#: data/com.jeffser.Alpaca.metainfo.xml.in:152 #: data/com.jeffser.Alpaca.metainfo.xml.in:152
msgid "Model search" msgid "Model search"
msgstr "" msgstr "মডেল অনুসন্ধান"
#: data/com.jeffser.Alpaca.metainfo.xml.in:153 #: data/com.jeffser.Alpaca.metainfo.xml.in:153
msgid "Added support for bearer tokens on remote instances" msgid "Added support for bearer tokens on remote instances"
msgstr "" msgstr "দূরবর্তী ইনস্ট্যান্সে বেয়ারার টোকেনের জন্য সমর্থন যোগ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:154 #: data/com.jeffser.Alpaca.metainfo.xml.in:154
msgid "Preferences dialog redesign" msgid "Preferences dialog redesign"
msgstr "" msgstr "পছন্দ ডায়ালগ পুনঃনকশা"
#: data/com.jeffser.Alpaca.metainfo.xml.in:155 #: data/com.jeffser.Alpaca.metainfo.xml.in:155
msgid "Added context menus to interact with a chat" msgid "Added context menus to interact with a chat"
msgstr "" msgstr "চ্যাটের সাথে ইন্টারঅ্যাক্ট করার জন্য সংক্ষিপ্ত মেনু যোগ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:156 #: data/com.jeffser.Alpaca.metainfo.xml.in:156
msgid "Redesigned primary and secondary menus" msgid "Redesigned primary and secondary menus"
msgstr "" msgstr "প্রাথমিক এবং গৌণ মেনু পুনঃনকশা"
#: data/com.jeffser.Alpaca.metainfo.xml.in:157 #: data/com.jeffser.Alpaca.metainfo.xml.in:157
msgid "" msgid ""
"YouTube integration: Paste the URL of a video with a transcript and it will " "YouTube integration: Paste the URL of a video with a transcript and it will "
"be added to the prompt" "be added to the prompt"
msgstr "" msgstr ""
"ইউটিউব একীকরণ: একটি লিপি সহ ভিডিওর ইউআরএল পেস্ট করুন এবং এটি প্রম্পটে যোগ করা হবে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:158 #: data/com.jeffser.Alpaca.metainfo.xml.in:158
msgid "" msgid ""
"Website integration (Experimental): Extract the text from the body of a " "Website integration (Experimental): Extract the text from the body of a "
"website by adding it's URL to the prompt" "website by adding it's URL to the prompt"
msgstr "" msgstr ""
"ওয়েবসাইট একীকরণ (পরীক্ষামূলক): প্রম্পটে ইউআরএল যোগ করে ওয়েবসাইটের শরীর থেকে "
"পাঠ্য নির্যাস করুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:159 #: data/com.jeffser.Alpaca.metainfo.xml.in:159
msgid "Chat title generation" msgid "Chat title generation"
msgstr "" msgstr "চ্যাট শিরোনাম উৎপাদন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:160 #: data/com.jeffser.Alpaca.metainfo.xml.in:160
msgid "Auto resizing of message entry" msgid "Auto resizing of message entry"
msgstr "" msgstr "বার্তা প্রবেশের স্বয়ংক্রিয় আকার পরিবর্তন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:161 #: data/com.jeffser.Alpaca.metainfo.xml.in:161
msgid "Chat notifications" msgid "Chat notifications"
msgstr "" msgstr "চ্যাট বিজ্ঞপ্তি"
#: data/com.jeffser.Alpaca.metainfo.xml.in:162 #: data/com.jeffser.Alpaca.metainfo.xml.in:162
msgid "Added indicator when an image is missing" msgid "Added indicator when an image is missing"
msgstr "" msgstr "একটি ছবি অনুপস্থিত থাকলে সূচক যোগ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:163 #: data/com.jeffser.Alpaca.metainfo.xml.in:163
msgid "Auto rearrange the order of chats when a message is received" msgid "Auto rearrange the order of chats when a message is received"
msgstr "" msgstr "একটি বার্তা প্রাপ্ত হলে চ্যাটের ক্রম স্বয়ংক্রিয় পুনর্বিন্যাস"
#: data/com.jeffser.Alpaca.metainfo.xml.in:164 #: data/com.jeffser.Alpaca.metainfo.xml.in:164
msgid "Redesigned file preview dialog" msgid "Redesigned file preview dialog"
msgstr "" msgstr "ফাইল পূর্বরূপ ডায়ালগ পুনঃনকশা"
#: data/com.jeffser.Alpaca.metainfo.xml.in:165 #: data/com.jeffser.Alpaca.metainfo.xml.in:165
msgid "Credited new contributors" msgid "Credited new contributors"
msgstr "" msgstr "নতুন অবদানকারীদের কৃতিত্ব দেওয়া হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:166 #: data/com.jeffser.Alpaca.metainfo.xml.in:166
msgid "Better stability and optimization" msgid "Better stability and optimization"
msgstr "" msgstr "আরও ভালো স্থিতিশীলতা এবং অপ্টিমাইজেশন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:167 #: data/com.jeffser.Alpaca.metainfo.xml.in:167
msgid "Edit messages to change the context of a conversation" msgid "Edit messages to change the context of a conversation"
msgstr "" msgstr "কনভার্সেশনের প্রসঙ্গ পরিবর্তন করার জন্য বার্তা সম্পাদনা করুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:168 #: data/com.jeffser.Alpaca.metainfo.xml.in:168
msgid "Added disclaimers when pulling models" msgid "Added disclaimers when pulling models"
msgstr "" msgstr "মডেল টানার সময় দাবি যোগ করা হয়েছে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:169 #: data/com.jeffser.Alpaca.metainfo.xml.in:169
msgid "Preview files before sending a message" msgid "Preview files before sending a message"
msgstr "" msgstr "বার্তা পাঠানোর আগে ফাইল পূর্বরূপ দেখুন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:170 #: data/com.jeffser.Alpaca.metainfo.xml.in:170
msgid "Better format for date and time on messages" msgid "Better format for date and time on messages"
msgstr "" msgstr "বার্তায় তারিখ এবং সময়ের জন্য আরও ভালো ফরম্যাট"
#: data/com.jeffser.Alpaca.metainfo.xml.in:171 #: data/com.jeffser.Alpaca.metainfo.xml.in:171
msgid "Error and debug logging on terminal" msgid "Error and debug logging on terminal"
msgstr "" msgstr "টার্মিনালে ত্রুটি এবং ডিবাগ লগিং"
#: data/com.jeffser.Alpaca.metainfo.xml.in:172 #: data/com.jeffser.Alpaca.metainfo.xml.in:172
msgid "Auto-hiding sidebar button" msgid "Auto-hiding sidebar button"
msgstr "" msgstr "সাইডবার বাটন স্বয়ংক্রিয় লুকানো"
#: data/com.jeffser.Alpaca.metainfo.xml.in:173 #: data/com.jeffser.Alpaca.metainfo.xml.in:173
msgid "Various UI tweaks" msgid "Various UI tweaks"
msgstr "" msgstr "বিভিন্ন ইউআই টুইকস"
#: data/com.jeffser.Alpaca.metainfo.xml.in:175 #: data/com.jeffser.Alpaca.metainfo.xml.in:175
msgid "New Models" msgid "New Models"
msgstr "" msgstr "নতুন মডেল"
#: data/com.jeffser.Alpaca.metainfo.xml.in:177 #: data/com.jeffser.Alpaca.metainfo.xml.in:177
msgid "Gemma2" msgid "Gemma2"
msgstr "" msgstr "জেমা 2"
#: data/com.jeffser.Alpaca.metainfo.xml.in:178 #: data/com.jeffser.Alpaca.metainfo.xml.in:178
msgid "GLM4" msgid "GLM4"
msgstr "" msgstr "জিএলএম 4"
#: data/com.jeffser.Alpaca.metainfo.xml.in:179 #: data/com.jeffser.Alpaca.metainfo.xml.in:179
msgid "Codegeex4" msgid "Codegeex4"
msgstr "" msgstr "কোডজিক্স 4"
#: data/com.jeffser.Alpaca.metainfo.xml.in:180 #: data/com.jeffser.Alpaca.metainfo.xml.in:180
msgid "InternLM2" msgid "InternLM2"
msgstr "" msgstr "ইন্টার্নএলএম 2"
#: data/com.jeffser.Alpaca.metainfo.xml.in:181 #: data/com.jeffser.Alpaca.metainfo.xml.in:181
msgid "Llama3-groq-tool-use" msgid "Llama3-groq-tool-use"
msgstr "" msgstr "ল্লামা 3-গ্রোক-টুল-ব্যবহার"
#: data/com.jeffser.Alpaca.metainfo.xml.in:182 #: data/com.jeffser.Alpaca.metainfo.xml.in:182
msgid "Mathstral" msgid "Mathstral"
msgstr "" msgstr "ম্যাথস্ট্রাল"
#: data/com.jeffser.Alpaca.metainfo.xml.in:183 #: data/com.jeffser.Alpaca.metainfo.xml.in:183
msgid "Mistral-nemo" msgid "Mistral-nemo"
msgstr "" msgstr "মিস্ট্রাল-নেমো"
#: data/com.jeffser.Alpaca.metainfo.xml.in:184 #: data/com.jeffser.Alpaca.metainfo.xml.in:184
msgid "Firefunction-v2" msgid "Firefunction-v2"
msgstr "" msgstr "ফায়ারফাংশন-ভি 2"
#: data/com.jeffser.Alpaca.metainfo.xml.in:185 #: data/com.jeffser.Alpaca.metainfo.xml.in:185
msgid "Nuextract" msgid "Nuextract"
msgstr "" msgstr "নুএক্সট্র্যাক্ট"
#: data/com.jeffser.Alpaca.metainfo.xml.in:187 #: data/com.jeffser.Alpaca.metainfo.xml.in:187
msgid "Translations" msgid "Translations"
msgstr "" msgstr "অনুবাদ"
#: data/com.jeffser.Alpaca.metainfo.xml.in:188 #: data/com.jeffser.Alpaca.metainfo.xml.in:188
msgid "" msgid ""
"These are all the available translations on 1.0.0, thanks to all the " "These are all the available translations on 1.0.0, thanks to all the "
"contributors!" "contributors!"
msgstr "" msgstr ""
"এগুলি 1.0.0 এর উপলব্ধ সমস্ত অনুবাদ, সমস্ত অবদানকারীদের ধন্যবাদ!"
#: data/com.jeffser.Alpaca.metainfo.xml.in:190 #: data/com.jeffser.Alpaca.metainfo.xml.in:190
msgid "Russian: Alex K" msgid "Russian: Alex K"
msgstr "" msgstr "রাশিয়ান: আলেক্স কে"
#: data/com.jeffser.Alpaca.metainfo.xml.in:191 #: data/com.jeffser.Alpaca.metainfo.xml.in:191
msgid "Spanish: Jeffser" msgid "Spanish: Jeffser"
msgstr "" msgstr "স্প্যানিশ: জেফসার"
#: data/com.jeffser.Alpaca.metainfo.xml.in:192 #: data/com.jeffser.Alpaca.metainfo.xml.in:192
msgid "Brazilian Portuguese: Daimar Stein" msgid "Brazilian Portuguese: Daimar Stein"
msgstr "" msgstr "ব্রাজিলিয়ান পর্তুগিজ: ডাইমার স্টাইন"
#: data/com.jeffser.Alpaca.metainfo.xml.in:193 #: data/com.jeffser.Alpaca.metainfo.xml.in:193
msgid "French: Louis Chauvet-Villaret" msgid "French: Louis Chauvet-Villaret"
msgstr "" msgstr "ফ্রেন্চ: লুই শাভে-ভিলারেট"
#: data/com.jeffser.Alpaca.metainfo.xml.in:194 #: data/com.jeffser.Alpaca.metainfo.xml.in:194
msgid "Norwegian: CounterFlow64" msgid "Norwegian: CounterFlow64"
msgstr "" msgstr "নরওয়েজিয়ান: কাউন্টারফ্লো 64"
#: data/com.jeffser.Alpaca.metainfo.xml.in:195 #: data/com.jeffser.Alpaca.metainfo.xml.in:195
msgid "Bengali: Aritra Saha" msgid "Bengali: Aritra Saha"
msgstr "" msgstr "বাংলা: অরিত্র সাহা"
#: data/com.jeffser.Alpaca.metainfo.xml.in:196 #: data/com.jeffser.Alpaca.metainfo.xml.in:196
msgid "Simplified Chinese: Yuehao Sui" msgid "Simplified Chinese: Yuehao Sui"
msgstr "" msgstr "সরলীকৃত চাইনিজ: ইউহাও সুই"
#: data/com.jeffser.Alpaca.metainfo.xml.in:203 #: data/com.jeffser.Alpaca.metainfo.xml.in:203
#: data/com.jeffser.Alpaca.metainfo.xml.in:252 #: data/com.jeffser.Alpaca.metainfo.xml.in:252
@@ -1097,6 +1103,7 @@ msgid ""
"Llama 3.1 is a new state-of-the-art model from Meta available in 8B, 70B and " "Llama 3.1 is a new state-of-the-art model from Meta available in 8B, 70B and "
"405B parameter sizes." "405B parameter sizes."
msgstr "" msgstr ""
"ল্লামা 3.1 হল মেটা থেকে নতুন স্টেট-অফ-দ্য-আর্ট মডেল, 8B, 70B এবং 405B প্যারামিটার আকারে উপলব্ধ।"
#: src/available_models_descriptions.py:3 #: src/available_models_descriptions.py:3
msgid "Google Gemma 2 is now available in 2 sizes, 9B and 27B." msgid "Google Gemma 2 is now available in 2 sizes, 9B and 27B."
@@ -1107,6 +1114,7 @@ msgid ""
"A state-of-the-art 12B model with 128k context length, built by Mistral AI " "A state-of-the-art 12B model with 128k context length, built by Mistral AI "
"in collaboration with NVIDIA." "in collaboration with NVIDIA."
msgstr "" msgstr ""
"একটি স্টেট-অফ-দ্য-আর্ট 12B মডেল, 128k কনটেক্সট দৈর্ঘ্য, মিস্ট্রাল এআই এবং এনভিডিয়ার সহযোগিতায় নির্মিত।"
#: src/available_models_descriptions.py:5 #: src/available_models_descriptions.py:5
msgid "" msgid ""
@@ -1114,6 +1122,8 @@ msgid ""
"capable in code generation, mathematics, and reasoning with 128k context " "capable in code generation, mathematics, and reasoning with 128k context "
"window and support for dozens of languages." "window and support for dozens of languages."
msgstr "" msgstr ""
"মিস্ট্রাল লার্জ 2 হল মিস্ট্রালের নতুন ফ্ল্যাগশিপ মডেল, যা কোড জেনারেশন, গণিত এবং যুক্তির ক্ষেত্রে "
"উল্লেখযোগ্যভাবে আরও ক্ষমতাসম্পন্ন, 128k কনটেক্সট উইন্ডো এবং ডজনখানি ভাষার সমর্থন সহ।"
#: src/available_models_descriptions.py:6 #: src/available_models_descriptions.py:6
msgid "Qwen2 is a new series of large language models from Alibaba group" msgid "Qwen2 is a new series of large language models from Alibaba group"
@@ -2160,6 +2170,11 @@ msgid ""
"model's website.\n" "model's website.\n"
" " " "
msgstr "" msgstr ""
"আলপাকা আপনার ডিভাইসে স্থানীয়ভাবে কাজ করে, চ্যাটিং শুরু করতে আপনার একটি এআই মডেল প্রয়োজন, "
"আপনি এই তালিকা থেকে মডেল টানতে পারেন বা পরে 'মডেল ব্যবস্থাপনা' মেনু থেকে।\n"
"\n"
"যে কোনও মডেল ডাউনলোড করার মাধ্যমে আপনি তাদের লাইসেন্স চুক্তি গ্রহণ করছেন যা মডেলের ওয়েবসাইটে উপলব্ধ।\n"
" "
#: src/window.ui:909 #: src/window.ui:909
msgid "Built by Meta" msgid "Built by Meta"

View File

@@ -5,7 +5,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.9.6.1\n" "Project-Id-Version: 1.0.4\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-01 14:36-0600\n" "POT-Creation-Date: 2024-08-01 14:36-0600\n"
"PO-Revision-Date: 2024-07-21 22:46+0200\n" "PO-Revision-Date: 2024-07-21 22:46+0200\n"

View File

@@ -28,6 +28,7 @@
<file alias="icons/scalable/status/edit-find-symbolic.svg">icons/edit-find-symbolic.svg</file> <file alias="icons/scalable/status/edit-find-symbolic.svg">icons/edit-find-symbolic.svg</file>
<file alias="icons/scalable/status/edit-symbolic.svg">icons/edit-symbolic.svg</file> <file alias="icons/scalable/status/edit-symbolic.svg">icons/edit-symbolic.svg</file>
<file alias="icons/scalable/status/image-missing-symbolic.svg">icons/image-missing-symbolic.svg</file> <file alias="icons/scalable/status/image-missing-symbolic.svg">icons/image-missing-symbolic.svg</file>
<file alias="icons/scalable/status/update-symbolic.svg">icons/update-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

@@ -224,7 +224,7 @@ def create_model_from_existing_response(self, dialog, task, dropdown):
def create_model_from_existing(self): def create_model_from_existing(self):
string_list = Gtk.StringList() string_list = Gtk.StringList()
for model in self.local_models: for model in self.local_models:
string_list.append(model) string_list.append(self.convert_model_name(model, 0))
dropdown = Gtk.DropDown() dropdown = Gtk.DropDown()
dropdown.set_model(string_list) dropdown.set_model(string_list)
@@ -257,6 +257,27 @@ def create_model_from_file(self):
file_dialog = Gtk.FileDialog(default_filter=self.file_filter_gguf) 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)) file_dialog.open(self, None, lambda file_dialog, result: create_model_from_file_response(self, file_dialog, result))
def create_model_from_name_response(self, dialog, task, entry):
model = entry.get_text().lower().strip()
if dialog.choose_finish(task) == 'accept' and model:
self.pull_model(model)
def create_model_from_name(self):
entry = Gtk.Entry()
entry.get_delegate().connect("insert-text", self.check_alphanumeric)
dialog = Adw.AlertDialog(
heading=_("Pull Model"),
body=_("Input the name of the model in this format\nname:tag"),
extra_child=entry
)
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, entry=entry: create_model_from_name_response(self, dialog, task, entry)
)
# FILE CHOOSER | WORKS # FILE CHOOSER | WORKS
def attach_file_response(self, file_dialog, result): def attach_file_response(self, file_dialog, result):
@@ -378,6 +399,8 @@ def support_response(self, dialog, task):
elif res == 'support': elif res == 'support':
self.show_toast(_("Thank you!"), self.main_overlay) self.show_toast(_("Thank you!"), self.main_overlay)
os.system('xdg-open https://github.com/sponsors/Jeffser') os.system('xdg-open https://github.com/sponsors/Jeffser')
elif res == 'nope':
self.show_toast(_("Visit Alpaca's website if you change your mind!"), self.main_overlay)
self.show_support = False self.show_support = False
self.save_server_config() self.save_server_config()

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"><g fill="#222222"><path d="m 7.957031 2 c -0.082031 0 -0.164062 0.003906 -0.246093 0.007812 c -0.1875 0.011719 -0.375 0.03125 -0.5625 0.0625 c -1.582032 0.226563 -3.007813 1.070313 -3.96875 2.34375 c -0.804688 1.074219 -1.183594 2.332032 -1.179688 3.585938 h 2.003906 c 0 -0.832031 0.253906 -1.671875 0.796875 -2.398438 c 1.335938 -1.777343 3.820313 -2.113281 5.597657 -0.78125 c 0.429687 0.320313 0.769531 0.734376 1.03125 1.1875 h -1.4375 c -0.550782 0 -1 0.449219 -1 1 v 1 h 6 v -6 h -1 c -0.550782 0 -1 0.449219 -1 1 v 1.6875 c -1.113282 -1.695312 -3.007813 -2.710937 -5.039063 -2.695312 z m 0 0"/><path d="m 8.035156 15.007812 c 0.082032 0 0.164063 -0.003906 0.246094 -0.007812 c 0.1875 -0.011719 0.375 -0.03125 0.5625 -0.0625 c 1.582031 -0.226562 3.007812 -1.066406 3.96875 -2.34375 c 0.804688 -1.074219 1.183594 -2.332031 1.179688 -3.585938 h -2.003907 c -0.003906 0.832032 -0.257812 1.675782 -0.796875 2.398438 c -1.335937 1.777344 -3.820312 2.113281 -5.597656 0.78125 c -0.429688 -0.320312 -0.769531 -0.734375 -1.03125 -1.1875 h 1.4375 c 0.550781 0 1 -0.449219 1 -1 v -1 h -6 v 6 h 1 c 0.550781 0 1 -0.449219 1 -1 v -1.6875 c 1.113281 1.695312 3.007812 2.710938 5.035156 2.695312 z m 0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -2,7 +2,7 @@
box-shadow: none; box-shadow: none;
border-width: 0; border-width: 0;
} }
.message_text_view { .message_text_view, .modelfile_textview {
background-color: rgba(0,0,0,0); background-color: rgba(0,0,0,0);
} }
.chat_image_button { .chat_image_button {
@@ -12,7 +12,3 @@
border-radius: 5px; border-radius: 5px;
padding: 5px; padding: 5px;
} }
.chat_row:selected {
background: mix(@theme_bg_color, @theme_selected_bg_color, 0.3);
color: mix(@window_fg_color, @theme_selected_bg_color, 0.5);
}

View File

@@ -68,11 +68,11 @@ class AlpacaWindow(Adw.ApplicationWindow):
override_HIP_VISIBLE_DEVICES = Gtk.Template.Child() override_HIP_VISIBLE_DEVICES = Gtk.Template.Child()
#Elements #Elements
regenerate_button : Gtk.Button = None
create_model_base = Gtk.Template.Child() create_model_base = Gtk.Template.Child()
create_model_name = Gtk.Template.Child() create_model_name = Gtk.Template.Child()
create_model_system = Gtk.Template.Child() create_model_system = Gtk.Template.Child()
create_model_template = Gtk.Template.Child() create_model_modelfile = Gtk.Template.Child()
create_model_dialog = Gtk.Template.Child()
temperature_spin = Gtk.Template.Child() temperature_spin = Gtk.Template.Child()
seed_spin = Gtk.Template.Child() seed_spin = Gtk.Template.Child()
keep_alive_spin = Gtk.Template.Child() keep_alive_spin = Gtk.Template.Child()
@@ -135,7 +135,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
def verify_if_image_can_be_used(self, pspec=None, user_data=None): def verify_if_image_can_be_used(self, pspec=None, user_data=None):
logger.debug("Verifying if image can be used") logger.debug("Verifying if image can be used")
if self.model_drop_down.get_selected_item() == None: return True if self.model_drop_down.get_selected_item() == None: return True
selected = self.model_drop_down.get_selected_item().get_string().split(" (")[0].lower() 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"]]: if selected in [key for key, value in self.available_models.items() if value["image"]]:
for name, content in self.attachments.items(): for name, content in self.attachments.items():
if content['type'] == 'image': if content['type'] == 'image':
@@ -183,8 +183,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.chats['order'].remove(self.chats['selected_chat']) self.chats['order'].remove(self.chats['selected_chat'])
self.chats['order'].insert(0, self.chats['selected_chat']) self.chats['order'].insert(0, self.chats['selected_chat'])
self.save_history() self.save_history()
current_model = self.model_drop_down.get_selected_item().get_string().split(' (') current_model = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1)
current_model = '{}:{}'.format(current_model[0].replace(' ', '-').lower(), current_model[1][:-1])
if current_model is None: if current_model is None:
self.show_toast(_("Please select a model before chatting"), self.main_overlay) self.show_toast(_("Please select a model before chatting"), self.main_overlay)
return return
@@ -282,8 +281,10 @@ class AlpacaWindow(Adw.ApplicationWindow):
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"].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()): for i in range(self.model_string_list.get_n_items()):
if self.model_string_list.get_string(i) == self.chats["chats"][self.chats["selected_chat"]]["messages"][list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys())[-1]]["model"]: if self.model_string_list.get_string(i) == last_model_used:
self.model_drop_down.set_selected(i) self.model_drop_down.set_selected(i)
break break
self.save_history() self.save_history()
@@ -343,19 +344,18 @@ class AlpacaWindow(Adw.ApplicationWindow):
@Gtk.Template.Callback() @Gtk.Template.Callback()
def create_model_start(self, button): def create_model_start(self, button):
base = self.create_model_base.get_subtitle() name = self.create_model_name.get_text().lower().replace(":", "")
name = self.create_model_name.get_text() modelfile_buffer = self.create_model_modelfile.get_buffer()
system = self.create_model_system.get_text() modelfile_raw = modelfile_buffer.get_text(modelfile_buffer.get_start_iter(), modelfile_buffer.get_end_iter(), False)
template = self.create_model_template.get_text() modelfile = ["FROM {}".format(self.create_model_base.get_subtitle()), "SYSTEM {}".format(self.create_model_system.get_text())]
if "/" in base: for line in modelfile_raw.split('\n'):
modelfile = f"FROM {base}\nSYSTEM {system}\nTEMPLATE {template}" if not line.startswith('SYSTEM') and not line.startswith('FROM'):
else: modelfile.append(line)
modelfile = f"FROM {base}\nSYSTEM {system}"
self.pulling_model_list_box.set_visible(True) self.pulling_model_list_box.set_visible(True)
model_row = Adw.ActionRow( model_row = Adw.ActionRow(
title = name title = name
) )
thread = threading.Thread(target=self.pull_model_process, kwargs={"model": name, "modelfile": modelfile}) thread = threading.Thread(target=self.pull_model_process, kwargs={"model": name, "modelfile": '\n'.join(modelfile)})
overlay = Gtk.Overlay() overlay = Gtk.Overlay()
progress_bar = Gtk.ProgressBar( progress_bar = Gtk.ProgressBar(
valign = 2, valign = 2,
@@ -377,7 +377,7 @@ class AlpacaWindow(Adw.ApplicationWindow):
overlay.set_child(model_row) overlay.set_child(model_row)
overlay.add_overlay(progress_bar) overlay.add_overlay(progress_bar)
self.pulling_model_list_box.append(overlay) self.pulling_model_list_box.append(overlay)
self.create_model_dialog.close() self.navigation_view_manage_models.pop()
self.manage_models_dialog.present(self) self.manage_models_dialog.present(self)
thread.start() thread.start()
@@ -415,38 +415,37 @@ class AlpacaWindow(Adw.ApplicationWindow):
self.available_model_list_box.set_visible(True) self.available_model_list_box.set_visible(True)
self.no_results_page.set_visible(False) self.no_results_page.set_visible(False)
def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag
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])
def check_alphanumeric(self, editable, text, length, position): def check_alphanumeric(self, editable, text, length, position):
new_text = ''.join([char for char in text if char.isalnum() or char in ['-', '_']]) 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") if new_text != text: editable.stop_emission_by_name("insert-text")
def create_model(self, model:str, file:bool): def create_model(self, model:str, file:bool):
name = "" modelfile_buffer = self.create_model_modelfile.get_buffer()
system = "" modelfile_buffer.delete(modelfile_buffer.get_start_iter(), modelfile_buffer.get_end_iter())
template = "" self.create_model_system.set_text('')
if not file: if not file:
response = connection_handler.simple_post(f"{connection_handler.url}/api/show", json.dumps({"name": model})) response = connection_handler.simple_post(f"{connection_handler.url}/api/show", json.dumps({"name": self.convert_model_name(model, 1)}))
if response.status_code == 200: if response.status_code == 200:
data = json.loads(response.text) data = json.loads(response.text)
modelfile = []
for line in data['modelfile'].split('\n'): for line in data['modelfile'].split('\n'):
if line.startswith('SYSTEM'): if line.startswith('SYSTEM'):
system = line[len('SYSTEM'):].strip() self.create_model_system.set_text(line[len('SYSTEM'):].strip())
elif line.startswith('TEMPLATE'): if not line.startswith('SYSTEM') and not line.startswith('FROM') and not line.startswith('#'):
template = line[len('TEMPLATE'):].strip() modelfile.append(line)
self.create_model_template.set_sensitive(False) self.create_model_name.set_text(self.convert_model_name(model, 1).split(':')[0] + "-custom")
name = model.split(':')[0] modelfile_buffer.insert(modelfile_buffer.get_start_iter(), '\n'.join(modelfile), len('\n'.join(modelfile).encode('utf-8')))
else:
##TODO ERROR MESSAGE
return
else: else:
self.create_model_template.set_sensitive(True) self.create_model_name.set_text(model.split("/")[-1].split(".")[0])
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|>"""' self.create_model_base.set_subtitle(self.convert_model_name(model, 1))
name = model.split("/")[-1].split(".")[0] self.navigation_view_manage_models.push_by_tag('model_create_page')
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:str, overlay): def show_toast(self, message:str, overlay):
logger.info(message) logger.info(message)
@@ -574,13 +573,12 @@ Generate a title following these rules:
```PROMPT ```PROMPT
{message['content']} {message['content']}
```""" ```"""
current_model = self.model_drop_down.get_selected_item().get_string().split(' (') current_model = self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1)
current_model = '{}:{}'.format(current_model[0].replace(' ', '-').lower(), current_model[1][:-1])
data = {"model": current_model, "prompt": prompt, "stream": False} data = {"model": current_model, "prompt": prompt, "stream": False}
if 'images' in message: data["images"] = message['images'] if 'images' in message: data["images"] = message['images']
response = connection_handler.simple_post(f"{connection_handler.url}/api/generate", data=json.dumps(data)) response = connection_handler.simple_post(f"{connection_handler.url}/api/generate", data=json.dumps(data))
new_chat_name = json.loads(response.text)["response"].strip().removeprefix("Title: ").removeprefix("title: ").strip('\'"').replace('\n', ' ').title() new_chat_name = json.loads(response.text)["response"].strip().removeprefix("Title: ").removeprefix("title: ").strip('\'"').replace('\n', ' ').title().replace('\'S', '\'s')
new_chat_name = new_chat_name[:50] + (new_chat_name[50:] and '...') new_chat_name = new_chat_name[:50] + (new_chat_name[50:] and '...')
self.rename_chat(label_element.get_name(), new_chat_name, label_element) self.rename_chat(label_element.get_name(), new_chat_name, label_element)
@@ -616,6 +614,11 @@ Generate a title following these rules:
css_classes = ["flat", "circular"], css_classes = ["flat", "circular"],
tooltip_text = _("Edit Message") tooltip_text = _("Edit Message")
) )
regenerate_button = Gtk.Button(
icon_name = "update-symbolic",
css_classes = ["flat", "circular"],
tooltip_text = _("Regenerate Message")
)
button_container = Gtk.Box( button_container = Gtk.Box(
orientation=0, orientation=0,
@@ -731,9 +734,10 @@ Generate a title following these rules:
delete_button.connect("clicked", lambda button, element=overlay: self.delete_message(element)) delete_button.connect("clicked", lambda button, element=overlay: self.delete_message(element))
copy_button.connect("clicked", lambda button, element=overlay: self.copy_message(element)) copy_button.connect("clicked", lambda button, element=overlay: self.copy_message(element))
edit_button.connect("clicked", lambda button, element=overlay, textview=message_text, button_container=button_container: self.edit_message(element, textview, button_container)) edit_button.connect("clicked", lambda button, element=overlay, textview=message_text, button_container=button_container: self.edit_message(element, textview, button_container))
regenerate_button.connect('clicked', lambda button, id=id, bot_message_box=message_box, bot_message_button_container=button_container : self.regenerate_message(id, bot_message_box, bot_message_button_container))
button_container.append(delete_button) button_container.append(delete_button)
button_container.append(copy_button) button_container.append(copy_button)
if not bot: button_container.append(edit_button) button_container.append(regenerate_button if bot else edit_button)
overlay.add_overlay(button_container) overlay.add_overlay(button_container)
self.chat_container.append(overlay) self.chat_container.append(overlay)
@@ -756,25 +760,25 @@ Generate a title following these rules:
else: else:
self.local_model_list_box.set_visible(True) self.local_model_list_box.set_visible(True)
for model in json.loads(response.text)['models']: for model in json.loads(response.text)['models']:
model_name = self.convert_model_name(model["name"], 0)
model_row = Adw.ActionRow( model_row = Adw.ActionRow(
title = "<b>{}</b>".format(model["name"].split(":")[0].replace("-", " ").title()), title = "<b>{}</b>".format(model_name.split(" (")[0]),
subtitle = model["name"].split(":")[1] subtitle = model_name.split(" (")[1][:-1]
) )
button = Gtk.Button( button = Gtk.Button(
icon_name = "user-trash-symbolic", icon_name = "user-trash-symbolic",
vexpand = False, vexpand = False,
valign = 3, valign = 3,
css_classes = ["error", "circular"], css_classes = ["error", "circular"],
tooltip_text = _("Remove '{} ({})'").format(model["name"].split(":")[0].replace('-', ' ').title(), model["name"].split(":")[1]) tooltip_text = _("Remove '{}'").format(model_name)
) )
button.connect("clicked", lambda button=button, model_name=model["name"]: dialogs.delete_model(self, model_name)) button.connect("clicked", lambda button=button, model_name=model["name"]: dialogs.delete_model(self, model_name))
model_row.add_suffix(button) model_row.add_suffix(button)
self.local_model_list_box.append(model_row) self.local_model_list_box.append(model_row)
self.model_string_list.append(f"{model['name'].split(':')[0].replace('-', ' ').title()} ({model['name'].split(':')[1]})") self.model_string_list.append(model_name)
self.local_models.append(model["name"]) self.local_models.append(model["name"])
self.model_drop_down.set_selected(0) #self.verify_if_image_can_be_used()
self.verify_if_image_can_be_used()
return return
else: else:
self.connection_error() self.connection_error()
@@ -948,9 +952,9 @@ Generate a title following these rules:
vadjustment = self.chat_window.get_vadjustment() vadjustment = self.chat_window.get_vadjustment()
if id not in self.chats["chats"][self.chats["selected_chat"]]["messages"] or vadjustment.get_value() + 50 >= vadjustment.get_upper() - vadjustment.get_page_size(): if id not in self.chats["chats"][self.chats["selected_chat"]]["messages"] or vadjustment.get_value() + 50 >= vadjustment.get_upper() - vadjustment.get_page_size():
GLib.idle_add(vadjustment.set_value, vadjustment.get_upper()) GLib.idle_add(vadjustment.set_value, vadjustment.get_upper())
if data['done']: if 'done' in data and data['done']:
formated_date = GLib.markup_escape_text(self.generate_datetime_format(datetime.strptime(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["date"], '%Y/%m/%d %H:%M:%S'))) formated_date = GLib.markup_escape_text(self.generate_datetime_format(datetime.strptime(self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["date"], '%Y/%m/%d %H:%M:%S')))
text = f"\n\n{data['model'].split(':')[0].replace('-', ' ').title()} ({data['model'].split(':')[1]})\n<small>{formated_date}</small>" text = f"\n\n{self.convert_model_name(data['model'], 0)}\n<small>{formated_date}</small>"
GLib.idle_add(self.bot_message.insert_markup, self.bot_message.get_end_iter(), text, len(text.encode('utf-8'))) GLib.idle_add(self.bot_message.insert_markup, self.bot_message.get_end_iter(), text, len(text.encode('utf-8')))
self.save_history() self.save_history()
GLib.idle_add(self.bot_message_button_container.set_visible, True) GLib.idle_add(self.bot_message_button_container.set_visible, True)
@@ -958,15 +962,9 @@ Generate a title following these rules:
first_paragraph = self.bot_message.get_text(self.bot_message.get_start_iter(), self.bot_message.get_end_iter(), False).split("\n")[0] first_paragraph = self.bot_message.get_text(self.bot_message.get_start_iter(), self.bot_message.get_end_iter(), False).split("\n")[0]
GLib.idle_add(self.show_notification, self.chats["selected_chat"], first_paragraph[:100] + (first_paragraph[100:] and '...'), Gio.ThemedIcon.new("chat-message-new-symbolic")) GLib.idle_add(self.show_notification, self.chats["selected_chat"], first_paragraph[:100] + (first_paragraph[100:] and '...'), Gio.ThemedIcon.new("chat-message-new-symbolic"))
else: else:
if id not in self.chats["chats"][self.chats["selected_chat"]]["messages"]: if not self.chats["chats"][self.chats["selected_chat"]]["messages"][id]["content"] and self.loading_spinner:
GLib.idle_add(self.chat_container.remove, self.loading_spinner) GLib.idle_add(self.chat_container.remove, self.loading_spinner)
self.loading_spinner = None self.loading_spinner = None
self.chats["chats"][self.chats["selected_chat"]]["messages"][id] = {
"role": "assistant",
"model": data['model'],
"date": datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
"content": ''
}
GLib.idle_add(self.bot_message.insert, self.bot_message.get_end_iter(), data['message']['content']) GLib.idle_add(self.bot_message.insert, self.bot_message.get_end_iter(), data['message']['content'])
self.chats["chats"][self.chats["selected_chat"]]["messages"][id]['content'] += data['message']['content'] self.chats["chats"][self.chats["selected_chat"]]["messages"][id]['content'] += data['message']['content']
@@ -981,17 +979,69 @@ Generate a title following these rules:
def run_message(self, messages, model, id): def run_message(self, messages, model, id):
logger.debug("Running message") logger.debug("Running message")
self.bot_message_button_container.set_visible(False) self.bot_message_button_container.set_visible(False)
response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, id=id: self.update_bot_message(data, id)) self.chats["chats"][self.chats["selected_chat"]]["messages"][id] = {
GLib.idle_add(self.add_code_blocks) "role": "assistant",
GLib.idle_add(self.switch_send_stop_button) "model": model,
GLib.idle_add(self.toggle_ui_sensitive, True) "date": datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
if self.loading_spinner: "content": ''
GLib.idle_add(self.chat_container.remove, self.loading_spinner) }
self.loading_spinner = None if self.regenerate_button:
if response.status_code != 200: GLib.idle_add(self.chat_container.remove, self.regenerate_button)
try:
response = connection_handler.stream_post(f"{connection_handler.url}/api/chat", data=json.dumps({"model": model, "messages": messages}), callback=lambda data, id=id: self.update_bot_message(data, id))
if response.status_code != 200: raise Exception('Network Error')
GLib.idle_add(self.add_code_blocks)
except Exception as e:
GLib.idle_add(self.connection_error) GLib.idle_add(self.connection_error)
self.regenerate_button = Gtk.Button(
child=Adw.ButtonContent(
icon_name='update-symbolic',
label=_('Regenerate Response')
),
css_classes=["suggested-action"],
halign=3
)
GLib.idle_add(self.chat_container.append, self.regenerate_button)
self.regenerate_button.connect('clicked', lambda button, id=id, bot_message_box=self.bot_message_box, bot_message_button_container=self.bot_message_button_container : self.regenerate_message(id, bot_message_box, bot_message_button_container))
finally:
GLib.idle_add(self.switch_send_stop_button)
GLib.idle_add(self.toggle_ui_sensitive, True)
if self.loading_spinner:
GLib.idle_add(self.chat_container.remove, self.loading_spinner)
self.loading_spinner = None
def regenerate_message(self, id, bot_message_box, bot_message_button_container):
self.bot_message_button_container = bot_message_button_container
self.bot_message_view = Gtk.TextView(
editable=False,
focusable=True,
wrap_mode= Gtk.WrapMode.WORD,
margin_top=12,
margin_bottom=12,
hexpand=True,
css_classes=["flat"]
)
self.bot_message = self.bot_message_view.get_buffer()
for widget in list(bot_message_box): bot_message_box.remove(widget)
bot_message_box.append(self.bot_message_view)
history = self.convert_history_to_ollama()[:list(self.chats["chats"][self.chats["selected_chat"]]["messages"].keys()).index(id)]
if id in self.chats["chats"][self.chats["selected_chat"]]["messages"]:
del self.chats["chats"][self.chats["selected_chat"]]["messages"][id]
data = {
"model": self.convert_model_name(self.model_drop_down.get_selected_item().get_string(), 1),
"messages": history,
"options": {"temperature": self.model_tweaks["temperature"], "seed": self.model_tweaks["seed"]},
"keep_alive": f"{self.model_tweaks['keep_alive']}m"
}
self.switch_send_stop_button()
self.toggle_ui_sensitive(False)
thread = threading.Thread(target=self.run_message, args=(data['messages'], data['model'], id))
thread.start()
def pull_model_update(self, data, model_name): def pull_model_update(self, data, model_name):
if 'error' in data:
self.pulling_models[model_name]['error'] = data['error']
return
if model_name in list(self.pulling_models.keys()): if model_name in list(self.pulling_models.keys()):
if 'completed' in data and 'total' in data: if 'completed' in data and 'total' in data:
GLib.idle_add(self.pulling_models[model_name]['row'].set_subtitle, '<tt>{}%</tt>'.format(round(data['completed'] / data['total'] * 100, 2))) GLib.idle_add(self.pulling_models[model_name]['row'].set_subtitle, '<tt>{}%</tt>'.format(round(data['completed'] / data['total'] * 100, 2)))
@@ -1012,28 +1062,31 @@ Generate a title following these rules:
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)) 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.update_list_local_models)
if response.status_code == 200: 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")) GLib.idle_add(self.show_notification, _("Task Complete"), _("Model '{}' pulled successfully.").format(model), Gio.ThemedIcon.new("emblem-ok-symbolic"))
GLib.idle_add(self.show_toast, _("Model '{}' pulled successfully.").format(model), self.manage_models_overlay) GLib.idle_add(self.show_toast, _("Model '{}' pulled successfully.").format(model), self.manage_models_overlay)
GLib.idle_add(self.pulling_models[model]['overlay'].get_parent().get_parent().remove, self.pulling_models[model]['overlay'].get_parent()) elif response.status_code == 200 and self.pulling_models[model]['error']:
del self.pulling_models[model] GLib.idle_add(self.show_notification, _("Pull Model Error"), _("Failed to pull model '{}': {}").format(model, self.pulling_models[model]['error']), Gio.ThemedIcon.new("dialog-error-symbolic"))
GLib.idle_add(self.show_toast, _("Error pulling '{}': {}").format(model, self.pulling_models[model]['error']), self.manage_models_overlay)
else: else:
GLib.idle_add(self.show_notification, _("Pull Model Error"), _("Failed to pull model '{}' due to network error.").format(model), Gio.ThemedIcon.new("dialog-error-symbolic")) GLib.idle_add(self.show_notification, _("Pull Model Error"), _("Failed to pull model '{}' due to network error.").format(model), Gio.ThemedIcon.new("dialog-error-symbolic"))
GLib.idle_add(self.pulling_models[model]['overlay'].get_parent().get_parent().remove, self.pulling_models[model]['overlay'].get_parent()) GLib.idle_add(self.show_toast, _("Error pulling '{}'").format(model), self.manage_models_overlay)
del self.pulling_models[model]
GLib.idle_add(self.manage_models_dialog.close) GLib.idle_add(self.manage_models_dialog.close)
GLib.idle_add(self.connection_error) GLib.idle_add(self.connection_error)
GLib.idle_add(self.pulling_models[model]['overlay'].get_parent().get_parent().remove, self.pulling_models[model]['overlay'].get_parent())
del self.pulling_models[model]
if len(list(self.pulling_models.keys())) == 0: if len(list(self.pulling_models.keys())) == 0:
GLib.idle_add(self.pulling_model_list_box.set_visible, False) GLib.idle_add(self.pulling_model_list_box.set_visible, False)
def pull_model(self, model): def pull_model(self, model):
if model in list(self.pulling_models.keys()) or model in self.local_models or ":" not in model: return
logger.info("Pulling model") logger.info("Pulling model")
if model in list(self.pulling_models.keys()) or model in self.local_models:
return
self.pulling_model_list_box.set_visible(True) self.pulling_model_list_box.set_visible(True)
#self.pulling_model_list_box.connect('row_selected', lambda list_box, row: dialogs.stop_pull_model(self, row.get_name()) if row else None) #It isn't working for some reason #self.pulling_model_list_box.connect('row_selected', lambda list_box, row: dialogs.stop_pull_model(self, row.get_name()) if row else None) #It isn't working for some reason
model_name = self.convert_model_name(model, 0)
model_row = Adw.ActionRow( model_row = Adw.ActionRow(
title = "<b>{}</b> <small>{}</small>".format(model.split(":")[0].replace("-", " ").title(), model.split(":")[1]), title = "<b>{}</b> <small>{}</small>".format(model_name.split(" (")[0], model_name.split(" (")[1][:-1]),
name = model name = model
) )
thread = threading.Thread(target=self.pull_model_process, kwargs={"model": model, "modelfile": None}) thread = threading.Thread(target=self.pull_model_process, kwargs={"model": model, "modelfile": None})
@@ -1050,7 +1103,7 @@ Generate a title following these rules:
vexpand = False, vexpand = False,
valign = 3, valign = 3,
css_classes = ["error", "circular"], css_classes = ["error", "circular"],
tooltip_text = _("Stop Pulling '{} ({})'").format(model.split(':')[0].replace('-', ' ').title(), model.split(':')[1]) tooltip_text = _("Stop Pulling '{}'").format(model_name)
) )
button.connect("clicked", lambda button, model_name=model : dialogs.stop_pull_model(self, model_name)) button.connect("clicked", lambda button, model_name=model : dialogs.stop_pull_model(self, model_name))
model_row.add_suffix(button) model_row.add_suffix(button)
@@ -1118,7 +1171,7 @@ Generate a title following these rules:
if message['role'] == 'user': if message['role'] == 'user':
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, 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, id=key)
else: else:
self.show_message(message['content'], True, f"\n\n{message['model'].split(':')[0].replace('-', ' ').title()} ({message['model'].split(':')[1]})\n<small>{formated_date}</small>", id=key) self.show_message(message['content'], True, f"\n\n{self.convert_model_name(message['model'], 0)}\n<small>{formated_date}</small>", id=key)
self.add_code_blocks() self.add_code_blocks()
self.bot_message = None self.bot_message = None
@@ -1134,6 +1187,13 @@ Generate a title following these rules:
self.chats["order"] = [] self.chats["order"] = []
for chat_name in self.chats["chats"].keys(): for chat_name in self.chats["chats"].keys():
self.chats["order"].append(chat_name) 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)
break
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
self.chats = {"chats": {}, "selected_chat": None, "order": []} self.chats = {"chats": {}, "selected_chat": None, "order": []}
@@ -1554,6 +1614,7 @@ Generate a title following these rules:
self.get_application().create_action('import_chat', lambda *_: self.import_chat(), ['<primary>i']) self.get_application().create_action('import_chat', lambda *_: self.import_chat(), ['<primary>i'])
self.get_application().create_action('create_model_from_existing', lambda *_: dialogs.create_model_from_existing(self)) 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.get_application().create_action('create_model_from_file', lambda *_: dialogs.create_model_from_file(self))
self.get_application().create_action('create_model_from_name', lambda *_: dialogs.create_model_from_name(self))
self.get_application().create_action('delete_chat', self.chat_actions) self.get_application().create_action('delete_chat', self.chat_actions)
self.get_application().create_action('rename_chat', self.chat_actions) self.get_application().create_action('rename_chat', self.chat_actions)
self.get_application().create_action('rename_current_chat', self.current_chat_actions) self.get_application().create_action('rename_current_chat', self.current_chat_actions)
@@ -1593,7 +1654,7 @@ Generate a title following these rules:
#Support dialog #Support dialog
if 'show_support' not in data or data['show_support']: if 'show_support' not in data or data['show_support']:
if random.randint(0, 49) == 0: if random.randint(0, 49) == 0 or True:
dialogs.support(self) dialogs.support(self)
if 'show_support' in data: self.show_support = data['show_support'] if 'show_support' in data: self.show_support = data['show_support']
self.background_switch.set_active(self.run_on_background) self.background_switch.set_active(self.run_on_background)

View File

@@ -14,7 +14,6 @@
<object class="AdwBreakpoint"> <object class="AdwBreakpoint">
<condition>max-width: 800sp</condition> <condition>max-width: 800sp</condition>
<setter object="split_view_overlay" property="collapsed">true</setter> <setter object="split_view_overlay" property="collapsed">true</setter>
<setter object="show_sidebar_button" property="visible">true</setter>
</object> </object>
</child> </child>
<child> <child>
@@ -23,10 +22,8 @@
<object class="AdwBreakpoint"> <object class="AdwBreakpoint">
<condition>max-width: 500sp</condition> <condition>max-width: 500sp</condition>
<setter object="split_view_overlay" property="collapsed">true</setter> <setter object="split_view_overlay" property="collapsed">true</setter>
<setter object="show_sidebar_button" property="visible">true</setter>
<setter object="welcome_dialog" property="width-request">360</setter> <setter object="welcome_dialog" property="width-request">360</setter>
<setter object="manage_models_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> <setter object="preferences_dialog" property="width-request">360</setter>
<setter object="file_preview_dialog" property="width-request">360</setter> <setter object="file_preview_dialog" property="width-request">360</setter>
</object> </object>
@@ -80,7 +77,6 @@
<object class="AdwHeaderBar" id="header_bar"> <object class="AdwHeaderBar" id="header_bar">
<child type="start"> <child type="start">
<object class="GtkToggleButton" id="show_sidebar_button"> <object class="GtkToggleButton" id="show_sidebar_button">
<property name="visible">false</property>
<property name="icon-name">sidebar-show-symbolic</property> <property name="icon-name">sidebar-show-symbolic</property>
<property name="tooltip-text" translatable="yes">Toggle Sidebar</property> <property name="tooltip-text" translatable="yes">Toggle Sidebar</property>
<property name="active" bind-source="split_view_overlay" bind-property="show-sidebar" bind-flags="sync-create"/> <property name="active" bind-source="split_view_overlay" bind-property="show-sidebar" bind-flags="sync-create"/>
@@ -93,7 +89,7 @@
<child> <child>
<object class="GtkDropDown" id="model_drop_down"> <object class="GtkDropDown" id="model_drop_down">
<signal name="notify" handler="verify_if_image_can_be_used"/> <signal name="notify" handler="verify_if_image_can_be_used"/>
<property name="width-request">150</property> <property name="width-request">175</property>
<property name="enable-search">true</property> <property name="enable-search">true</property>
<property name="tooltip-text">Select Model</property> <property name="tooltip-text">Select Model</property>
<property name="model"> <property name="model">
@@ -217,6 +213,8 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="max-content-height">150</property> <property name="max-content-height">150</property>
<property name="propagate-natural-height">true</property> <property name="propagate-natural-height">true</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<style> <style>
<class name="message_input_scroll_window"/> <class name="message_input_scroll_window"/>
</style> </style>
@@ -226,8 +224,6 @@
<class name="message_text_view"/> <class name="message_text_view"/>
</style> </style>
<property name="wrap-mode">word</property> <property name="wrap-mode">word</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="top-margin">10</property> <property name="top-margin">10</property>
<property name="bottom-margin">10</property> <property name="bottom-margin">10</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
@@ -246,6 +242,7 @@
<style> <style>
<class name="accent"/> <class name="accent"/>
<class name="circular"/> <class name="circular"/>
<class name="suggested-action"/>
</style> </style>
<child> <child>
<object class="AdwButtonContent"> <object class="AdwButtonContent">
@@ -456,127 +453,6 @@
</child> </child>
</object> </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"/>
<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"> <object class="AdwDialog" id="manage_models_dialog">
<property name="can-close">true</property> <property name="can-close">true</property>
<property name="width-request">400</property> <property name="width-request">400</property>
@@ -730,6 +606,143 @@
</property> </property>
</object> </object>
</child> </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 type="start">
<object class="GtkButton">
<signal name="clicked" handler="link_button_handler"/>
<property name="icon-name">globe-symbolic</property>
</object>
</child>
</object>
</child>
<property name="content">
<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="sensitive">false</property>
<property name="subtitle"/>
<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="GtkBox">
<property name="height-request">140</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<style>
<class name="card"/>
</style>
<child>
<object class="GtkScrolledWindow">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<child>
<object class="GtkTextView" id="create_model_modelfile">
<style>
<class name="modelfile_textview"/>
</style>
<property name="wrap-mode">word</property>
<property name="top-margin">10</property>
<property name="bottom-margin">10</property>
<property name="hexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Some models require a modelfile, Alpaca fills FROM and SYSTEM (context) instructions automatically. Please visit the model's website or Ollama documentation for more information if you're unsure.</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="halign">1</property>
<property name="wrap">true</property>
<style>
<class name="caption"/>
</style>
</object>
</child>
</object>
</child>
<child>
<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>
</object>
</property>
</object>
</property>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
@@ -1085,9 +1098,13 @@ By downloading any model you accept their license agreement available on the mod
<attribute name="action">app.create_model_from_existing</attribute> <attribute name="action">app.create_model_from_existing</attribute>
</item> </item>
<item> <item>
<attribute name="label" translatable="yes">From GGUF File (Experimental)</attribute> <attribute name="label" translatable="yes">From GGUF File</attribute>
<attribute name="action">app.create_model_from_file</attribute> <attribute name="action">app.create_model_from_file</attribute>
</item> </item>
<item>
<attribute name="label" translatable="yes">From Name</attribute>
<attribute name="action">app.create_model_from_name</attribute>
</item>
</section> </section>
</menu> </menu>
<object class="GtkFileFilter" id="file_filter_attachments"> <object class="GtkFileFilter" id="file_filter_attachments">