From 6922529b786b9f39bb190ff36833ca396ee64277 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 30 May 2024 16:23:10 -0700 Subject: [PATCH 001/411] enh: keep originalContent --- src/lib/components/chat/Chat.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index e58d2cdc46..e0152bfc3c 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -626,7 +626,11 @@ if (res !== null) { // Update chat history with the new messages for (const message of res.messages) { - history.messages[message.id] = { ...history.messages[message.id], ...message }; + history.messages[message.id] = { + ...history.messages[message.id], + originalContent: history.messages[message.id].content, + ...message + }; } } } From e1d65065f5dc14c7b2c0ff6e54659e5fae792968 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 30 May 2024 16:31:55 -0700 Subject: [PATCH 002/411] fix --- src/lib/components/chat/Chat.svelte | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index e0152bfc3c..44080a288a 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -628,7 +628,9 @@ for (const message of res.messages) { history.messages[message.id] = { ...history.messages[message.id], - originalContent: history.messages[message.id].content, + ...(history.messages[message.id].content !== message.content + ? { originalContent: history.messages[message.id].content } + : {}), ...message }; } @@ -913,7 +915,13 @@ if (res !== null) { // Update chat history with the new messages for (const message of res.messages) { - history.messages[message.id] = { ...history.messages[message.id], ...message }; + history.messages[message.id] = { + ...history.messages[message.id], + ...(history.messages[message.id].content !== message.content + ? { originalContent: history.messages[message.id].content } + : {}), + ...message + }; } } } From 995f7bc51bf7a00f31b4c8841aafb3781ca69e21 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 30 May 2024 21:43:10 -0700 Subject: [PATCH 003/411] fix: chat completed --- backend/main.py | 10 ++++++++++ src/lib/components/chat/Chat.svelte | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/main.py b/backend/main.py index 3ffb5bdd7a..ea35ba2a16 100644 --- a/backend/main.py +++ b/backend/main.py @@ -271,6 +271,11 @@ class PipelineMiddleware(BaseHTTPMiddleware): except: pass + model = app.state.MODELS[model_id] + + if "pipeline" in model: + sorted_filters.append(model) + for filter in sorted_filters: r = None try: @@ -490,6 +495,11 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)): ] sorted_filters = sorted(filters, key=lambda x: x["pipeline"]["priority"]) + model = app.state.MODELS[model_id] + + if "pipeline" in model: + sorted_filters = [model] + sorted_filters + for filter in sorted_filters: r = None try: diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 44080a288a..348d79d75f 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -899,7 +899,7 @@ const messages = createMessagesList(responseMessageId); const res = await chatCompleted(localStorage.token, { - model: model, + model: model.id, messages: messages.map((m) => ({ id: m.id, role: m.role, From 9283ed168542356235793810e76e095634f82a23 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 02:11:25 -0700 Subject: [PATCH 004/411] feat: hide/unhide model from selector --- .../chat/ModelSelector/Selector.svelte | 8 +- .../icons/EllipsisHorizontal.svelte | 19 +++ src/lib/components/workspace/Models.svelte | 128 ++++++++-------- .../workspace/Models/ModelMenu.svelte | 142 ++++++++++++++++++ .../(app)/workspace/models/edit/+page.svelte | 4 +- 5 files changed, 231 insertions(+), 70 deletions(-) create mode 100644 src/lib/components/icons/EllipsisHorizontal.svelte create mode 100644 src/lib/components/workspace/Models/ModelMenu.svelte diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 96af8c763b..8507f7a21a 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -42,9 +42,11 @@ let searchValue = ''; let ollamaVersion = null; - $: filteredItems = searchValue - ? items.filter((item) => item.value.toLowerCase().includes(searchValue.toLowerCase())) - : items; + $: filteredItems = items.filter((item) => + searchValue + ? item.value.toLowerCase().includes(searchValue.toLowerCase()) + : true && !(item.model?.info?.meta?.hidden ?? false) + ); const pullModelHandler = async () => { const sanitizedModelTag = searchValue.trim().replace(/^ollama\s+(run|pull)\s+/, ''); diff --git a/src/lib/components/icons/EllipsisHorizontal.svelte b/src/lib/components/icons/EllipsisHorizontal.svelte new file mode 100644 index 0000000000..6a7d532e38 --- /dev/null +++ b/src/lib/components/icons/EllipsisHorizontal.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 7c4829e3ae..2fe8cef278 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -12,6 +12,8 @@ import { goto } from '$app/navigation'; import { getModels } from '$lib/apis'; + import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte'; + import ModelMenu from './Models/ModelMenu.svelte'; const i18n = getContext('i18n'); @@ -74,6 +76,41 @@ ); }; + const hideModelHandler = async (model) => { + let info = model.info; + + if (!info) { + info = { + id: model.id, + name: model.name, + meta: { + suggestion_prompts: null + }, + params: {} + }; + } + + info.meta = { + ...info.meta, + hidden: !(info?.meta?.hidden ?? false) + }; + + console.log(info); + + const res = await updateModelById(localStorage.token, info.id, info); + + if (res) { + toast.success( + $i18n.t(`Model {{name}} is now {{status}}`, { + name: info.id, + status: info.meta.hidden ? 'hidden' : 'visible' + }) + ); + } + + await models.set(await getModels(localStorage.token)); + }; + const downloadModels = async (models) => { let blob = new Blob([JSON.stringify(models)], { type: 'application/json' @@ -177,7 +214,11 @@ href={`/?models=${encodeURIComponent(model.id)}`} >
-
+
modelfile profile
-
+
{model.name}
{!!model?.info?.meta?.description ? model?.info?.meta?.description : model.id}
-
+
- - - - - + + +
{/each} diff --git a/src/lib/components/workspace/Models/ModelMenu.svelte b/src/lib/components/workspace/Models/ModelMenu.svelte new file mode 100644 index 0000000000..364893229a --- /dev/null +++ b/src/lib/components/workspace/Models/ModelMenu.svelte @@ -0,0 +1,142 @@ + + + { + if (e.detail === false) { + onClose(); + } + }} +> + + + + +
+ + { + shareHandler(); + }} + > + +
{$i18n.t('Share')}
+
+ + { + cloneHandler(); + }} + > + + + + +
{$i18n.t('Clone')}
+
+ + { + hideHandler(); + }} + > + {#if model?.info?.meta?.hidden ?? false} + + + + {:else} + + + + + {/if} + +
+ {$i18n.t(model?.info?.meta?.hidden ?? false ? 'Show Model' : 'Hide Model')} +
+
+ +
+ + { + deleteHandler(); + }} + > + +
{$i18n.t('Delete')}
+
+
+
+
diff --git a/src/routes/(app)/workspace/models/edit/+page.svelte b/src/routes/(app)/workspace/models/edit/+page.svelte index a2d5a7d76e..558ad36634 100644 --- a/src/routes/(app)/workspace/models/edit/+page.svelte +++ b/src/routes/(app)/workspace/models/edit/+page.svelte @@ -460,7 +460,7 @@
-
+
{$i18n.t('Capabilities')}
@@ -473,7 +473,7 @@ }} /> -
+
{$i18n.t(capability)}
From c999c86c5e22a5b083102efeea50194449978a6c Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 02:15:41 -0700 Subject: [PATCH 005/411] refac --- src/lib/components/chat/Messages/Placeholder.svelte | 2 +- src/lib/components/workspace/Models.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/Messages/Placeholder.svelte b/src/lib/components/chat/Messages/Placeholder.svelte index ed121dbe65..17beff50ed 100644 --- a/src/lib/components/chat/Messages/Placeholder.svelte +++ b/src/lib/components/chat/Messages/Placeholder.svelte @@ -64,7 +64,7 @@
- {#if models[selectedModelIdx]?.info} + {#if models[selectedModelIdx]?.info?.meta?.description ?? null}
{models[selectedModelIdx]?.info?.meta?.description}
diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 2fe8cef278..a920a3bc2c 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -216,7 +216,7 @@
Date: Fri, 31 May 2024 15:12:07 +0300 Subject: [PATCH 006/411] fix: incorrect translations fixed and new translations synced --- src/lib/i18n/locales/tr-TR/translation.json | 114 ++++++++++---------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index caa64ad800..0a0dc2638d 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -4,24 +4,24 @@ "(e.g. `sh webui.sh --api`)": "(örn. `sh webui.sh --api`)", "(latest)": "(en son)", "{{ models }}": "", - "{{ owner }}: You cannot delete a base model": "", + "{{ owner }}: You cannot delete a base model": "{{ owner }}: Temel modeli silemezsiniz", "{{modelName}} is thinking...": "{{modelName}} düşünüyor...", "{{user}}'s Chats": "{{user}} Sohbetleri", "{{webUIName}} Backend Required": "{{webUIName}} Arkayüz Gerekli", - "A task model is used when performing tasks such as generating titles for chats and web search queries": "", + "A task model is used when performing tasks such as generating titles for chats and web search queries": "Bir görev modeli, sohbetler ve web arama sorguları için başlık oluşturma gibi görevleri yerine getirirken kullanılır", "a user": "bir kullanıcı", "About": "Hakkında", "Account": "Hesap", "Accurate information": "Doğru bilgi", "Add": "Ekle", - "Add a model id": "", - "Add a short description about what this model does": "", + "Add a model id": "Model id ekle", + "Add a short description about what this model does": "Bu modelin ne yaptığı hakkında kısa bir açıklama ekle", "Add a short title for this prompt": "Bu prompt için kısa bir başlık ekleyin", "Add a tag": "Bir etiket ekleyin", "Add custom prompt": "Özel prompt ekle", "Add Docs": "Dökümanlar Ekle", "Add Files": "Dosyalar Ekle", - "Add Memory": "Yerelleştirme Ekle", + "Add Memory": "Bellek Ekle", "Add message": "Mesaj ekle", "Add Model": "Model Ekle", "Add Tags": "Etiketler ekle", @@ -31,7 +31,7 @@ "Admin Panel": "Yönetici Paneli", "Admin Settings": "Yönetici Ayarları", "Advanced Parameters": "Gelişmiş Parametreler", - "Advanced Params": "", + "Advanced Params": "Gelişmiş Parametreler", "all": "tümü", "All Documents": "Tüm Belgeler", "All Users": "Tüm Kullanıcılar", @@ -48,7 +48,7 @@ "API keys": "API anahtarları", "April": "Nisan", "Archive": "Arşiv", - "Archive All Chats": "", + "Archive All Chats": "Tüm Sohbetleri Arşivle", "Archived Chats": "Arşivlenmiş Sohbetler", "are allowed - Activate this command by typing": "izin verilir - Bu komutu yazarak etkinleştirin", "Are you sure?": "Emin misiniz?", @@ -63,13 +63,13 @@ "available!": "mevcut!", "Back": "Geri", "Bad Response": "Kötü Yanıt", - "Banners": "", - "Base Model (From)": "", + "Banners": "Afişler", + "Base Model (From)": "Temel Model ('den)", "before": "önce", "Being lazy": "Tembelleşiyor", "Bypass SSL verification for Websites": "Web Siteleri için SSL doğrulamasını atlayın", "Cancel": "İptal", - "Capabilities": "", + "Capabilities": "Yetenekler", "Change Password": "Parola Değiştir", "Chat": "Sohbet", "Chat Bubble UI": "Sohbet Balonu UI", @@ -111,7 +111,7 @@ "Copy Link": "Bağlantıyı Kopyala", "Copying to clipboard was successful!": "Panoya kopyalama başarılı!", "Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Aşağıdaki sorgu için başlık olarak 3-5 kelimelik kısa ve öz bir ifade oluşturun, 3-5 kelime sınırına kesinlikle uyun ve 'başlık' kelimesini kullanmaktan kaçının:", - "Create a model": "", + "Create a model": "Bir model oluştur", "Create Account": "Hesap Oluştur", "Create new key": "Yeni anahtar oluştur", "Create new secret key": "Yeni gizli anahtar oluştur", @@ -120,7 +120,7 @@ "Current Model": "Mevcut Model", "Current Password": "Mevcut Parola", "Custom": "Özel", - "Customize models for a specific purpose": "", + "Customize models for a specific purpose": "Modelleri belirli amaçlar için özelleştir", "Dark": "Koyu", "Database": "Veritabanı", "December": "Aralık", @@ -128,24 +128,24 @@ "Default (Automatic1111)": "Varsayılan (Automatic1111)", "Default (SentenceTransformers)": "Varsayılan (SentenceTransformers)", "Default (Web API)": "Varsayılan (Web API)", - "Default Model": "", + "Default Model": "Varsayılan Model", "Default model updated": "Varsayılan model güncellendi", "Default Prompt Suggestions": "Varsayılan Prompt Önerileri", "Default User Role": "Varsayılan Kullanıcı Rolü", "delete": "sil", "Delete": "Sil", "Delete a model": "Bir modeli sil", - "Delete All Chats": "", + "Delete All Chats": "Tüm Sohbetleri Sil", "Delete chat": "Sohbeti sil", "Delete Chat": "Sohbeti Sil", "delete this link": "bu bağlantıyı sil", "Delete User": "Kullanıcıyı Sil", "Deleted {{deleteModelTag}}": "{{deleteModelTag}} silindi", - "Deleted {{name}}": "", + "Deleted {{name}}": "{{name}} silindi", "Description": "Açıklama", "Didn't fully follow instructions": "Talimatları tam olarak takip etmedi", "Disabled": "Devre Dışı", - "Discover a model": "", + "Discover a model": "Bir model keşfedin", "Discover a prompt": "Bir prompt keşfedin", "Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin", "Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin", @@ -170,15 +170,15 @@ "Embedding Model Engine": "Gömme Modeli Motoru", "Embedding model set to \"{{embedding_model}}\"": "Gömme modeli \"{{embedding_model}}\" olarak ayarlandı", "Enable Chat History": "Sohbet Geçmişini Etkinleştir", - "Enable Community Sharing": "", + "Enable Community Sharing": "Topluluk Paylaşımını Etkinleştir", "Enable New Sign Ups": "Yeni Kayıtları Etkinleştir", "Enabled": "Etkin", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "CSV dosyanızın şu sırayla 4 sütun içerdiğinden emin olun: İsim, E-posta, Şifre, Rol.", "Enter {{role}} message here": "Buraya {{role}} mesajını girin", - "Enter a detail about yourself for your LLMs to recall": "LLM'lerin hatırlaması için kendiniz hakkında bir detay girin", + "Enter a detail about yourself for your LLMs to recall": "LLM'lerinizin hatırlaması için kendiniz hakkında bir bilgi girin", "Enter Chunk Overlap": "Chunk Örtüşmesini Girin", "Enter Chunk Size": "Chunk Boyutunu Girin", - "Enter Github Raw URL": "", + "Enter Github Raw URL": "Github Raw URL'sini girin", "Enter Image Size (e.g. 512x512)": "Görüntü Boyutunu Girin (örn. 512x512)", "Enter language codes": "Dil kodlarını girin", "Enter model tag (e.g. {{modelTag}})": "Model etiketini girin (örn. {{modelTag}})", @@ -192,12 +192,12 @@ "Enter Your Full Name": "Tam Adınızı Girin", "Enter Your Password": "Parolanızı Girin", "Enter Your Role": "Rolünüzü Girin", - "Error": "", + "Error": "Hata", "Experimental": "Deneysel", "Export All Chats (All Users)": "Tüm Sohbetleri Dışa Aktar (Tüm Kullanıcılar)", "Export Chats": "Sohbetleri Dışa Aktar", "Export Documents Mapping": "Belge Eşlemesini Dışa Aktar", - "Export Models": "", + "Export Models": "Modelleri Dışa Aktar", "Export Prompts": "Promptları Dışa Aktar", "Failed to create API Key.": "API Anahtarı oluşturulamadı.", "Failed to read clipboard contents": "Pano içeriği okunamadı", @@ -210,11 +210,11 @@ "Focus chat input": "Sohbet girişine odaklan", "Followed instructions perfectly": "Talimatları mükemmel şekilde takip etti", "Format your variables using square brackets like this:": "Değişkenlerinizi şu şekilde kare parantezlerle biçimlendirin:", - "Frequencey Penalty": "", + "Frequencey Penalty": "Frekans Cezası", "Full Screen Mode": "Tam Ekran Modu", "General": "Genel", "General Settings": "Genel Ayarlar", - "Generating search query": "", + "Generating search query": "Arama sorgusu oluşturma", "Generation Info": "Üretim Bilgisi", "Good Response": "İyi Yanıt", "h:mm a": "h:mm a", @@ -230,18 +230,18 @@ "Images": "Görüntüler", "Import Chats": "Sohbetleri İçe Aktar", "Import Documents Mapping": "Belge Eşlemesini İçe Aktar", - "Import Models": "", + "Import Models": "Modelleri İçe Aktar", "Import Prompts": "Promptları İçe Aktar", "Include `--api` flag when running stable-diffusion-webui": "stable-diffusion-webui çalıştırılırken `--api` bayrağını dahil edin", - "Info": "", + "Info": "Bilgi", "Input commands": "Giriş komutları", - "Install from Github URL": "", + "Install from Github URL": "Github URL'sinden yükleyin", "Interface": "Arayüz", "Invalid Tag": "Geçersiz etiket", "January": "Ocak", "join our Discord for help.": "yardım için Discord'umuza katılın.", "JSON": "JSON", - "JSON Preview": "", + "JSON Preview": "JSON Önizlemesi", "July": "Temmuz", "June": "Haziran", "JWT Expiration": "JWT Bitişi", @@ -258,14 +258,14 @@ "Make sure to enclose them with": "Değişkenlerinizi şu şekilde biçimlendirin:", "Manage Models": "Modelleri Yönet", "Manage Ollama Models": "Ollama Modellerini Yönet", - "Manage Pipelines": "", + "Manage Pipelines": "Pipeline'ları Yönet", "March": "Mart", - "Max Tokens (num_predict)": "", + "Max Tokens (num_predict)": "Maksimum Token (num_predict)", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Aynı anda en fazla 3 model indirilebilir. Lütfen daha sonra tekrar deneyin.", "May": "Mayıs", - "Memories accessible by LLMs will be shown here.": "LLM'ler tarafından erişilebilecek hatalar burada gösterilecektir.", - "Memory": "Hatalar", - "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Bağlantınızı oluşturduktan sonra gönderdiğiniz mesajlar paylaşılmaz. URL'ye sahip kullanıcılar paylaşılan sohbeti görüntüleyebilir.", + "Memories accessible by LLMs will be shown here.": "LLM'ler tarafından erişilebilen bellekler burada gösterilecektir.", + "Memory": "Bellek", + "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Bağlantınızı oluşturduktan sonra gönderdiğiniz mesajlar paylaşılmayacaktır. URL'ye sahip kullanıcılar paylaşılan sohbeti görüntüleyebilecektir.", "Minimum Score": "Minimum Skor", "Mirostat": "Mirostat", "Mirostat Eta": "Mirostat Eta", @@ -275,11 +275,11 @@ "Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' başarıyla indirildi.", "Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' zaten indirme sırasında.", "Model {{modelId}} not found": "{{modelId}} bulunamadı", - "Model {{modelName}} is not vision capable": "", + "Model {{modelName}} is not vision capable": "Model {{modelName}} görüntü yeteneğine sahip değil", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Model dosya sistemi yolu algılandı. Güncelleme için model kısa adı gerekli, devam edilemiyor.", - "Model ID": "", + "Model ID": "Model ID", "Model not selected": "Model seçilmedi", - "Model Params": "", + "Model Params": "Model Parametreleri", "Model Whitelisting": "Model Beyaz Listeye Alma", "Model(s) Whitelisted": "Model(ler) Beyaz Listeye Alındı", "Modelfile Content": "Model Dosyası İçeriği", @@ -287,14 +287,14 @@ "More": "Daha Fazla", "Name": "Ad", "Name Tag": "Ad Etiketi", - "Name your model": "", + "Name your model": "Modelinizi Adlandırın", "New Chat": "Yeni Sohbet", "New Password": "Yeni Parola", "No results found": "Sonuç bulunamadı", - "No search query generated": "", - "No search results found": "", + "No search query generated": "Hiç arama sorgusu oluşturulmadı", + "No search results found": "Hiç arama sonucu bulunmadı", "No source available": "Kaynak mevcut değil", - "None": "", + "None": "Yok", "Not factually correct": "Gerçeklere göre doğru değil", "Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Not: Minimum bir skor belirlerseniz, arama yalnızca minimum skora eşit veya daha yüksek bir skora sahip belgeleri getirecektir.", "Notifications": "Bildirimler", @@ -304,7 +304,7 @@ "Okay, Let's Go!": "Tamam, Hadi Başlayalım!", "OLED Dark": "OLED Koyu", "Ollama": "Ollama", - "Ollama API": "", + "Ollama API": "Ollama API", "Ollama Version": "Ollama Sürümü", "On": "Açık", "Only": "Yalnızca", @@ -328,7 +328,7 @@ "PDF Extract Images (OCR)": "PDF Görüntülerini Çıkart (OCR)", "pending": "beklemede", "Permission denied when accessing microphone: {{error}}": "Mikrofona erişim izni reddedildi: {{error}}", - "Personalization": "Kullanıcı Özelleştirme", + "Personalization": "Kişiselleştirme", "Pipelines": "", "Pipelines Valves": "", "Plain text (.txt)": "Düz metin (.txt)", @@ -375,24 +375,24 @@ "Scan for documents from {{path}}": "{{path}} dizininden belgeleri tarayın", "Search": "Ara", "Search a model": "Bir model ara", - "Search Chats": "", + "Search Chats": "Sohbetleri Ara", "Search Documents": "Belgeleri Ara", - "Search Models": "", + "Search Models": "Modelleri Ara", "Search Prompts": "Prompt Ara", - "Searched {{count}} sites_one": "", - "Searched {{count}} sites_other": "", - "Searching the web for '{{searchQuery}}'": "", + "Searched {{count}} sites_one": "Arandı {{count}} sites_one", + "Searched {{count}} sites_other": "Arandı {{count}} sites_other", + "Searching the web for '{{searchQuery}}'": "Web'de '{{searchQuery}}' aranıyor", "See readme.md for instructions": "Yönergeler için readme.md dosyasına bakın", "See what's new": "Yeniliklere göz atın", "Seed": "Seed", - "Select a base model": "", + "Select a base model": "Bir temel model seç", "Select a mode": "Bir mod seç", "Select a model": "Bir model seç", - "Select a pipeline": "", - "Select a pipeline url": "", + "Select a pipeline": "Bir pipeline seç", + "Select a pipeline url": "Bir pipeline URL'si seç", "Select an Ollama instance": "Bir Ollama örneği seçin", "Select model": "Model seç", - "Selected model(s) do not support image inputs": "", + "Selected model(s) do not support image inputs": "Seçilen model(ler) görüntü girişlerini desteklemiyor", "Send": "Gönder", "Send a Message": "Bir Mesaj Gönder", "Send message": "Mesaj gönder", @@ -402,10 +402,10 @@ "Set Default Model": "Varsayılan Modeli Ayarla", "Set embedding model (e.g. {{model}})": "Gömme modelini ayarlayın (örn. {{model}})", "Set Image Size": "Görüntü Boyutunu Ayarla", - "Set Model": "Model Ayarla", + "Set Model": "Modeli Ayarla", "Set reranking model (e.g. {{model}})": "Yeniden sıralama modelini ayarlayın (örn. {{model}})", "Set Steps": "Adımları Ayarla", - "Set Task Model": "", + "Set Task Model": "Görev Modeli Ayarla", "Set Voice": "Ses Ayarla", "Settings": "Ayarlar", "Settings saved successfully!": "Ayarlar başarıyla kaydedildi!", @@ -471,7 +471,7 @@ "Update and Copy Link": "Güncelle ve Bağlantıyı Kopyala", "Update password": "Parolayı Güncelle", "Upload a GGUF model": "Bir GGUF modeli yükle", - "Upload Files": "", + "Upload Files": "Dosyaları Yükle", "Upload Progress": "Yükleme İlerlemesi", "URL Mode": "URL Modu", "Use '#' in the prompt input to load and select your documents.": "Belgelerinizi yüklemek ve seçmek için promptda '#' kullanın.", @@ -485,12 +485,12 @@ "variable": "değişken", "variable to have them replaced with clipboard content.": "panodaki içerikle değiştirilmesi için değişken.", "Version": "Sürüm", - "Warning": "", + "Warning": "Uyarı", "Warning: If you update or change your embedding model, you will need to re-import all documents.": "Uyarı: Gömme modelinizi günceller veya değiştirirseniz, tüm belgeleri yeniden içe aktarmanız gerekecektir.", "Web": "Web", "Web Loader Settings": "Web Yükleyici Ayarları", "Web Params": "Web Parametreleri", - "Web Search": "", + "Web Search": "Web Araması", "Webhook URL": "Webhook URL", "WebUI Add-ons": "WebUI Eklentileri", "WebUI Settings": "WebUI Ayarları", @@ -503,11 +503,11 @@ "Write a summary in 50 words that summarizes [topic or keyword].": "[Konuyu veya anahtar kelimeyi] özetleyen 50 kelimelik bir özet yazın.", "Yesterday": "Dün", "You": "Sen", - "You cannot clone a base model": "", + "You cannot clone a base model": "Bir temel modeli klonlayamazsınız", "You have no archived conversations.": "Arşivlenmiş sohbetleriniz yok.", "You have shared this chat": "Bu sohbeti paylaştınız", "You're a helpful assistant.": "Sen yardımcı bir asistansın.", - "You're now logged in.": "Şimdi oturum açtınız.", + "You're now logged in.": "Şimdi giriş yaptınız.", "Youtube": "Youtube", "Youtube Loader Settings": "Youtube Yükleyici Ayarları" } From 36e2a5e6747345cf4dd09063a4890bcb85b1e808 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 31 May 2024 11:48:56 -0500 Subject: [PATCH 007/411] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..f257663f7e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,75 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contribute to a positive environment for our community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission +- **Spamming of any kind** +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all community spaces and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, spamming, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at hello@openwebui.com. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Temporary Ban + +**Community Impact**: Any violation of community standards, including but not limited to inappropriate language, unprofessional behavior, harassment, or spamming. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 2. Permanent Ban + +**Community Impact**: Repeated or severe violations of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. From 7674229e3af606bba258479e321f9b5163b7a289 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 10:30:42 -0700 Subject: [PATCH 008/411] feat: chat clone --- backend/apps/webui/routers/chats.py | 26 +++++++++++++ src/lib/apis/chats/index.ts | 38 +++++++++++++++++++ .../components/icons/DocumentDuplicate.svelte | 19 ++++++++++ src/lib/components/layout/Sidebar.svelte | 18 ++++++++- .../components/layout/Sidebar/ChatMenu.svelte | 34 +++++++++++------ .../workspace/Models/ModelMenu.svelte | 16 +------- 6 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 src/lib/components/icons/DocumentDuplicate.svelte diff --git a/backend/apps/webui/routers/chats.py b/backend/apps/webui/routers/chats.py index 5d52f40c96..e7d176fd25 100644 --- a/backend/apps/webui/routers/chats.py +++ b/backend/apps/webui/routers/chats.py @@ -288,6 +288,32 @@ async def delete_chat_by_id(request: Request, id: str, user=Depends(get_current_ return result +############################ +# CloneChat +############################ + + +@router.get("/{id}/clone", response_model=Optional[ChatResponse]) +async def clone_chat_by_id(id: str, user=Depends(get_current_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + + chat_body = json.loads(chat.chat) + updated_chat = { + **chat_body, + "originalChatId": chat.id, + "branchPointMessageId": chat_body["history"]["currentId"], + "title": f"Clone of {chat.title}", + } + + chat = Chats.insert_new_chat(user.id, ChatForm(**{"chat": updated_chat})) + return ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)}) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + ############################ # ArchiveChat ############################ diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index 834e29d296..648e3580e1 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -325,6 +325,44 @@ export const getChatByShareId = async (token: string, share_id: string) => { return res; }; +export const cloneChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const shareChatById = async (token: string, id: string) => { let error = null; diff --git a/src/lib/components/icons/DocumentDuplicate.svelte b/src/lib/components/icons/DocumentDuplicate.svelte new file mode 100644 index 0000000000..a208fefc8a --- /dev/null +++ b/src/lib/components/icons/DocumentDuplicate.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index c746e343ab..0bf00e4722 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -22,7 +22,8 @@ getChatListByTagName, updateChatById, getAllChatTags, - archiveChatById + archiveChatById, + cloneChatById } from '$lib/apis/chats'; import { toast } from 'svelte-sonner'; import { fade, slide } from 'svelte/transition'; @@ -182,6 +183,18 @@ } }; + const cloneChatHandler = async (id) => { + const res = await cloneChatById(localStorage.token, id).catch((error) => { + toast.error(error); + return null; + }); + + if (res) { + goto(`/c/${res.id}`); + await chats.set(await getChatList(localStorage.token)); + } + }; + const saveSettings = async (updated) => { await settings.set({ ...$settings, ...updated }); await updateUserSettings(localStorage.token, { ui: $settings }); @@ -601,6 +614,9 @@
{ + cloneChatHandler(chat.id); + }} shareHandler={() => { shareChatId = selectedChatId; showShareChatModal = true; diff --git a/src/lib/components/layout/Sidebar/ChatMenu.svelte b/src/lib/components/layout/Sidebar/ChatMenu.svelte index a47502a411..db264f3524 100644 --- a/src/lib/components/layout/Sidebar/ChatMenu.svelte +++ b/src/lib/components/layout/Sidebar/ChatMenu.svelte @@ -10,10 +10,12 @@ import Tags from '$lib/components/chat/Tags.svelte'; import Share from '$lib/components/icons/Share.svelte'; import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte'; + import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte'; const i18n = getContext('i18n'); export let shareHandler: Function; + export let cloneChatHandler: Function; export let archiveChatHandler: Function; export let renameHandler: Function; export let deleteHandler: Function; @@ -38,22 +40,12 @@
- { - shareHandler(); - }} - > - -
{$i18n.t('Share')}
-
- { @@ -64,6 +56,16 @@
{$i18n.t('Rename')}
+ { + cloneChatHandler(); + }} + > + +
{$i18n.t('Clone')}
+
+ { @@ -74,6 +76,16 @@
{$i18n.t('Archive')}
+ { + shareHandler(); + }} + > + +
{$i18n.t('Share')}
+
+ { diff --git a/src/lib/components/workspace/Models/ModelMenu.svelte b/src/lib/components/workspace/Models/ModelMenu.svelte index 364893229a..bde54e7097 100644 --- a/src/lib/components/workspace/Models/ModelMenu.svelte +++ b/src/lib/components/workspace/Models/ModelMenu.svelte @@ -10,6 +10,7 @@ import Tags from '$lib/components/chat/Tags.svelte'; import Share from '$lib/components/icons/Share.svelte'; import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte'; + import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte'; const i18n = getContext('i18n'); @@ -60,20 +61,7 @@ cloneHandler(); }} > - - - +
{$i18n.t('Clone')}
From 9dfa334a8344cd45a6cdc7704b60c97e498cee0f Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 11:11:28 -0700 Subject: [PATCH 009/411] feat: CURRENT_DATE, USER_NAME prompt variable support --- src/lib/apis/ollama/index.ts | 4 +-- src/lib/apis/openai/index.ts | 4 +-- src/lib/components/chat/Chat.svelte | 14 ++++++--- src/lib/utils/index.test.ts | 34 +++++++++++----------- src/lib/utils/index.ts | 44 +++++++++++++++++++++++++++-- 5 files changed, 73 insertions(+), 27 deletions(-) diff --git a/src/lib/apis/ollama/index.ts b/src/lib/apis/ollama/index.ts index 7bd0ed20a1..5ab2363cbb 100644 --- a/src/lib/apis/ollama/index.ts +++ b/src/lib/apis/ollama/index.ts @@ -1,5 +1,5 @@ import { OLLAMA_API_BASE_URL } from '$lib/constants'; -import { promptTemplate } from '$lib/utils'; +import { titleGenerationTemplate } from '$lib/utils'; export const getOllamaConfig = async (token: string = '') => { let error = null; @@ -212,7 +212,7 @@ export const generateTitle = async ( ) => { let error = null; - template = promptTemplate(template, prompt); + template = titleGenerationTemplate(template, prompt); console.log(template); diff --git a/src/lib/apis/openai/index.ts b/src/lib/apis/openai/index.ts index ddeab495ca..fc9365d128 100644 --- a/src/lib/apis/openai/index.ts +++ b/src/lib/apis/openai/index.ts @@ -1,5 +1,5 @@ import { OPENAI_API_BASE_URL } from '$lib/constants'; -import { promptTemplate } from '$lib/utils'; +import { titleGenerationTemplate } from '$lib/utils'; import { type Model, models, settings } from '$lib/stores'; export const getOpenAIConfig = async (token: string = '') => { @@ -340,7 +340,7 @@ export const generateTitle = async ( ) => { let error = null; - template = promptTemplate(template, prompt); + template = titleGenerationTemplate(template, prompt); console.log(template); diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 348d79d75f..ab1b482de9 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -16,9 +16,15 @@ showSidebar, tags as _tags, WEBUI_NAME, - banners + banners, + user } from '$lib/stores'; - import { convertMessagesToHistory, copyToClipboard, splitStream } from '$lib/utils'; + import { + convertMessagesToHistory, + copyToClipboard, + promptTemplate, + splitStream + } from '$lib/utils'; import { cancelOllamaRequest, generateChatCompletion } from '$lib/apis/ollama'; import { @@ -515,7 +521,7 @@ $settings.system || (responseMessage?.userContext ?? null) ? { role: 'system', - content: `${$settings?.system ?? ''}${ + content: `${promptTemplate($settings?.system ?? '', $user.name)}${ responseMessage?.userContext ?? null ? `\n\nUser Context:\n${(responseMessage?.userContext ?? []).join('\n')}` : '' @@ -816,7 +822,7 @@ $settings.system || (responseMessage?.userContext ?? null) ? { role: 'system', - content: `${$settings?.system ?? ''}${ + content: `${promptTemplate($settings?.system ?? '', $user.name)}${ responseMessage?.userContext ?? null ? `\n\nUser Context:\n${(responseMessage?.userContext ?? []).join('\n')}` : '' diff --git a/src/lib/utils/index.test.ts b/src/lib/utils/index.test.ts index f67449dcc7..f69ef22601 100644 --- a/src/lib/utils/index.test.ts +++ b/src/lib/utils/index.test.ts @@ -1,66 +1,66 @@ -import { promptTemplate } from '$lib/utils/index'; +import { titleGenerationTemplate } from '$lib/utils/index'; import { expect, test } from 'vitest'; -test('promptTemplate correctly replaces {{prompt}} placeholder', () => { +test('titleGenerationTemplate correctly replaces {{prompt}} placeholder', () => { const template = 'Hello {{prompt}}!'; const prompt = 'world'; const expected = 'Hello world!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate correctly replaces {{prompt:start:}} placeholder', () => { +test('titleGenerationTemplate correctly replaces {{prompt:start:}} placeholder', () => { const template = 'Hello {{prompt:start:3}}!'; const prompt = 'world'; const expected = 'Hello wor!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate correctly replaces {{prompt:end:}} placeholder', () => { +test('titleGenerationTemplate correctly replaces {{prompt:end:}} placeholder', () => { const template = 'Hello {{prompt:end:3}}!'; const prompt = 'world'; const expected = 'Hello rld!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate correctly replaces {{prompt:middletruncate:}} placeholder when prompt length is greater than length', () => { +test('titleGenerationTemplate correctly replaces {{prompt:middletruncate:}} placeholder when prompt length is greater than length', () => { const template = 'Hello {{prompt:middletruncate:4}}!'; const prompt = 'world'; const expected = 'Hello wo...ld!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate correctly replaces {{prompt:middletruncate:}} placeholder when prompt length is less than or equal to length', () => { +test('titleGenerationTemplate correctly replaces {{prompt:middletruncate:}} placeholder when prompt length is less than or equal to length', () => { const template = 'Hello {{prompt:middletruncate:5}}!'; const prompt = 'world'; const expected = 'Hello world!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate returns original template when no placeholders are present', () => { +test('titleGenerationTemplate returns original template when no placeholders are present', () => { const template = 'Hello world!'; const prompt = 'world'; const expected = 'Hello world!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate does not replace placeholders inside of replaced placeholders', () => { +test('titleGenerationTemplate does not replace placeholders inside of replaced placeholders', () => { const template = 'Hello {{prompt}}!'; const prompt = 'World, {{prompt}} injection'; const expected = 'Hello World, {{prompt}} injection!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); -test('promptTemplate correctly replaces multiple placeholders', () => { +test('titleGenerationTemplate correctly replaces multiple placeholders', () => { const template = 'Hello {{prompt}}! This is {{prompt:start:3}}!'; const prompt = 'world'; const expected = 'Hello world! This is wor!'; - const actual = promptTemplate(template, prompt); + const actual = titleGenerationTemplate(template, prompt); expect(actual).toBe(expected); }); diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 8594ff8c9d..15ac73f1b2 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -449,6 +449,42 @@ export const blobToFile = (blob, fileName) => { return file; }; +/** + * @param {string} template - The template string containing placeholders. + * @returns {string} The template string with the placeholders replaced by the prompt. + */ +export const promptTemplate = ( + template: string, + user_name?: string, + current_location?: string +): string => { + // Get the current date + const currentDate = new Date(); + + // Format the date to YYYY-MM-DD + const formattedDate = + currentDate.getFullYear() + + '-' + + String(currentDate.getMonth() + 1).padStart(2, '0') + + '-' + + String(currentDate.getDate()).padStart(2, '0'); + + // Replace {{CURRENT_DATE}} in the template with the formatted date + template = template.replace('{{CURRENT_DATE}}', formattedDate); + + if (user_name) { + // Replace {{USER_NAME}} in the template with the user's name + template = template.replace('{{USER_NAME}}', user_name); + } + + if (current_location) { + // Replace {{CURRENT_LOCATION}} in the template with the current location + template = template.replace('{{CURRENT_LOCATION}}', current_location); + } + + return template; +}; + /** * This function is used to replace placeholders in a template string with the provided prompt. * The placeholders can be in the following formats: @@ -461,8 +497,8 @@ export const blobToFile = (blob, fileName) => { * @param {string} prompt - The string to replace the placeholders with. * @returns {string} The template string with the placeholders replaced by the prompt. */ -export const promptTemplate = (template: string, prompt: string): string => { - return template.replace( +export const titleGenerationTemplate = (template: string, prompt: string): string => { + template = template.replace( /{{prompt}}|{{prompt:start:(\d+)}}|{{prompt:end:(\d+)}}|{{prompt:middletruncate:(\d+)}}/g, (match, startLength, endLength, middleLength) => { if (match === '{{prompt}}') { @@ -482,6 +518,10 @@ export const promptTemplate = (template: string, prompt: string): string => { return ''; } ); + + template = promptTemplate(template); + + return template; }; export const approximateToHumanReadable = (nanoseconds: number) => { From 0cf9b07ec2d29d89fd59f792c569a117ce5d61aa Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 11:24:24 -0700 Subject: [PATCH 010/411] refac: model list styling --- src/lib/components/workspace/Models.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index a920a3bc2c..8151df8876 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -210,10 +210,10 @@ class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl" > -
+
-
{model.name}
-
+
{model.name}
+
{!!model?.info?.meta?.description ? model?.info?.meta?.description : model.id}
From eca20b1b2c2f805e1ea49d727f6fb6f31788411c Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 12:08:25 -0700 Subject: [PATCH 011/411] feat: model tag support --- src/lib/components/common/Banner.svelte | 2 +- src/lib/components/common/Dropdown.svelte | 1 + src/lib/components/common/Tags.svelte | 2 +- .../components/common/Tags/TagInput.svelte | 38 ++++---- src/lib/components/common/Tags/TagList.svelte | 7 +- .../workspace/models/create/+page.svelte | 70 ++++++++++++--- .../(app)/workspace/models/edit/+page.svelte | 89 ++++++++++++++----- 7 files changed, 155 insertions(+), 54 deletions(-) diff --git a/src/lib/components/common/Banner.svelte b/src/lib/components/common/Banner.svelte index 6599505149..64a7a2054f 100644 --- a/src/lib/components/common/Banner.svelte +++ b/src/lib/components/common/Banner.svelte @@ -39,7 +39,7 @@ {#if !dismissed} {#if mounted}
diff --git a/src/lib/components/common/Dropdown.svelte b/src/lib/components/common/Dropdown.svelte index 4beb1d26c6..e8e1eb8b5a 100644 --- a/src/lib/components/common/Dropdown.svelte +++ b/src/lib/components/common/Dropdown.svelte @@ -14,6 +14,7 @@ onOpenChange={(state) => { dispatch('change', state); }} + typeahead={false} > diff --git a/src/lib/components/common/Tags.svelte b/src/lib/components/common/Tags.svelte index c3eb3c99f8..bc1e7b5b38 100644 --- a/src/lib/components/common/Tags.svelte +++ b/src/lib/components/common/Tags.svelte @@ -11,7 +11,7 @@ export let addTag: Function; -
+
{ diff --git a/src/lib/components/common/Tags/TagInput.svelte b/src/lib/components/common/Tags/TagInput.svelte index 31fe581a52..c583c897b7 100644 --- a/src/lib/components/common/Tags/TagInput.svelte +++ b/src/lib/components/common/Tags/TagInput.svelte @@ -22,26 +22,12 @@ }; -
+
{#if showTagInput}
- { @@ -55,11 +41,27 @@
{/if} {#if label && !showTagInput} - {label} + {label} {/if}
diff --git a/src/lib/components/common/Tags/TagList.svelte b/src/lib/components/common/Tags/TagList.svelte index 09773a2dc4..f1a23f6dc7 100644 --- a/src/lib/components/common/Tags/TagList.svelte +++ b/src/lib/components/common/Tags/TagList.svelte @@ -7,22 +7,23 @@ {#each tags as tag}
{tag.name}
-
-
{$i18n.t('Description')}
+
+
+
{$i18n.t('Description')}
-
+ +
+ + {#if info.meta.description !== null} -
+ {/if}
+
+
{$i18n.t('Model Params')}
@@ -401,7 +424,9 @@
-
+
+ +
{$i18n.t('Prompt suggestions')}
@@ -491,8 +516,8 @@ {/if}
-
-
+
+
{$i18n.t('Capabilities')}
@@ -505,7 +530,7 @@ }} /> -
+
{$i18n.t(capability)}
@@ -513,7 +538,30 @@
-
+
+
+
{$i18n.t('Tags')}
+
+ +
+ { + info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName); + }} + addTag={(tagName) => { + console.log(tagName); + if (!(info?.meta?.tags ?? null)) { + info.meta.tags = [{ name: tagName }]; + } else { + info.meta.tags = [...info.meta.tags, { name: tagName }]; + } + }} + /> +
+
+ +
{$i18n.t('JSON Preview')}
diff --git a/src/routes/(app)/workspace/models/edit/+page.svelte b/src/routes/(app)/workspace/models/edit/+page.svelte index 558ad36634..169d439fa1 100644 --- a/src/routes/(app)/workspace/models/edit/+page.svelte +++ b/src/routes/(app)/workspace/models/edit/+page.svelte @@ -13,6 +13,7 @@ import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte'; import { getModels } from '$lib/apis'; import Checkbox from '$lib/components/common/Checkbox.svelte'; + import Tags from '$lib/components/common/Tags.svelte'; const i18n = getContext('i18n'); @@ -44,7 +45,8 @@ meta: { profile_image_url: '/favicon.png', description: '', - suggestion_prompts: null + suggestion_prompts: null, + tags: [] }, params: { system: '' @@ -223,26 +225,26 @@
-
+
-
{$i18n.t('Name')}*
+
{$i18n.t('Name')}*
-
{$i18n.t('Model ID')}*
+
{$i18n.t('Model ID')}*
{#if model.preset} -
-
{$i18n.t('Base Model (From)')}
+
+
{$i18n.t('Base Model (From)')}
-
+ {/if}
+
+
{$i18n.t('Model Params')}
@@ -369,7 +393,9 @@
-
+
+ +
{$i18n.t('Prompt suggestions')}
@@ -459,7 +485,7 @@ {/if}
-
+
{$i18n.t('Capabilities')}
@@ -481,7 +507,30 @@
-
+
+
+
{$i18n.t('Tags')}
+
+ +
+ { + info.meta.tags = info.meta.tags.filter((tag) => tag.name !== tagName); + }} + addTag={(tagName) => { + console.log(tagName); + if (!(info?.meta?.tags ?? null)) { + info.meta.tags = [{ name: tagName }]; + } else { + info.meta.tags = [...info.meta.tags, { name: tagName }]; + } + }} + /> +
+
+ +
{$i18n.t('JSON Preview')}
From cddbeb023da5433d09256f50934f19247068aef1 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 12:23:29 -0700 Subject: [PATCH 012/411] feat: model selector tag search --- .../chat/ModelSelector/Selector.svelte | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 8507f7a21a..3bd02c7621 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -42,10 +42,14 @@ let searchValue = ''; let ollamaVersion = null; - $: filteredItems = items.filter((item) => - searchValue - ? item.value.toLowerCase().includes(searchValue.toLowerCase()) - : true && !(item.model?.info?.meta?.hidden ?? false) + $: filteredItems = items.filter( + (item) => + (searchValue + ? item.value.toLowerCase().includes(searchValue.toLowerCase()) || + (item.model?.info?.meta?.tags ?? []).some((tag) => + tag.name.toLowerCase().includes(searchValue.toLowerCase()) + ) + : true) && !(item.model?.info?.meta?.hidden ?? false) ); const pullModelHandler = async () => { @@ -324,10 +328,22 @@
{/if} + + {#if (item?.model?.info?.meta?.tags ?? []).length > 0} +
+ {#each item.model?.info?.meta.tags as tag} +
+ {tag.name} +
+ {/each} +
+ {/if}
{#if value === item.value} -
+
{/if} From 9c67a94542d75b3b5a634cc6e107f1c5fa405e74 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 12:26:49 -0700 Subject: [PATCH 013/411] refac: styling --- .../chat/ModelSelector/Selector.svelte | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 3bd02c7621..7fcc3b5b4f 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -278,6 +278,18 @@ {/if}
+ {#if (item?.model?.info?.meta?.tags ?? []).length > 0} +
+ {#each item.model?.info?.meta.tags as tag} +
+ {tag.name} +
+ {/each} +
+ {/if} + {#if item.model.owned_by === 'openai'} @@ -328,18 +340,6 @@
{/if} - - {#if (item?.model?.info?.meta?.tags ?? []).length > 0} -
- {#each item.model?.info?.meta.tags as tag} -
- {tag.name} -
- {/each} -
- {/if}
{#if value === item.value} From fc2b314c4f12a2481dde31f00f5e6269b8dfa5ff Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 13:11:04 -0700 Subject: [PATCH 014/411] feat: model ordering --- package-lock.json | 6 +++ package.json | 1 + src/lib/apis/index.ts | 22 ++++++-- src/lib/components/workspace/Models.svelte | 62 ++++++++++++++++++++-- 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5f969e59d7..93a3ec6647 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "katex": "^0.16.9", "marked": "^9.1.0", "pyodide": "^0.26.0-alpha.4", + "sortablejs": "^1.15.2", "svelte-sonner": "^0.3.19", "tippy.js": "^6.3.7", "uuid": "^9.0.1" @@ -6913,6 +6914,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sortablejs": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz", + "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==" + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", diff --git a/package.json b/package.json index 3f5b5cb6d2..b1a6ecd33a 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "katex": "^0.16.9", "marked": "^9.1.0", "pyodide": "^0.26.0-alpha.4", + "sortablejs": "^1.15.2", "svelte-sonner": "^0.3.19", "tippy.js": "^6.3.7", "uuid": "^9.0.1" diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts index 63a0c21b95..f6b2de4d0d 100644 --- a/src/lib/apis/index.ts +++ b/src/lib/apis/index.ts @@ -29,8 +29,24 @@ export const getModels = async (token: string = '') => { models = models .filter((models) => models) + // Sort the models .sort((a, b) => { - // Compare case-insensitively + // Check if models have position property + const aHasPosition = a.info?.meta?.position !== undefined; + const bHasPosition = b.info?.meta?.position !== undefined; + + // If both a and b have the position property + if (aHasPosition && bHasPosition) { + return a.info.meta.position - b.info.meta.position; + } + + // If only a has the position property, it should come first + if (aHasPosition) return -1; + + // If only b has the position property, it should come first + if (bHasPosition) return 1; + + // Compare case-insensitively by name for models without position property const lowerA = a.name.toLowerCase(); const lowerB = b.name.toLowerCase(); @@ -39,8 +55,8 @@ export const getModels = async (token: string = '') => { // If same case-insensitively, sort by original strings, // lowercase will come before uppercase due to ASCII values - if (a < b) return -1; - if (a > b) return 1; + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; return 0; // They are equal }); diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 8151df8876..43f0cad67d 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -1,9 +1,11 @@ @@ -202,12 +255,13 @@
-
- {#each $models.filter((m) => searchValue === '' || m.name +
+ {#each _models.filter((m) => searchValue === '' || m.name .toLowerCase() .includes(searchValue.toLowerCase())) as model}
Date: Fri, 31 May 2024 13:30:12 -0700 Subject: [PATCH 015/411] fix: pipelines --- backend/apps/openai/main.py | 5 ----- backend/main.py | 8 ++++++-- src/lib/apis/openai/index.ts | 5 ++++- src/lib/components/chat/Chat.svelte | 1 + 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/backend/apps/openai/main.py b/backend/apps/openai/main.py index 9bf76818fd..6a83476281 100644 --- a/backend/apps/openai/main.py +++ b/backend/apps/openai/main.py @@ -400,11 +400,6 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)): if "pipeline" in model and model.get("pipeline"): payload["user"] = {"name": user.name, "id": user.id} - payload["title"] = ( - True - if payload["stream"] == False and payload["max_tokens"] == 50 - else False - ) # Check if the model is "gpt-4-vision-preview" and set "max_tokens" to 4000 # This is a workaround until OpenAI fixes the issue with this model diff --git a/backend/main.py b/backend/main.py index ea35ba2a16..a64543b41c 100644 --- a/backend/main.py +++ b/backend/main.py @@ -315,8 +315,12 @@ class PipelineMiddleware(BaseHTTPMiddleware): else: pass - if "chat_id" in data: - del data["chat_id"] + if "pipeline" not in app.state.MODELS[model_id]: + if "chat_id" in data: + del data["chat_id"] + + if "title" in data: + del data["title"] modified_body_bytes = json.dumps(data).encode("utf-8") # Replace the request body with the modified one diff --git a/src/lib/apis/openai/index.ts b/src/lib/apis/openai/index.ts index fc9365d128..2a52ebb320 100644 --- a/src/lib/apis/openai/index.ts +++ b/src/lib/apis/openai/index.ts @@ -336,6 +336,7 @@ export const generateTitle = async ( template: string, model: string, prompt: string, + chat_id?: string, url: string = OPENAI_API_BASE_URL ) => { let error = null; @@ -361,7 +362,9 @@ export const generateTitle = async ( ], stream: false, // Restricting the max tokens to 50 to avoid long titles - max_tokens: 50 + max_tokens: 50, + ...(chat_id && { chat_id: chat_id }), + title: true }) }) .then(async (res) => { diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index ab1b482de9..2eb9a9b303 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -1118,6 +1118,7 @@ ) + ' {{prompt}}', titleModelId, userPrompt, + $chatId, titleModel?.owned_by === 'openai' ?? false ? `${OPENAI_API_BASE_URL}` : `${OLLAMA_API_BASE_URL}/v1` From 92700302b94c16d27ab2ddceb6a6c604b76fd20d Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 13:35:47 -0700 Subject: [PATCH 016/411] fix: edit --- src/routes/(app)/workspace/models/edit/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(app)/workspace/models/edit/+page.svelte b/src/routes/(app)/workspace/models/edit/+page.svelte index 169d439fa1..526271d46d 100644 --- a/src/routes/(app)/workspace/models/edit/+page.svelte +++ b/src/routes/(app)/workspace/models/edit/+page.svelte @@ -70,9 +70,9 @@ const res = await updateModelById(localStorage.token, info.id, info); if (res) { + await models.set(await getModels(localStorage.token)); toast.success('Model updated successfully'); await goto('/workspace/models'); - await models.set(await getModels(localStorage.token)); } loading = false; From 5ef478a154899cf2d6fad845a53dab1c92a49d13 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 14:19:46 -0700 Subject: [PATCH 017/411] fix: read only compare messages --- src/lib/components/chat/Messages.svelte | 1 + src/lib/components/chat/Messages/CompareMessages.svelte | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 4e2a383a18..0a8bde796e 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -340,6 +340,7 @@ showPreviousMessage(model)} showNextMessage={() => showNextMessage(model)} + {readOnly} {rateMessage} {copyToClipboard} {continueGeneration} From 5b01d7994a8627abfb40fcbb0aae259d12f6c271 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 14:21:26 -0700 Subject: [PATCH 018/411] fix: openai notification issue --- src/lib/components/chat/Chat.svelte | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 2eb9a9b303..430ab8355c 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -951,27 +951,27 @@ messages = messages; } - if ($settings.notificationEnabled && !document.hasFocus()) { - const notification = new Notification(`OpenAI ${model}`, { - body: responseMessage.content, - icon: `${WEBUI_BASE_URL}/static/favicon.png` - }); - } - - if ($settings.responseAutoCopy) { - copyToClipboard(responseMessage.content); - } - - if ($settings.responseAutoPlayback) { - await tick(); - document.getElementById(`speak-button-${responseMessage.id}`)?.click(); - } - if (autoScroll) { scrollToBottom(); } } + if ($settings.notificationEnabled && !document.hasFocus()) { + const notification = new Notification(`OpenAI ${model}`, { + body: responseMessage.content, + icon: `${WEBUI_BASE_URL}/static/favicon.png` + }); + } + + if ($settings.responseAutoCopy) { + copyToClipboard(responseMessage.content); + } + + if ($settings.responseAutoPlayback) { + await tick(); + document.getElementById(`speak-button-${responseMessage.id}`)?.click(); + } + if (lastUsage) { responseMessage.info = { ...lastUsage, openai: true }; } From 2dbbd1bc6feb7cfcee0fc7be168bbc0f7b84d899 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 19:40:58 -0700 Subject: [PATCH 019/411] refac: pipelines --- src/lib/components/admin/Settings/Pipelines.svelte | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib/components/admin/Settings/Pipelines.svelte b/src/lib/components/admin/Settings/Pipelines.svelte index 7be08e69c5..35ea425bef 100644 --- a/src/lib/components/admin/Settings/Pipelines.svelte +++ b/src/lib/components/admin/Settings/Pipelines.svelte @@ -40,8 +40,10 @@ const pipeline = pipelines[selectedPipelineIdx]; if (pipeline && (pipeline?.valves ?? false)) { - if (valves?.pipelines ?? false) { - valves.pipelines = valves.pipelines.split(',').map((v) => v.trim()); + for (const property in valves_spec.properties) { + if (valves_spec.properties[property]?.type === 'array') { + valves[property] = valves[property].split(',').map((v) => v.trim()); + } } const res = await updatePipelineValves( @@ -79,8 +81,10 @@ selectedPipelinesUrlIdx ); - if (valves?.pipelines ?? false) { - valves.pipelines = valves.pipelines.join(','); + for (const property in valves_spec.properties) { + if (valves_spec.properties[property]?.type === 'array') { + valves[property] = valves[property].join(','); + } } }; From 3730251958f13530fbe4fd404e09201f8b4116f2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 31 May 2024 19:51:34 -0700 Subject: [PATCH 020/411] refac: selector mobile styling --- .../chat/ModelSelector/Selector.svelte | 168 ++++++++++-------- 1 file changed, 91 insertions(+), 77 deletions(-) diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 7fcc3b5b4f..6b8d173537 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -251,35 +251,9 @@ show = false; }} > -
-
-
- {item.label} -
- {#if item.model.owned_by === 'ollama' && (item.model.ollama?.details?.parameter_size ?? '') !== ''} -
- - {item.model.ollama?.details?.parameter_size ?? ''} - -
- {/if} -
- - {#if (item?.model?.info?.meta?.tags ?? []).length > 0} -
+
+ {#if $mobile && (item?.model?.info?.meta?.tags ?? []).length > 0} +
{#each item.model?.info?.meta.tags as tag}
{/if} - - - - {#if item.model.owned_by === 'openai'} - -
- - - - +
+
+
+ {item.label}
- - {/if} + {#if item.model.owned_by === 'ollama' && (item.model.ollama?.details?.parameter_size ?? '') !== ''} +
+ + {item.model.ollama?.details?.parameter_size ?? ''} + +
+ {/if} +
- {#if item.model?.info?.meta?.description} - ')}`} - > -
- - - + {#if !$mobile && (item?.model?.info?.meta?.tags ?? []).length > 0} +
+ {#each item.model?.info?.meta.tags as tag} +
+ {tag.name} +
+ {/each}
- - {/if} + {/if} + + + + {#if item.model.owned_by === 'openai'} + +
+ + + + +
+
+ {/if} + + {#if item.model?.info?.meta?.description} + ')}`} + > +
+ + + +
+
+ {/if} +
{#if value === item.value} From afbea2ecea3550140c9ffdfc4ad2d093a698e6af Mon Sep 17 00:00:00 2001 From: Jun Siang Cheah Date: Sat, 1 Jun 2024 14:16:39 +0100 Subject: [PATCH 021/411] fix: don't use BUILD_HASH build arg until needed, busts cache otherwise --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index be5c1da411..2bd05e6baa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,6 @@ ARG USE_OLLAMA ARG USE_CUDA_VER ARG USE_EMBEDDING_MODEL ARG USE_RERANKING_MODEL -ARG BUILD_HASH ARG UID ARG GID @@ -154,6 +153,7 @@ HEALTHCHECK CMD curl --silent --fail http://localhost:8080/health | jq -e '.stat USER $UID:$GID +ARG BUILD_HASH ENV WEBUI_BUILD_VERSION=${BUILD_HASH} CMD [ "bash", "start.sh"] From fd31b5f8d6914c0c1a94c31bc68c71e672fa6fd5 Mon Sep 17 00:00:00 2001 From: Jun Siang Cheah Date: Sun, 26 May 2024 16:58:00 +0100 Subject: [PATCH 022/411] refac: error message separate from content --- src/lib/components/chat/Chat.svelte | 13 +++--- .../chat/Messages/ResponseMessage.svelte | 43 ++++++++++--------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 430ab8355c..42bc086123 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -681,8 +681,7 @@ if (responseMessage.content == '') { responseMessage.error = true; - responseMessage.content = - 'Oops! No text generated from Ollama, Please try again.'; + responseMessage.errorContent = 'Oops! No text generated from Ollama, Please try again.'; } responseMessage.context = data.context ?? null; @@ -754,22 +753,22 @@ console.log(error); if ('detail' in error) { toast.error(error.detail); - responseMessage.content = error.detail; + responseMessage.errorContent = error.detail; } else { toast.error(error.error); - responseMessage.content = error.error; + responseMessage.errorContent = error.error; } } else { toast.error( $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: 'Ollama' }) ); - responseMessage.content = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { + responseMessage.errorContent = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: 'Ollama' }); } responseMessage.error = true; - responseMessage.content = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { + responseMessage.errorContent = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: 'Ollama' }); responseMessage.done = true; @@ -1036,7 +1035,7 @@ } responseMessage.error = true; - responseMessage.content = + responseMessage.errorContent = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: model.name ?? model.id }) + diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 2e1b3144a0..0e64ad6ee5 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -451,7 +451,27 @@
{:else}
- {#if message?.error === true} + {#if message.content === '' && !message.error} + + {:else if !message.error || message.errorContent} + {#each tokens as token, tokenIdx} + {#if token.type === 'code'} + + {:else} + {@html marked.parse(token.raw, { + ...defaults, + gfm: true, + breaks: true, + renderer + })} + {/if} + {/each} + {/if} + {#if message.error === true}
@@ -471,28 +491,9 @@
- {message.content} + {message.errorContent ?? message.content}
- {:else if message.content === ''} - - {:else} - {#each tokens as token, tokenIdx} - {#if token.type === 'code'} - - {:else} - {@html marked.parse(token.raw, { - ...defaults, - gfm: true, - breaks: true, - renderer - })} - {/if} - {/each} {/if} {#if message.citations} From 78b279cabc3af75e55380a1c42891466b792a994 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 10:19:27 -0700 Subject: [PATCH 023/411] refac --- src/lib/components/chat/Chat.svelte | 29 +++++++++---------- .../chat/Messages/ResponseMessage.svelte | 6 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 42bc086123..8b8873c026 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -680,8 +680,10 @@ responseMessage.done = true; if (responseMessage.content == '') { - responseMessage.error = true; - responseMessage.errorContent = 'Oops! No text generated from Ollama, Please try again.'; + responseMessage.error = { + code: 400, + content: `Oops! No text generated from Ollama, Please try again.` + }; } responseMessage.context = data.context ?? null; @@ -753,24 +755,21 @@ console.log(error); if ('detail' in error) { toast.error(error.detail); - responseMessage.errorContent = error.detail; + responseMessage.error = { content: error.detail }; } else { toast.error(error.error); - responseMessage.errorContent = error.error; + responseMessage.error = { content: error.error }; } } else { toast.error( $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: 'Ollama' }) ); - responseMessage.errorContent = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { - provider: 'Ollama' - }); + responseMessage.error = { + content: $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { + provider: 'Ollama' + }) + }; } - - responseMessage.error = true; - responseMessage.errorContent = $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { - provider: 'Ollama' - }); responseMessage.done = true; messages = messages; } @@ -1034,13 +1033,13 @@ errorMessage = innerError.message; } - responseMessage.error = true; - responseMessage.errorContent = - $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { + responseMessage.error = { + content: $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { provider: model.name ?? model.id }) + '\n' + errorMessage; + }; responseMessage.done = true; messages = messages; diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 0e64ad6ee5..32da079636 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -453,7 +453,7 @@
{#if message.content === '' && !message.error} - {:else if !message.error || message.errorContent} + {:else if !message.error} {#each tokens as token, tokenIdx} {#if token.type === 'code'} @@ -491,7 +491,7 @@
- {message.errorContent ?? message.content} + {message?.error?.content ?? message.content}
{/if} From 6bd7c20fbb4de807b94a891c8f0b04554bb1527e Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 10:33:49 -0700 Subject: [PATCH 024/411] fix --- src/lib/components/chat/Chat.svelte | 11 ++++++----- .../components/chat/Messages/ResponseMessage.svelte | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 8b8873c026..2d0bee01e0 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -1034,11 +1034,12 @@ } responseMessage.error = { - content: $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { - provider: model.name ?? model.id - }) + - '\n' + - errorMessage; + content: + $i18n.t(`Uh-oh! There was an issue connecting to {{provider}}.`, { + provider: model.name ?? model.id + }) + + '\n' + + errorMessage }; responseMessage.done = true; diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 32da079636..c7890f1c52 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -471,6 +471,7 @@ {/if} {/each} {/if} + {#if message.error}
Date: Sat, 1 Jun 2024 12:03:36 -0700 Subject: [PATCH 025/411] refac: disable sortable on mobile --- src/lib/components/workspace/Models.svelte | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 43f0cad67d..dcecef8198 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -7,7 +7,7 @@ import { onMount, getContext, tick } from 'svelte'; - import { WEBUI_NAME, modelfiles, models, settings, user } from '$lib/stores'; + import { WEBUI_NAME, mobile, models, settings, user } from '$lib/stores'; import { addNewModel, deleteModelById, getModelInfos, updateModelById } from '$lib/apis/models'; import { deleteModel } from '$lib/apis/ollama'; @@ -170,14 +170,16 @@ console.log(localModelfiles); } - // SortableJS - sortable = new Sortable(document.getElementById('model-list'), { - animation: 150, - onUpdate: async (event) => { - console.log(event); - positionChangeHanlder(); - } - }); + if (!$mobile) { + // SortableJS + sortable = new Sortable(document.getElementById('model-list'), { + animation: 150, + onUpdate: async (event) => { + console.log(event); + positionChangeHanlder(); + } + }); + } }); From 51d2cecd366af962c6ca600167865d43964c2738 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 12:06:12 -0700 Subject: [PATCH 026/411] refac: styling --- src/lib/components/chat/MessageInput.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index cb4e5f1604..c78ecffc1d 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -778,7 +778,7 @@ {/if}
-
+
{ From 561778d04dfc25f06bca4d94d0ac4ed6fc236005 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 12:17:18 -0700 Subject: [PATCH 027/411] feat: pipelines warning message --- src/lib/components/admin/Settings/Pipelines.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/components/admin/Settings/Pipelines.svelte b/src/lib/components/admin/Settings/Pipelines.svelte index 35ea425bef..875e610519 100644 --- a/src/lib/components/admin/Settings/Pipelines.svelte +++ b/src/lib/components/admin/Settings/Pipelines.svelte @@ -263,6 +263,14 @@ {/if}
+ +
+ Warning: Pipelines are a plugin + system with arbitrary code execution — + don't fetch random pipelines from sources you don't trust. +

From 1cef48730e0c359e717cfced80da46e45b048e82 Mon Sep 17 00:00:00 2001 From: Jun Siang Cheah Date: Sat, 1 Jun 2024 20:47:04 +0100 Subject: [PATCH 028/411] fix: show both message contents and error message --- src/lib/components/chat/Messages/ResponseMessage.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index c7890f1c52..571ac924e1 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -453,7 +453,9 @@
{#if message.content === '' && !message.error} - {:else if !message.error} + {:else if message.content && message.error !== true} + + {#each tokens as token, tokenIdx} {#if token.type === 'code'} Date: Sat, 1 Jun 2024 13:46:14 -0700 Subject: [PATCH 029/411] fix: typo --- .../components/chat/Settings/Advanced/AdvancedParams.svelte | 2 +- src/lib/i18n/locales/ar-BH/translation.json | 4 +++- src/lib/i18n/locales/bg-BG/translation.json | 4 +++- src/lib/i18n/locales/bn-BD/translation.json | 4 +++- src/lib/i18n/locales/ca-ES/translation.json | 4 +++- src/lib/i18n/locales/ceb-PH/translation.json | 4 +++- src/lib/i18n/locales/de-DE/translation.json | 4 +++- src/lib/i18n/locales/dg-DG/translation.json | 4 +++- src/lib/i18n/locales/en-GB/translation.json | 4 +++- src/lib/i18n/locales/en-US/translation.json | 4 +++- src/lib/i18n/locales/es-ES/translation.json | 4 +++- src/lib/i18n/locales/fa-IR/translation.json | 4 +++- src/lib/i18n/locales/fi-FI/translation.json | 4 +++- src/lib/i18n/locales/fr-CA/translation.json | 4 +++- src/lib/i18n/locales/fr-FR/translation.json | 4 +++- src/lib/i18n/locales/he-IL/translation.json | 4 +++- src/lib/i18n/locales/hi-IN/translation.json | 4 +++- src/lib/i18n/locales/hr-HR/translation.json | 4 +++- src/lib/i18n/locales/it-IT/translation.json | 4 +++- src/lib/i18n/locales/ja-JP/translation.json | 4 +++- src/lib/i18n/locales/ka-GE/translation.json | 4 +++- src/lib/i18n/locales/ko-KR/translation.json | 4 +++- src/lib/i18n/locales/nl-NL/translation.json | 4 +++- src/lib/i18n/locales/pa-IN/translation.json | 4 +++- src/lib/i18n/locales/pl-PL/translation.json | 4 +++- src/lib/i18n/locales/pt-BR/translation.json | 4 +++- src/lib/i18n/locales/pt-PT/translation.json | 4 +++- src/lib/i18n/locales/ru-RU/translation.json | 4 +++- src/lib/i18n/locales/sr-RS/translation.json | 4 +++- src/lib/i18n/locales/sv-SE/translation.json | 4 +++- src/lib/i18n/locales/tr-TR/translation.json | 4 +++- src/lib/i18n/locales/uk-UA/translation.json | 4 +++- src/lib/i18n/locales/vi-VN/translation.json | 4 +++- src/lib/i18n/locales/zh-CN/translation.json | 4 +++- src/lib/i18n/locales/zh-TW/translation.json | 4 +++- 35 files changed, 103 insertions(+), 35 deletions(-) diff --git a/src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte b/src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte index 93c4827119..55648df54a 100644 --- a/src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte +++ b/src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte @@ -379,7 +379,7 @@
-
{$i18n.t('Frequencey Penalty')}
+
{$i18n.t('Frequency Penalty')}
-
-
{/if} + +
+ +
+ + + +
From 7f2e89a8aa00f688df6aba54bc18348d663eb225 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 16:34:36 -0700 Subject: [PATCH 032/411] enh: allow label search --- src/lib/components/chat/ModelSelector/Selector.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 6b8d173537..868c75da73 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -46,6 +46,7 @@ (item) => (searchValue ? item.value.toLowerCase().includes(searchValue.toLowerCase()) || + item.label.toLowerCase().includes(searchValue.toLowerCase()) || (item.model?.info?.meta?.tags ?? []).some((tag) => tag.name.toLowerCase().includes(searchValue.toLowerCase()) ) From 53b44b75dcc66d051e7d511619ac1a04701285fc Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 17:41:07 -0700 Subject: [PATCH 033/411] doc: changelog --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98656a309e..2354d47a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,44 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0] - 2024-06-01 + +### Added + +- **🔧 Pipelines Support**: Open WebUI now includes a plugin framework for enhanced customization and functionality. (https://github.com/open-webui/pipelines). Easily add custom logic and integrate Python libraries, from AI agents to home automation APIs. +- **🔗 Function Calling via Pipelines**: Integrate function calling seamlessly through Pipelines. +- **⚖️ User Rate Limiting via Pipelines**: Implement user-specific rate limits to manage API usage efficiently. +- **📊 Usage Monitoring with Langfuse**: Track and analyze usage statistics with Langfuse integration through Pipelines. +- **🕒 Conversation Turn Limits**: Set limits on conversation turns to manage interactions better through Pipelines. +- **🛡️ Toxic Message Filtering**: Automatically filter out toxic messages to maintain a safe environment using pipelines. +- **🔍 Web Search Support**: Enhance functionality with built-in web search capabilities. +- **🗂️ Models Workspace**: Create and manage model presets for both Ollama/OpenAI API. Note: The old Modelfiles workspace is deprecated. +- **🛠️ Model Builder Feature**: Build and edit all models with persistent builder mode. +- **🏷️ Model Tagging Support**: Organize models with tagging features in the models workspace. +- **📋 Model Ordering Support**: Easily arrange models within the models workspace. +- **📈 OpenAI Generation Stats**: Access detailed generation statistics for OpenAI models. +- **📅 System Prompt Variables**: New variables added: '{{CURRENT_DATE}}' and '{{USER_NAME}}' for dynamic prompts. +- **📢 Global Banner Support**: Manage global banners from admin settings > banners. +- **🗃️ Enhanced Archived Chats Modal**: Search and export archived chats easily. +- **📂 Archive All Button**: Quickly archive all chats from settings > chats. +- **🌐 Improved Translations**: Added and improved translations for French, Croatian, Cebuano, and Vietnamese. + +### Fixed + +- **🔍 Archived Chats Visibility**: Resolved issue with archived chats not showing in the admin panel. +- **💬 Message Styling**: Fixed styling issues affecting message appearance. +- **🔗 Shared Chat Responses**: Corrected the issue where shared chat response messages were not readonly. + +### Changed + +- **💾 User Settings Storage**: User settings are now saved on the backend, ensuring consistency across all devices. +- **📡 Unified API Requests**: The API request for getting models is now unified to '/api/models' for easier usage. +- **🔄 Versioning Update**: Our versioning will now follow the format 0.x for major updates and 0.x.y for patches. + +### Removed + +- **🚫 Bundled LiteLLM Support Deprecated**: Migrate your LiteLLM config.yaml to a self-hosted LiteLLM instance. LiteLLM can still be added via OpenAI Connections. Download the LiteLLM config.yaml from admin settings > database > export LiteLLM config.yaml. + ## [0.1.125] - 2024-05-19 ### Added From d993beb18f070b16d912615bb7f25074ffa042e8 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 17:42:55 -0700 Subject: [PATCH 034/411] fix: typo --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2354d47a32..3db7c593e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- **🔧 Pipelines Support**: Open WebUI now includes a plugin framework for enhanced customization and functionality. (https://github.com/open-webui/pipelines). Easily add custom logic and integrate Python libraries, from AI agents to home automation APIs. +- **🔧 Pipelines Support**: Open WebUI now includes a plugin framework for enhanced customization and functionality (https://github.com/open-webui/pipelines). Easily add custom logic and integrate Python libraries, from AI agents to home automation APIs. - **🔗 Function Calling via Pipelines**: Integrate function calling seamlessly through Pipelines. - **⚖️ User Rate Limiting via Pipelines**: Implement user-specific rate limits to manage API usage efficiently. - **📊 Usage Monitoring with Langfuse**: Track and analyze usage statistics with Langfuse integration through Pipelines. - **🕒 Conversation Turn Limits**: Set limits on conversation turns to manage interactions better through Pipelines. -- **🛡️ Toxic Message Filtering**: Automatically filter out toxic messages to maintain a safe environment using pipelines. +- **🛡️ Toxic Message Filtering**: Automatically filter out toxic messages to maintain a safe environment using Pipelines. - **🔍 Web Search Support**: Enhance functionality with built-in web search capabilities. - **🗂️ Models Workspace**: Create and manage model presets for both Ollama/OpenAI API. Note: The old Modelfiles workspace is deprecated. - **🛠️ Model Builder Feature**: Build and edit all models with persistent builder mode. From ef4af8688337a3e2b6602749ddf65e48b53bfa20 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 18:00:01 -0700 Subject: [PATCH 035/411] refac: message new line issue --- src/lib/components/chat/MessageInput.svelte | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index c78ecffc1d..1ede59f2da 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -817,7 +817,10 @@ ? $i18n.t('Listening...') : $i18n.t('Send a Message')} bind:value={prompt} - on:keypress={(e) => { + on:keypress={(e) => {}} + on:keydown={async (e) => { + // Check if the device is not a mobile device or if it is a mobile device, check if it is not a touch device + // This is to prevent the Enter key from submitting the prompt on mobile devices if ( !$mobile || !( @@ -826,15 +829,22 @@ navigator.msMaxTouchPoints > 0 ) ) { - if (e.keyCode == 13 && !e.shiftKey) { + // Check if Enter is pressed + // Check if Shift key is not pressed + if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); } - if (prompt !== '' && e.keyCode == 13 && !e.shiftKey) { + + if (e.key === 'Enter' && !e.shiftKey && prompt !== '') { submitPrompt(prompt, user); + return; + } + + if (e.key === 'Enter' && e.shiftKey && prompt !== '') { + return; } } - }} - on:keydown={async (e) => { + const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac // Check if Ctrl + R is pressed From c5c33aabf9161ccdc37db8e23387560a806003c8 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 1 Jun 2024 18:11:54 -0700 Subject: [PATCH 036/411] refac: styling --- src/lib/components/chat/Chat.svelte | 23 +- src/lib/components/chat/MessageInput.svelte | 1138 +++++++++---------- src/lib/components/chat/Messages.svelte | 4 +- 3 files changed, 578 insertions(+), 587 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 2d0bee01e0..a6cea0c073 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -1269,18 +1269,17 @@ />
+
- - {/if} diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 1ede59f2da..7c1c877049 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -440,292 +440,212 @@
{/if} -
-
-
-
-
- {#if autoScroll === false && messages.length > 0} -
+
+
+
+
+ {#if autoScroll === false && messages.length > 0} +
+ +
+ {/if} +
+ +
+ {#if prompt.charAt(0) === '/'} + + {:else if prompt.charAt(0) === '#'} + { + console.log(e); + uploadYoutubeTranscription(e.detail); + }} + on:url={(e) => { + console.log(e); + uploadWeb(e.detail); + }} + on:select={(e) => { + console.log(e); + files = [ + ...files, + { + type: e?.detail?.type ?? 'doc', + ...e.detail, + upload_status: true + } + ]; + }} + /> + {/if} + + { + atSelectedModel = e.detail; + chatTextAreaElement?.focus(); + }} + /> + + {#if atSelectedModel !== undefined} +
+
+ model profile model.id === atSelectedModel.id)?.info?.meta + ?.profile_image_url ?? + ($i18n.language === 'dg-DG' + ? `/doge.png` + : `${WEBUI_BASE_URL}/static/favicon.png`)} + /> +
+ Talking to {atSelectedModel.name} +
+
+
- {/if} -
- -
- {#if prompt.charAt(0) === '/'} - - {:else if prompt.charAt(0) === '#'} - { - console.log(e); - uploadYoutubeTranscription(e.detail); - }} - on:url={(e) => { - console.log(e); - uploadWeb(e.detail); - }} - on:select={(e) => { - console.log(e); - files = [ - ...files, - { - type: e?.detail?.type ?? 'doc', - ...e.detail, - upload_status: true - } - ]; - }} - /> - {/if} - - { - atSelectedModel = e.detail; - chatTextAreaElement?.focus(); - }} - /> - - {#if atSelectedModel !== undefined} -
-
- model profile model.id === atSelectedModel.id)?.info?.meta - ?.profile_image_url ?? - ($i18n.language === 'dg-DG' - ? `/doge.png` - : `${WEBUI_BASE_URL}/static/favicon.png`)} - /> -
- Talking to {atSelectedModel.name} -
-
-
- -
-
- {/if} -
+
+ {/if}
+
-
-
-
- { - if (inputFiles && inputFiles.length > 0) { - const _inputFiles = Array.from(inputFiles); - _inputFiles.forEach((file) => { - if ( - ['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(file['type']) - ) { - if (visionCapableModels.length === 0) { - toast.error($i18n.t('Selected model(s) do not support image inputs')); - inputFiles = null; - filesInputElement.value = ''; - return; - } - let reader = new FileReader(); - reader.onload = (event) => { - files = [ - ...files, - { - type: 'image', - url: `${event.target.result}` - } - ]; - inputFiles = null; - filesInputElement.value = ''; - }; - reader.readAsDataURL(file); - } else if ( - SUPPORTED_FILE_TYPE.includes(file['type']) || - SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1)) - ) { - uploadDoc(file); - filesInputElement.value = ''; - } else { - toast.error( - $i18n.t( - `Unknown File Type '{{file_type}}', but accepting and treating as plain text`, - { file_type: file['type'] } - ) - ); - uploadDoc(file); +
+
+
+ { + if (inputFiles && inputFiles.length > 0) { + const _inputFiles = Array.from(inputFiles); + _inputFiles.forEach((file) => { + if (['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(file['type'])) { + if (visionCapableModels.length === 0) { + toast.error($i18n.t('Selected model(s) do not support image inputs')); + inputFiles = null; filesInputElement.value = ''; + return; } - }); - } else { - toast.error($i18n.t(`File not found.`)); - } - }} - /> -
{ - // check if selectedModels support image input - submitPrompt(prompt, user); - }} - > - {#if files.length > 0} -
- {#each files as file, fileIdx} -
- {#if file.type === 'image'} -
- input - {#if atSelectedModel ? visionCapableModels.length === 0 : selectedModels.length !== visionCapableModels.length} - !visionCapableModels.includes(id)) - .join(', ') - })} + let reader = new FileReader(); + reader.onload = (event) => { + files = [ + ...files, + { + type: 'image', + url: `${event.target.result}` + } + ]; + inputFiles = null; + filesInputElement.value = ''; + }; + reader.readAsDataURL(file); + } else if ( + SUPPORTED_FILE_TYPE.includes(file['type']) || + SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1)) + ) { + uploadDoc(file); + filesInputElement.value = ''; + } else { + toast.error( + $i18n.t( + `Unknown File Type '{{file_type}}', but accepting and treating as plain text`, + { file_type: file['type'] } + ) + ); + uploadDoc(file); + filesInputElement.value = ''; + } + }); + } else { + toast.error($i18n.t(`File not found.`)); + } + }} + /> + { + // check if selectedModels support image input + submitPrompt(prompt, user); + }} + > + {#if files.length > 0} +
+ {#each files as file, fileIdx} +
+ {#if file.type === 'image'} +
+ input + {#if atSelectedModel ? visionCapableModels.length === 0 : selectedModels.length !== visionCapableModels.length} + !visionCapableModels.includes(id)) + .join(', ') + })} + > + - - - - - {/if} -
- {:else if file.type === 'doc'} -
-
- {#if file.upload_status} - - - - - {:else} - - {/if} -
- -
-
- {file.name} -
- -
{$i18n.t('Document')}
-
-
- {:else if file.type === 'collection'} -
-
+ + + + {/if} +
+ {:else if file.type === 'doc'} +
+
+ {#if file.upload_status} -
- -
-
- {file?.title ?? `#${file.name}`} -
- -
{$i18n.t('Collection')}
-
-
- {/if} - -
- -
-
- {/each} -
- {/if} - -
-
- { - filesInputElement.click(); - }} - onClose={async () => { - await tick(); - chatTextAreaElement?.focus(); - }} - > - - -
- -