forked from open-webui/open-webui
		
	Merge pull request #880 from open-webui/custom-name
feat: sponsor custom name support
This commit is contained in:
		
						commit
						9e287262f0
					
				
					 17 changed files with 94 additions and 44 deletions
				
			
		|  | @ -1,13 +1,17 @@ | |||
| import os | ||||
| import chromadb | ||||
| from chromadb import Settings | ||||
| from secrets import token_bytes | ||||
| from base64 import b64encode | ||||
| from constants import ERROR_MESSAGES | ||||
| from bs4 import BeautifulSoup | ||||
| 
 | ||||
| from pathlib import Path | ||||
| import json | ||||
| import markdown | ||||
| from bs4 import BeautifulSoup | ||||
| import requests | ||||
| import shutil | ||||
| 
 | ||||
| from secrets import token_bytes | ||||
| from constants import ERROR_MESSAGES | ||||
| 
 | ||||
| 
 | ||||
| try: | ||||
|  | @ -17,6 +21,8 @@ try: | |||
| except ImportError: | ||||
|     print("dotenv not installed, skipping...") | ||||
| 
 | ||||
| WEBUI_NAME = "Open WebUI" | ||||
| 
 | ||||
| 
 | ||||
| #################################### | ||||
| # ENV (dev,test,prod) | ||||
|  | @ -24,7 +30,6 @@ except ImportError: | |||
| 
 | ||||
| ENV = os.environ.get("ENV", "dev") | ||||
| 
 | ||||
| 
 | ||||
| try: | ||||
|     with open(f"../package.json", "r") as f: | ||||
|         PACKAGE_DATA = json.load(f) | ||||
|  | @ -94,6 +99,32 @@ for version in soup.find_all("h2"): | |||
| 
 | ||||
| CHANGELOG = changelog_json | ||||
| 
 | ||||
| 
 | ||||
| #################################### | ||||
| # CUSTOM_NAME | ||||
| #################################### | ||||
| 
 | ||||
| CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "") | ||||
| if CUSTOM_NAME: | ||||
|     r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}") | ||||
|     data = r.json() | ||||
| 
 | ||||
|     if "logo" in data: | ||||
|         url = ( | ||||
|             f"https://api.openwebui.com{data['logo']}" | ||||
|             if data["logo"][0] == "/" | ||||
|             else data["logo"] | ||||
|         ) | ||||
| 
 | ||||
|         r = requests.get(url, stream=True) | ||||
|         if r.status_code == 200: | ||||
|             with open("./static/favicon.png", "wb") as f: | ||||
|                 r.raw.decode_content = True | ||||
|                 shutil.copyfileobj(r.raw, f) | ||||
| 
 | ||||
|     WEBUI_NAME = data["name"] | ||||
| 
 | ||||
| 
 | ||||
| #################################### | ||||
| # DATA/FRONTEND BUILD DIR | ||||
| #################################### | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ from apps.rag.main import app as rag_app | |||
| 
 | ||||
| from apps.web.main import app as webui_app | ||||
| 
 | ||||
| from config import ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR | ||||
| from config import WEBUI_NAME, ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR | ||||
| 
 | ||||
| 
 | ||||
| class SPAStaticFiles(StaticFiles): | ||||
|  | @ -72,6 +72,7 @@ async def get_app_config(): | |||
| 
 | ||||
|     return { | ||||
|         "status": True, | ||||
|         "name": WEBUI_NAME, | ||||
|         "version": VERSION, | ||||
|         "images": images_app.state.ENABLED, | ||||
|         "default_models": webui_app.state.DEFAULT_MODELS, | ||||
|  | @ -84,6 +85,9 @@ async def get_app_changelog(): | |||
|     return CHANGELOG | ||||
| 
 | ||||
| 
 | ||||
| app.mount("/static", StaticFiles(directory="static"), name="static") | ||||
| 
 | ||||
| 
 | ||||
| app.mount( | ||||
|     "/", | ||||
|     SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True), | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								backend/static/favicon.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								backend/static/favicon.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 6 KiB | 
|  | @ -2,9 +2,9 @@ | |||
| 	import { onMount } from 'svelte'; | ||||
| 	import { Confetti } from 'svelte-confetti'; | ||||
| 
 | ||||
| 	import { config } from '$lib/stores'; | ||||
| 	import { WEBUI_NAME, config } from '$lib/stores'; | ||||
| 
 | ||||
| 	import { WEBUI_NAME, WEB_UI_VERSION } from '$lib/constants'; | ||||
| 	import { WEBUI_VERSION } from '$lib/constants'; | ||||
| 	import { getChangelog } from '$lib/apis'; | ||||
| 
 | ||||
| 	import Modal from './common/Modal.svelte'; | ||||
|  | @ -23,7 +23,7 @@ | |||
| 	<div class="px-5 py-4 dark:text-gray-300"> | ||||
| 		<div class="flex justify-between items-start"> | ||||
| 			<div class="text-xl font-bold"> | ||||
| 				What’s New in {WEBUI_NAME} | ||||
| 				What’s New in {$WEBUI_NAME} | ||||
| 				<Confetti x={[-1, -0.25]} y={[0, 0.5]} /> | ||||
| 			</div> | ||||
| 			<button | ||||
|  | @ -48,7 +48,7 @@ | |||
| 			<div class="text-sm dark:text-gray-200">Release Notes</div> | ||||
| 			<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" /> | ||||
| 			<div class="text-sm dark:text-gray-200"> | ||||
| 				v{WEB_UI_VERSION} | ||||
| 				v{WEBUI_VERSION} | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| <script lang="ts"> | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 
 | ||||
| 	export let models = []; | ||||
|  | @ -27,14 +28,16 @@ | |||
| 					> | ||||
| 						{#if model in modelfiles} | ||||
| 							<img | ||||
| 								src={modelfiles[model]?.imageUrl ?? './favicon.png'} | ||||
| 								src={modelfiles[model]?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png`} | ||||
| 								alt="modelfile" | ||||
| 								class=" w-14 rounded-full border-[1px] border-gray-200 dark:border-none" | ||||
| 								draggable="false" | ||||
| 							/> | ||||
| 						{:else} | ||||
| 							<img | ||||
| 								src={models.length === 1 ? '/favicon.png' : '/favicon.png'} | ||||
| 								src={models.length === 1 | ||||
| 									? `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 									: `${WEBUI_BASE_URL}/static/favicon.png`} | ||||
| 								class=" w-14 rounded-full border-[1px] border-gray-200 dark:border-none" | ||||
| 								alt="logo" | ||||
| 								draggable="false" | ||||
|  |  | |||
|  | @ -298,7 +298,9 @@ | |||
| 
 | ||||
| {#key message.id} | ||||
| 	<div class=" flex w-full message-{message.id}"> | ||||
| 		<ProfileImage src={modelfiles[message.model]?.imageUrl ?? '/favicon.png'} /> | ||||
| 		<ProfileImage | ||||
| 			src={modelfiles[message.model]?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png`} | ||||
| 		/> | ||||
| 
 | ||||
| 		<div class="w-full overflow-hidden"> | ||||
| 			<Name> | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| <script lang="ts"> | ||||
| 	import { getOllamaVersion } from '$lib/apis/ollama'; | ||||
| 	import { WEBUI_NAME, WEB_UI_VERSION } from '$lib/constants'; | ||||
| 	import { config, showChangelog } from '$lib/stores'; | ||||
| 	import { WEBUI_VERSION } from '$lib/constants'; | ||||
| 	import { WEBUI_NAME, config, showChangelog } from '$lib/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 
 | ||||
| 	let ollamaVersion = ''; | ||||
|  | @ -17,13 +17,13 @@ | |||
| 		<div> | ||||
| 			<div class=" mb-2.5 text-sm font-medium flex space-x-2 items-center"> | ||||
| 				<div> | ||||
| 					{WEBUI_NAME} Version | ||||
| 					{$WEBUI_NAME} Version | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="flex w-full"> | ||||
| 				<div class="flex-1 text-xs text-gray-700 dark:text-gray-200 flex space-x-1.5 items-center"> | ||||
| 					<div> | ||||
| 						v{WEB_UI_VERSION} | ||||
| 						v{WEBUI_VERSION} | ||||
| 					</div> | ||||
| 
 | ||||
| 					<button | ||||
|  |  | |||
|  | @ -3,8 +3,8 @@ | |||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
| 	import { createModel, deleteModel, pullModel } from '$lib/apis/ollama'; | ||||
| 	import { WEBUI_API_BASE_URL, WEBUI_NAME } from '$lib/constants'; | ||||
| 	import { models, user } from '$lib/stores'; | ||||
| 	import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import { WEBUI_NAME, models, user } from '$lib/stores'; | ||||
| 	import { splitStream } from '$lib/utils'; | ||||
| 
 | ||||
| 	export let getModels: Function; | ||||
|  | @ -59,9 +59,9 @@ | |||
| 				} else { | ||||
| 					toast.success(`Model '${modelName}' has been successfully downloaded.`); | ||||
| 
 | ||||
| 					const notification = new Notification(WEBUI_NAME, { | ||||
| 					const notification = new Notification($WEBUI_NAME, { | ||||
| 						body: `Model '${modelName}' has been successfully downloaded.`, | ||||
| 						icon: '/favicon.png' | ||||
| 						icon: `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 					}); | ||||
| 
 | ||||
| 					models.set(await getModels()); | ||||
|  |  | |||
|  | @ -4,14 +4,13 @@ | |||
| 	const { saveAs } = fileSaver; | ||||
| 
 | ||||
| 	import { getChatById } from '$lib/apis/chats'; | ||||
| 	import { chatId, modelfiles, settings } from '$lib/stores'; | ||||
| 	import { WEBUI_NAME, chatId, modelfiles, settings } from '$lib/stores'; | ||||
| 	import ShareChatModal from '../chat/ShareChatModal.svelte'; | ||||
| 	import TagInput from '../common/Tags/TagInput.svelte'; | ||||
| 	import Tags from '../common/Tags.svelte'; | ||||
| 	import { WEBUI_NAME } from '$lib/constants'; | ||||
| 
 | ||||
| 	export let initNewChat: Function; | ||||
| 	export let title: string = WEBUI_NAME; | ||||
| 	export let title: string = $WEBUI_NAME; | ||||
| 	export let shareEnabled: boolean = false; | ||||
| 
 | ||||
| 	export let tags = []; | ||||
|  | @ -102,7 +101,7 @@ | |||
| 			</div> | ||||
| 			<div class=" flex-1 self-center font-medium line-clamp-1"> | ||||
| 				<div> | ||||
| 					{title != '' ? title : WEBUI_NAME} | ||||
| 					{title != '' ? title : $WEBUI_NAME} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| 	} from '$lib/apis/chats'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 	import { slide } from 'svelte/transition'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 
 | ||||
| 	let show = false; | ||||
| 	let navElement; | ||||
|  | @ -114,7 +115,11 @@ | |||
| 			> | ||||
| 				<div class="flex self-center"> | ||||
| 					<div class="self-center mr-1.5"> | ||||
| 						<img src="/favicon.png" class=" w-7 -translate-x-1.5 rounded-full" alt="logo" /> | ||||
| 						<img | ||||
| 							src="{WEBUI_BASE_URL}/static/favicon.png" | ||||
| 							class=" w-7 -translate-x-1.5 rounded-full" | ||||
| 							alt="logo" | ||||
| 						/> | ||||
| 					</div> | ||||
| 
 | ||||
| 					<div class=" self-center font-medium text-sm">New Chat</div> | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { dev } from '$app/environment'; | ||||
| // import { version } from '../../package.json';
 | ||||
| 
 | ||||
| export const WEBUI_NAME = 'Open WebUI'; | ||||
| export const APP_NAME = 'Open WebUI'; | ||||
| export const WEBUI_BASE_URL = dev ? `http://${location.hostname}:8080` : ``; | ||||
| 
 | ||||
| export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`; | ||||
|  | @ -11,7 +11,7 @@ export const AUDIO_API_BASE_URL = `${WEBUI_BASE_URL}/audio/api/v1`; | |||
| export const IMAGES_API_BASE_URL = `${WEBUI_BASE_URL}/images/api/v1`; | ||||
| export const RAG_API_BASE_URL = `${WEBUI_BASE_URL}/rag/api/v1`; | ||||
| 
 | ||||
| export const WEB_UI_VERSION = APP_VERSION; | ||||
| export const WEBUI_VERSION = APP_VERSION; | ||||
| export const REQUIRED_OLLAMA_VERSION = '0.1.16'; | ||||
| 
 | ||||
| export const SUPPORTED_FILE_TYPE = [ | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| import { APP_NAME } from '$lib/constants'; | ||||
| import { writable } from 'svelte/store'; | ||||
| 
 | ||||
| // Backend
 | ||||
| export const WEBUI_NAME = writable(APP_NAME); | ||||
| export const config = writable(undefined); | ||||
| export const user = writable(undefined); | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ | |||
| 	import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; | ||||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import { RAGTemplate } from '$lib/utils/rag'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 
 | ||||
| 	let stopResponseFlag = false; | ||||
| 	let autoScroll = true; | ||||
|  | @ -334,7 +335,7 @@ | |||
| 						content: $settings.system | ||||
| 				  } | ||||
| 				: undefined, | ||||
| 			...messages.filter(message => !message.deleted) | ||||
| 			...messages.filter((message) => !message.deleted) | ||||
| 		] | ||||
| 			.filter((message) => message) | ||||
| 			.map((message, idx, arr) => ({ | ||||
|  | @ -452,7 +453,7 @@ | |||
| 												: `${model}`, | ||||
| 											{ | ||||
| 												body: responseMessage.content, | ||||
| 												icon: selectedModelfile?.imageUrl ?? '/favicon.png' | ||||
| 												icon: selectedModelfile?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 											} | ||||
| 										); | ||||
| 									} | ||||
|  | @ -540,7 +541,7 @@ | |||
| 							content: $settings.system | ||||
| 					  } | ||||
| 					: undefined, | ||||
| 			...messages.filter(message => !message.deleted) | ||||
| 				...messages.filter((message) => !message.deleted) | ||||
| 			] | ||||
| 				.filter((message) => message) | ||||
| 				.map((message, idx, arr) => ({ | ||||
|  | @ -622,7 +623,7 @@ | |||
| 				if ($settings.notificationEnabled && !document.hasFocus()) { | ||||
| 					const notification = new Notification(`OpenAI ${model}`, { | ||||
| 						body: responseMessage.content, | ||||
| 						icon: '/favicon.png' | ||||
| 						icon: `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 					}); | ||||
| 				} | ||||
| 
 | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ | |||
| 	import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; | ||||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import { RAGTemplate } from '$lib/utils/rag'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 
 | ||||
| 	let loaded = false; | ||||
| 
 | ||||
|  | @ -466,7 +467,7 @@ | |||
| 												: `${model}`, | ||||
| 											{ | ||||
| 												body: responseMessage.content, | ||||
| 												icon: selectedModelfile?.imageUrl ?? '/favicon.png' | ||||
| 												icon: selectedModelfile?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 											} | ||||
| 										); | ||||
| 									} | ||||
|  | @ -637,7 +638,7 @@ | |||
| 				if ($settings.notificationEnabled && !document.hasFocus()) { | ||||
| 					const notification = new Notification(`OpenAI ${model}`, { | ||||
| 						body: responseMessage.content, | ||||
| 						icon: '/favicon.png' | ||||
| 						icon: `${WEBUI_BASE_URL}/static/favicon.png` | ||||
| 					}); | ||||
| 				} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <script> | ||||
| 	import { onMount, tick } from 'svelte'; | ||||
| 	import { config, user, theme } from '$lib/stores'; | ||||
| 	import { config, user, theme, WEBUI_NAME } from '$lib/stores'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import toast, { Toaster } from 'svelte-french-toast'; | ||||
| 
 | ||||
|  | @ -10,7 +10,7 @@ | |||
| 	import '../app.css'; | ||||
| 	import '../tailwind.css'; | ||||
| 	import 'tippy.js/dist/tippy.css'; | ||||
| 	import { WEBUI_NAME } from '$lib/constants'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 
 | ||||
| 	let loaded = false; | ||||
| 
 | ||||
|  | @ -22,6 +22,8 @@ | |||
| 		if (backendConfig) { | ||||
| 			// Save Backend Status to Store | ||||
| 			await config.set(backendConfig); | ||||
| 
 | ||||
| 			await WEBUI_NAME.set(backendConfig.name); | ||||
| 			console.log(backendConfig); | ||||
| 
 | ||||
| 			if ($config) { | ||||
|  | @ -55,7 +57,8 @@ | |||
| </script> | ||||
| 
 | ||||
| <svelte:head> | ||||
| 	<title>{WEBUI_NAME}</title> | ||||
| 	<title>{$WEBUI_NAME}</title> | ||||
| 	<link rel="icon" href="{WEBUI_BASE_URL}/static/favicon.png" /> | ||||
| 
 | ||||
| 	<link rel="stylesheet" type="text/css" href="/themes/rosepine.css" /> | ||||
| 	<link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" /> | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| <script> | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { userSignIn, userSignUp } from '$lib/apis/auths'; | ||||
| 	import { WEBUI_API_BASE_URL, WEBUI_NAME } from '$lib/constants'; | ||||
| 	import { config, user } from '$lib/stores'; | ||||
| 	import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import { WEBUI_NAME, config, user } from '$lib/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
|  | @ -61,7 +61,7 @@ | |||
| 	<div class="fixed m-10 z-50"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/favicon.png" class=" w-8 rounded-full" alt="logo" /> | ||||
| 				<img src="{WEBUI_BASE_URL}/static/favicon.png" class=" w-8 rounded-full" alt="logo" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
|  | @ -90,12 +90,12 @@ | |||
| 					}} | ||||
| 				> | ||||
| 					<div class=" text-xl md:text-2xl font-bold"> | ||||
| 						{mode === 'signin' ? 'Sign in' : 'Sign up'} to {WEBUI_NAME} | ||||
| 						{mode === 'signin' ? 'Sign in' : 'Sign up'} to {$WEBUI_NAME} | ||||
| 					</div> | ||||
| 
 | ||||
| 					{#if mode === 'signup'} | ||||
| 						<div class=" mt-1 text-xs font-medium text-gray-500"> | ||||
| 							ⓘ {WEBUI_NAME} does not make any external connections, and your data stays securely on | ||||
| 							ⓘ {$WEBUI_NAME} does not make any external connections, and your data stays securely on | ||||
| 							your locally hosted server. | ||||
| 						</div> | ||||
| 					{/if} | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| <script> | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { WEBUI_NAME } from '$lib/constants'; | ||||
| 	import { config } from '$lib/stores'; | ||||
| 	import { WEBUI_NAME, config } from '$lib/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 
 | ||||
| 	let loaded = false; | ||||
|  | @ -20,7 +19,7 @@ | |||
| 		<div class="absolute rounded-xl w-full h-full backdrop-blur flex justify-center"> | ||||
| 			<div class="m-auto pb-44 flex flex-col justify-center"> | ||||
| 				<div class="max-w-md"> | ||||
| 					<div class="text-center text-2xl font-medium z-50">{WEBUI_NAME} Backend Required</div> | ||||
| 					<div class="text-center text-2xl font-medium z-50">{$WEBUI_NAME} Backend Required</div> | ||||
| 
 | ||||
| 					<div class=" mt-4 text-center text-sm w-full"> | ||||
| 						Oops! You're using an unsupported method (frontend only). Please serve the WebUI from | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek