Merge pull request #2794 from open-webui/dev

fix
This commit is contained in:
Timothy Jaeryang Baek 2024-06-03 15:52:04 -07:00 committed by GitHub
commit 8a94d8a226
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 172 additions and 29 deletions

View File

@ -21,7 +21,7 @@ Open WebUI is an extensible, feature-rich, and user-friendly self-hosted WebUI d
- 🤝 **Ollama/OpenAI API Integration**: Effortlessly integrate OpenAI-compatible APIs for versatile conversations alongside Ollama models. Customize the OpenAI API URL to link with **LMStudio, GroqCloud, Mistral, OpenRouter, and more**. - 🤝 **Ollama/OpenAI API Integration**: Effortlessly integrate OpenAI-compatible APIs for versatile conversations alongside Ollama models. Customize the OpenAI API URL to link with **LMStudio, GroqCloud, Mistral, OpenRouter, and more**.
- 🧩 **Pipelines, Open WebUI Plugin Support**: Seamlessly integrate custom logic and Python libraries into Open WebUI using [Pipelines Plugin Framework](https://github.com/open-webui/pipelines). Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. [Examples](https://github.com/open-webui/pipelines/examples) include **Function Calling**, User **Rate Limiting** to control access, **Usage Monitoring** with tools like Langfuse, **Live Translation with LibreTranslate** for multilingual support, **Toxic Message Filtering** and much more. - 🧩 **Pipelines, Open WebUI Plugin Support**: Seamlessly integrate custom logic and Python libraries into Open WebUI using [Pipelines Plugin Framework](https://github.com/open-webui/pipelines). Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. [Examples](https://github.com/open-webui/pipelines/tree/main/examples) include **Function Calling**, User **Rate Limiting** to control access, **Usage Monitoring** with tools like Langfuse, **Live Translation with LibreTranslate** for multilingual support, **Toxic Message Filtering** and much more.
- 📱 **Responsive Design**: Enjoy a seamless experience across Desktop PC, Laptop, and Mobile devices. - 📱 **Responsive Design**: Enjoy a seamless experience across Desktop PC, Laptop, and Mobile devices.

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '2';
</script>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
class={className}
>
<path
fill-rule="evenodd"
d="M2 7a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7Zm5.01 1H5v2.01h2.01V8Zm3 0H8v2.01h2.01V8Zm3 0H11v2.01h2.01V8Zm3 0H14v2.01h2.01V8Zm3 0H17v2.01h2.01V8Zm-12 3H5v2.01h2.01V11Zm3 0H8v2.01h2.01V11Zm3 0H11v2.01h2.01V11Zm3 0H14v2.01h2.01V11Zm3 0H17v2.01h2.01V11Zm-12 3H5v2.01h2.01V14ZM8 14l-.001 2 8.011.01V14H8Zm11.01 0H17v2.01h2.01V14Z"
clip-rule="evenodd"
/>
</svg>

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '2';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.712 4.33a9.027 9.027 0 0 1 1.652 1.306c.51.51.944 1.064 1.306 1.652M16.712 4.33l-3.448 4.138m3.448-4.138a9.014 9.014 0 0 0-9.424 0M19.67 7.288l-4.138 3.448m4.138-3.448a9.014 9.014 0 0 1 0 9.424m-4.138-5.976a3.736 3.736 0 0 0-.88-1.388 3.737 3.737 0 0 0-1.388-.88m2.268 2.268a3.765 3.765 0 0 1 0 2.528m-2.268-4.796a3.765 3.765 0 0 0-2.528 0m4.796 4.796c-.181.506-.475.982-.88 1.388a3.736 3.736 0 0 1-1.388.88m2.268-2.268 4.138 3.448m0 0a9.027 9.027 0 0 1-1.306 1.652c-.51.51-1.064.944-1.652 1.306m0 0-3.448-4.138m3.448 4.138a9.014 9.014 0 0 1-9.424 0m5.976-4.138a3.765 3.765 0 0 1-2.528 0m0 0a3.736 3.736 0 0 1-1.388-.88 3.737 3.737 0 0 1-.88-1.388m2.268 2.268L7.288 19.67m0 0a9.024 9.024 0 0 1-1.652-1.306 9.027 9.027 0 0 1-1.306-1.652m0 0 4.138-3.448M4.33 16.712a9.014 9.014 0 0 1 0-9.424m4.138 5.976a3.765 3.765 0 0 1 0-2.528m0 0c.181-.506.475-.982.88-1.388a3.736 3.736 0 0 1 1.388-.88m-2.268 2.268L4.33 7.288m6.406 1.18L7.288 4.33m0 0a9.024 9.024 0 0 0-1.652 1.306A9.025 9.025 0 0 0 4.33 7.288"
/>
</svg>

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'w-4 h-4';
export let strokeWidth = '2';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"
/>
</svg>

View File

@ -0,0 +1,40 @@
<script lang="ts">
import { onMount, tick, getContext } from 'svelte';
const i18n = getContext('i18n');
import ShortcutsModal from '../chat/ShortcutsModal.svelte';
import Tooltip from '../common/Tooltip.svelte';
import HelpMenu from './Help/HelpMenu.svelte';
let showShortcuts = false;
</script>
<div class=" hidden lg:flex fixed bottom-0 right-0 px-2 py-2 z-10">
<button
id="show-shortcuts-button"
class="hidden"
on:click={() => {
showShortcuts = !showShortcuts;
}}
/>
<HelpMenu
showDocsHandler={() => {
showShortcuts = !showShortcuts;
}}
showShortcutsHandler={() => {
showShortcuts = !showShortcuts;
}}
>
<Tooltip content={$i18n.t('Help')} placement="left">
<button
class="text-gray-600 dark:text-gray-300 bg-gray-300/20 size-5 flex items-center justify-center text-[0.7rem] rounded-full"
>
?
</button>
</Tooltip>
</HelpMenu>
</div>
<ShortcutsModal bind:show={showShortcuts} />

View File

@ -0,0 +1,60 @@
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
import { getContext } from 'svelte';
import { showSettings } from '$lib/stores';
import { flyAndScale } from '$lib/utils/transitions';
import Dropdown from '$lib/components/common/Dropdown.svelte';
import QuestionMarkCircle from '$lib/components/icons/QuestionMarkCircle.svelte';
import Lifebuoy from '$lib/components/icons/Lifebuoy.svelte';
import Keyboard from '$lib/components/icons/Keyboard.svelte';
const i18n = getContext('i18n');
export let showDocsHandler: Function;
export let showShortcutsHandler: Function;
export let onClose: Function = () => {};
</script>
<Dropdown
on:change={(e) => {
if (e.detail === false) {
onClose();
}
}}
>
<slot />
<div slot="content">
<DropdownMenu.Content
class="w-full max-w-[200px] rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
sideOffset={4}
side="top"
align="end"
transition={flyAndScale}
>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
id="chat-share-button"
on:click={() => {
window.open('https://docs.openwebui.com', '_blank');
}}
>
<QuestionMarkCircle className="size-5" />
<div class="flex items-center">{$i18n.t('Documentation')}</div>
</DropdownMenu.Item>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
id="chat-share-button"
on:click={() => {
showShortcutsHandler();
}}
>
<Keyboard className="size-5" />
<div class="flex items-center">{$i18n.t('Keyboard shortcuts')}</div>
</DropdownMenu.Item>
</DropdownMenu.Content>
</div>
</Dropdown>

View File

@ -3,7 +3,7 @@
"(Beta)": "(Beta)", "(Beta)": "(Beta)",
"(e.g. `sh webui.sh --api`)": "(örn. `sh webui.sh --api`)", "(e.g. `sh webui.sh --api`)": "(örn. `sh webui.sh --api`)",
"(latest)": "(en son)", "(latest)": "(en son)",
"{{ models }}": "{{ modeller }}", "{{ models }}": "{{ models }}",
"{{ owner }}: You cannot delete a base model": "{{ owner }}: Temel modeli silemezsiniz", "{{ owner }}: You cannot delete a base model": "{{ owner }}: Temel modeli silemezsiniz",
"{{modelName}} is thinking...": "{{modelName}} düşünüyor...", "{{modelName}} is thinking...": "{{modelName}} düşünüyor...",
"{{user}}'s Chats": "{{user}} Sohbetleri", "{{user}}'s Chats": "{{user}} Sohbetleri",
@ -37,7 +37,7 @@
"All Users": "Tüm Kullanıcılar", "All Users": "Tüm Kullanıcılar",
"Allow": "İzin ver", "Allow": "İzin ver",
"Allow Chat Deletion": "Sohbet Silmeye İzin Ver", "Allow Chat Deletion": "Sohbet Silmeye İzin Ver",
"Allow non-local voices": "", "Allow non-local voices": "Yerel olmayan seslere izin verin",
"alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler", "alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler",
"Already have an account?": "Zaten bir hesabınız mı var?", "Already have an account?": "Zaten bir hesabınız mı var?",
"an assistant": "bir asistan", "an assistant": "bir asistan",
@ -68,7 +68,7 @@
"Base Model (From)": "Temel Model ('den)", "Base Model (From)": "Temel Model ('den)",
"before": "önce", "before": "önce",
"Being lazy": "Tembelleşiyor", "Being lazy": "Tembelleşiyor",
"Brave Search API Key": "Cesur Arama API Anahtarı", "Brave Search API Key": "Brave Search API Anahtarı",
"Bypass SSL verification for Websites": "Web Siteleri için SSL doğrulamasını atlayın", "Bypass SSL verification for Websites": "Web Siteleri için SSL doğrulamasını atlayın",
"Cancel": "İptal", "Cancel": "İptal",
"Capabilities": "Yetenekler", "Capabilities": "Yetenekler",
@ -170,7 +170,7 @@
"Edit Doc": "Belgeyi Düzenle", "Edit Doc": "Belgeyi Düzenle",
"Edit User": "Kullanıcıyı Düzenle", "Edit User": "Kullanıcıyı Düzenle",
"Email": "E-posta", "Email": "E-posta",
"Embedding Batch Size": "", "Embedding Batch Size": "Gömme Yığın Boyutu",
"Embedding Model": "Gömme Modeli", "Embedding Model": "Gömme Modeli",
"Embedding Model Engine": "Gömme Modeli Motoru", "Embedding Model Engine": "Gömme Modeli Motoru",
"Embedding model set to \"{{embedding_model}}\"": "Gömme modeli \"{{embedding_model}}\" olarak ayarlandı", "Embedding model set to \"{{embedding_model}}\"": "Gömme modeli \"{{embedding_model}}\" olarak ayarlandı",
@ -187,7 +187,7 @@
"Enter Chunk Size": "Chunk Boyutunu Girin", "Enter Chunk Size": "Chunk Boyutunu Girin",
"Enter Github Raw URL": "Github Raw URL'sini girin", "Enter Github Raw URL": "Github Raw URL'sini girin",
"Enter Google PSE API Key": "Google PSE API Anahtarını Girin", "Enter Google PSE API Key": "Google PSE API Anahtarını Girin",
"Enter Google PSE Engine Id": "Google PSE Motor Kimliğini Girin", "Enter Google PSE Engine Id": "Google PSE Engine Id'sini Girin",
"Enter Image Size (e.g. 512x512)": "Görüntü Boyutunu Girin (örn. 512x512)", "Enter Image Size (e.g. 512x512)": "Görüntü Boyutunu Girin (örn. 512x512)",
"Enter language codes": "Dil kodlarını girin", "Enter language codes": "Dil kodlarını girin",
"Enter model tag (e.g. {{modelTag}})": "Model etiketini girin (örn. {{modelTag}})", "Enter model tag (e.g. {{modelTag}})": "Model etiketini girin (örn. {{modelTag}})",
@ -206,9 +206,9 @@
"Enter Your Role": "Rolünüzü Girin", "Enter Your Role": "Rolünüzü Girin",
"Error": "Hata", "Error": "Hata",
"Experimental": "Deneysel", "Experimental": "Deneysel",
"Export": "Ihracat", "Export": "Dışa Aktar",
"Export All Chats (All Users)": "Tüm Sohbetleri Dışa Aktar (Tüm Kullanıcılar)", "Export All Chats (All Users)": "Tüm Sohbetleri Dışa Aktar (Tüm Kullanıcılar)",
"Export chat (.json)": "", "Export chat (.json)": "Sohbeti dışa aktar (.json)",
"Export Chats": "Sohbetleri Dışa Aktar", "Export Chats": "Sohbetleri Dışa Aktar",
"Export Documents Mapping": "Belge Eşlemesini Dışa Aktar", "Export Documents Mapping": "Belge Eşlemesini Dışa Aktar",
"Export Models": "Modelleri Dışa Aktar", "Export Models": "Modelleri Dışa Aktar",
@ -232,7 +232,7 @@
"Generation Info": "Üretim Bilgisi", "Generation Info": "Üretim Bilgisi",
"Good Response": "İyi Yanıt", "Good Response": "İyi Yanıt",
"Google PSE API Key": "Google PSE API Anahtarı", "Google PSE API Key": "Google PSE API Anahtarı",
"Google PSE Engine Id": "Google PSE Motor Kimliği", "Google PSE Engine Id": "Google PSE Engine Id",
"h:mm a": "h:mm a", "h:mm a": "h:mm a",
"has no conversations.": "hiç konuşması yok.", "has no conversations.": "hiç konuşması yok.",
"Hello, {{name}}": "Merhaba, {{name}}", "Hello, {{name}}": "Merhaba, {{name}}",
@ -292,7 +292,7 @@
"Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' zaten indirme sırasında.", "Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' zaten indirme sırasında.",
"Model {{modelId}} not found": "{{modelId}} bulunamadı", "Model {{modelId}} not found": "{{modelId}} bulunamadı",
"Model {{modelName}} is not vision capable": "Model {{modelName}} görüntü yeteneğine sahip değil", "Model {{modelName}} is not vision capable": "Model {{modelName}} görüntü yeteneğine sahip değil",
"Model {{name}} is now {{status}}": "{{name}} modeli artık {{status}} oldu", "Model {{name}} is now {{status}}": "{{name}} modeli artık {{status}}",
"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 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 ID",
"Model not selected": "Model seçilmedi", "Model not selected": "Model seçilmedi",
@ -347,8 +347,8 @@
"pending": "beklemede", "pending": "beklemede",
"Permission denied when accessing microphone: {{error}}": "Mikrofona erişim izni reddedildi: {{error}}", "Permission denied when accessing microphone: {{error}}": "Mikrofona erişim izni reddedildi: {{error}}",
"Personalization": "Kişiselleştirme", "Personalization": "Kişiselleştirme",
"Pipelines": "Boru hattı", "Pipelines": "Pipelinelar",
"Pipelines Valves": "Boru Hatları Vanaları", "Pipelines Valves": "Pipeline Valvleri",
"Plain text (.txt)": "Düz metin (.txt)", "Plain text (.txt)": "Düz metin (.txt)",
"Playground": "Oyun Alanı", "Playground": "Oyun Alanı",
"Positive attitude": "Olumlu yaklaşım", "Positive attitude": "Olumlu yaklaşım",

View File

@ -36,6 +36,7 @@
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import { getBanners } from '$lib/apis/configs'; import { getBanners } from '$lib/apis/configs';
import { getUserSettings } from '$lib/apis/users'; import { getUserSettings } from '$lib/apis/users';
import Help from '$lib/components/layout/Help.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -160,7 +161,7 @@
if (isCtrlPressed && event.key === '/') { if (isCtrlPressed && event.key === '/') {
event.preventDefault(); event.preventDefault();
console.log('showShortcuts'); console.log('showShortcuts');
showShortcutsButtonElement.click(); document.getElementById('show-shortcuts-button')?.click();
} }
}); });
@ -175,22 +176,7 @@
}); });
</script> </script>
<div class=" hidden lg:flex fixed bottom-0 right-0 px-2 py-2 z-10"> <Help />
<Tooltip content={$i18n.t('Help')} placement="left">
<button
id="show-shortcuts-button"
bind:this={showShortcutsButtonElement}
class="text-gray-600 dark:text-gray-300 bg-gray-300/20 size-5 flex items-center justify-center text-[0.7rem] rounded-full"
on:click={() => {
showShortcuts = !showShortcuts;
}}
>
?
</button>
</Tooltip>
</div>
<ShortcutsModal bind:show={showShortcuts} />
<SettingsModal bind:show={$showSettings} /> <SettingsModal bind:show={$showSettings} />
<ChangelogModal bind:show={$showChangelog} /> <ChangelogModal bind:show={$showChangelog} />