This commit is contained in:
Timothy Jaeryang Baek
2026-07-27 19:39:36 -04:00
parent b6b16d5871
commit 810378c0b8
93 changed files with 440 additions and 12 deletions
+3
View File
@@ -18,6 +18,9 @@ def version_callback(value: bool) -> None:
if value:
from open_webui.env import VERSION
# LICENSE covers this Open WebUI CLI identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
typer.echo(f'Open WebUI version: {VERSION}')
raise typer.Exit()
+3
View File
@@ -2053,6 +2053,9 @@ DEFAULT_ARENA_MODEL = {
'id': 'arena-model',
'name': 'Arena Model',
'meta': {
# LICENSE covers this Open WebUI fallback logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'profile_image_url': '/favicon.png',
'description': 'Submit your questions to anonymous AI chatbots and vote on the best response.',
'model_ids': None,
+3
View File
@@ -121,6 +121,9 @@ class ERROR_MESSAGES(str, Enum):
FEATURE_DISABLED = lambda name='': f'{name} is disabled'
INPUT_TOO_LONG = lambda size='': f'Input prompt exceeds maximum length of {size}'
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
SERVER_CONNECTION_ERROR = 'Open WebUI: Server Connection Error'
REQUIRED_FIELD_EMPTY = lambda name='': f'Required field {name} is empty'
OAUTH_NOT_CONFIGURED = lambda name='': f"Provider '{name}' is not configured"
+6 -3
View File
@@ -888,14 +888,16 @@ if LICENSE_PUBLIC_KEY:
# WEBUI Identity
####################################
# LICENSE covers this Open WebUI name/logo/identifier.
# LICENSE covers this Open WebUI branding surface, including name, logo,
# visual, textual, symbolic identifiers, metadata, and surrounding UI.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
WEBUI_NAME = os.getenv('WEBUI_NAME', 'Open WebUI')
if WEBUI_NAME != 'Open WebUI':
WEBUI_NAME += ' (Open WebUI)'
# LICENSE covers this Open WebUI favicon identifier.
# LICENSE covers this Open WebUI branding surface, including this favicon
# and any visual, textual, or symbolic identifiers it preserves.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
WEBUI_FAVICON_URL = 'https://openwebui.com/favicon.png'
@@ -954,7 +956,8 @@ except ValueError:
# Progressive Web App
####################################
# LICENSE covers install-time Open WebUI branding.
# LICENSE covers this install-time Open WebUI branding surface, including
# names, logos, manifests, metadata, and surrounding UI.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
EXTERNAL_PWA_MANIFEST_URL = os.getenv('EXTERNAL_PWA_MANIFEST_URL', None)
+3
View File
@@ -1026,6 +1026,9 @@ def build_event(
async def dispatch_webhook_event(app: Any, event: Event) -> None:
# LICENSE covers this Open WebUI webhook identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
name = getattr(getattr(app, 'state', None), 'WEBUI_NAME', 'Open WebUI')
subject = event.subject or {}
subject_id = subject.get('id')
+12 -3
View File
@@ -320,6 +320,9 @@ https://github.com/open-webui/open-webui
print(banner)
except UnicodeEncodeError:
# Stdout can't encode the box-drawing banner (Windows cp1252, redirected/headless stdout); fall back to ASCII.
# LICENSE covers this Open WebUI CLI identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
print(f'Open WebUI v{VERSION} - building the best AI user interface.\nhttps://github.com/open-webui/open-webui')
@@ -461,6 +464,9 @@ async def lifespan(app: FastAPI):
# response_model routes keep FastAPI's Pydantic fast path either way.
apply_orjson_http_json()
# LICENSE covers this Open WebUI API metadata identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app = FastAPI(
title='Open WebUI',
docs_url='/docs' if ENV == 'dev' else None,
@@ -483,7 +489,8 @@ app.state.oauth_client_manager = oauth_client_manager
app.state.instance_id = None
app.state.redis = None
# LICENSE covers this Open WebUI name/logo/identifier.
# LICENSE covers this Open WebUI branding surface, including name, logo,
# visual, textual, symbolic identifiers, metadata, and surrounding UI.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app.state.WEBUI_NAME = WEBUI_NAME
@@ -2691,7 +2698,8 @@ async def oauth_backchannel_logout(
async def get_manifest_json():
external_pwa_manifest_url = getattr(app.state, 'EXTERNAL_PWA_MANIFEST_URL', None)
if external_pwa_manifest_url:
# LICENSE covers install-time Open WebUI branding.
# LICENSE covers this install-time Open WebUI branding surface, including
# names, logos, manifests, metadata, and surrounding UI.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
session = await get_session()
@@ -2702,7 +2710,8 @@ async def get_manifest_json():
r.raise_for_status()
return await r.json()
else:
# LICENSE covers generated Open WebUI install branding.
# LICENSE covers this generated Open WebUI install branding surface,
# including names, logos, manifests, metadata, and surrounding UI.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
return {
@@ -30,6 +30,9 @@ class ExternalWebLoader(BaseLoader):
response = requests.post(
self.external_url,
headers={
# LICENSE covers this Open WebUI user-agent identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'User-Agent': 'Open WebUI (https://github.com/open-webui/open-webui) External Web Loader',
'Authorization': f'Bearer {self.external_api_key}',
},
@@ -21,6 +21,9 @@ def search_external(
) -> List[SearchResult]:
try:
headers = {
# LICENSE covers this Open WebUI user-agent identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'User-Agent': 'Open WebUI (https://github.com/open-webui/open-webui) RAG Bot',
'Authorization': f'Bearer {external_api_key}',
}
@@ -12,6 +12,9 @@ log = logging.getLogger(__name__)
# SearXNG request headers — identifies the bot to instance operators.
_SEARXNG_HEADERS = {
# LICENSE covers this Open WebUI user-agent identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'User-Agent': 'Open WebUI (https://github.com/open-webui/open-webui) RAG Bot',
'Accept': 'text/html',
'Accept-Encoding': 'gzip, deflate',
+3
View File
@@ -59,6 +59,9 @@ def search_yacy(
query_url,
auth=yacy_auth,
headers={
# LICENSE covers this Open WebUI user-agent identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'User-Agent': 'Open WebUI (https://github.com/open-webui/open-webui) RAG Bot',
'Accept': 'text/html',
'Accept-Encoding': 'gzip, deflate',
@@ -41,6 +41,9 @@ def search_yandex(
) -> List[SearchResult]:
try:
headers = {
# LICENSE covers this Open WebUI user-agent identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'User-Agent': 'Open WebUI (https://github.com/open-webui/open-webui) RAG Bot',
'Authorization': f'Api-Key {yandex_search_api_key}',
}
+15
View File
@@ -330,6 +330,9 @@ def load_speech_pipeline(request):
async def _raise_tts_error(exc: Exception, r=None) -> None:
"""Raise a standardised HTTPException from a TTS provider failure."""
code = r.status if r is not None else 500
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
detail = 'Open WebUI: Server Connection Error'
if r is not None:
try:
@@ -711,6 +714,9 @@ async def _transcribe_openai(request, file_path, filename, languages, file_dir,
detail = f'External: {res["error"].get("message", "")}'
except Exception:
detail = f'External: {e}'
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise Exception(detail if detail else 'Open WebUI: Server Connection Error')
@@ -761,6 +767,9 @@ async def _transcribe_deepgram(request, file_path, languages, file_dir, id):
except Exception as e:
log.exception(e)
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
detail = 'Open WebUI: Server Connection Error'
if r is not None:
try:
@@ -890,6 +899,9 @@ async def _transcribe_azure(request, file_path, filename, file_dir, id):
detail = f'External: {res["error"].get("message", "")}'
except Exception:
detail = f'External: {e}'
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise HTTPException(
status_code=e.status if e.status else 500,
detail=detail if detail else 'Open WebUI: Server Connection Error',
@@ -1054,6 +1066,9 @@ async def _transcribe_mistral(request, file_path, filename, metadata, file_dir,
detail = f'External: {await r.text()}'
except Exception:
detail = f'External: {e}'
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise HTTPException(
status_code=e.status if e.status else 500,
detail=detail if detail else 'Open WebUI: Server Connection Error',
+6
View File
@@ -1809,6 +1809,9 @@ async def get_webhook_profile_image(webhook_id: str, user=Depends(get_verified_u
webhook = await Channels.get_webhook_by_id(webhook_id)
if not webhook:
# Return default favicon if webhook not found
# LICENSE covers this Open WebUI fallback logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
return FileResponse(f'{STATIC_DIR}/favicon.png')
if webhook.profile_image_url:
@@ -1834,6 +1837,9 @@ async def get_webhook_profile_image(webhook_id: str, user=Depends(get_verified_u
pass
# Return default favicon if no profile image
# LICENSE covers this Open WebUI fallback logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
return FileResponse(f'{STATIC_DIR}/favicon.png')
+6
View File
@@ -609,6 +609,9 @@ async def get_model_profile_image(
# only serve known-safe raster types inline; reject SVG/unknown (can run script on our origin)
if media_type not in PROFILE_IMAGE_ALLOWED_MIME_TYPES:
# LICENSE covers this Open WebUI fallback logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
return RedirectResponse(
url='/static/favicon.png',
status_code=status.HTTP_302_FOUND,
@@ -636,6 +639,9 @@ async def get_model_profile_image(
status_code=status.HTTP_302_FOUND,
)
# LICENSE covers this Open WebUI fallback logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
return RedirectResponse(
url='/static/favicon.png',
status_code=status.HTTP_302_FOUND,
@@ -94,6 +94,9 @@ async def set_default_notification_target(target_id: str, user=Depends(get_verif
async def test_notification_target(request: Request, target_id: str, user=Depends(get_verified_user)):
await _check_notifications_access(user)
try:
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app_name = getattr(request.app.state, 'WEBUI_NAME', 'Open WebUI')
return await test_target(user.id, target_id, app_name)
except ValueError as e:
+12
View File
@@ -166,6 +166,9 @@ async def get_headers_and_cookies(
'Content-Type': 'application/json',
**(
{
# LICENSE covers this Open WebUI upstream metadata identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'HTTP-Referer': 'https://openwebui.com/',
'X-Title': 'Open WebUI',
}
@@ -516,6 +519,9 @@ async def speech(request: Request, user=Depends(get_verified_user)):
except Exception:
detail = f'External: {e}'
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise HTTPException(
status_code=r.status if r else 500,
detail=detail if detail else 'Open WebUI: Server Connection Error',
@@ -773,6 +779,9 @@ async def get_models(request: Request, url_idx: int | None = None, user=Depends(
except aiohttp.ClientError as e:
# ClientError covers all aiohttp requests issues
log.exception(f'Client error: {str(e)}')
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise HTTPException(status_code=500, detail='Open WebUI: Server Connection Error')
except Exception as e:
log.exception(f'Unexpected error: {e}')
@@ -1784,6 +1793,9 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
raise
except Exception as e:
log.exception(e)
# LICENSE covers this Open WebUI error identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
raise HTTPException(
status_code=r.status if r else 500,
detail='Open WebUI: Server Connection Error',
+9
View File
@@ -0,0 +1,9 @@
# Open WebUI Branding Assets
This directory contains Open WebUI branding assets, including favicons, logos, splash images, app icons, and web app manifest icons.
Open WebUI branding in this directory includes assets, filenames, metadata, manifests, references, and surrounding UI that present or preserve the Open WebUI name, logo, visual, textual, or symbolic identifiers.
Do not alter, remove, obscure, or replace Open WebUI branding except as permitted by `LICENSE`.
See also: https://docs.openwebui.com/license.
+9
View File
@@ -0,0 +1,9 @@
# Open WebUI Branding Assets
This directory contains Open WebUI branding assets and references, including favicons, logos, splash images, app icons, manifests, metadata, and search identifiers.
Open WebUI branding here includes the name, logo, and any visual, textual, or symbolic identifiers that present or preserve Open WebUI attribution.
Do not alter, remove, obscure, or replace Open WebUI branding except as permitted by `LICENSE`.
See also: https://docs.openwebui.com/license.
+3
View File
@@ -138,6 +138,9 @@ async def notify(
return 'Notification failed: user not found.'
app_name = getattr(getattr(__request__, 'app', None), 'state', None)
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app_name = getattr(app_name, 'WEBUI_NAME', 'Open WebUI')
try:
result = await notify_target(user_id, message, target=target, title=title, app_name=app_name)
+3
View File
@@ -565,6 +565,9 @@ Conversation:
'messages': [
{
'role': 'system',
# LICENSE covers this Open WebUI system identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'content': "You are Open WebUI's private memory reviewer. Return only valid JSON.",
},
{'role': 'user', 'content': review_prompt},
+17 -1
View File
@@ -343,6 +343,9 @@ def _notification_webhook_content(event: Any) -> tuple[str, str, dict[str, Any],
return str(title), message, event.model_dump(), message if title else None
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
async def test_target(user_id: str, target_id: str, app_name: str = 'Open WebUI') -> dict[str, Any]:
notifications = await _load_notifications(user_id)
target = _find_target(notifications, target_id)
@@ -351,6 +354,9 @@ async def test_target(user_id: str, target_id: str, app_name: str = 'Open WebUI'
await _send_webhook(
app_name,
target,
# LICENSE covers this Open WebUI notification copy.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'This is a test notification from Open WebUI.',
{'action': 'test', 'user_id': user_id},
'Test notification',
@@ -358,8 +364,15 @@ async def test_target(user_id: str, target_id: str, app_name: str = 'Open WebUI'
return {'ok': True}
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
async def notify_target(
user_id: str, message: str, target: str = '', title: str = '', app_name: str = 'Open WebUI'
user_id: str,
message: str,
target: str = '',
title: str = '',
app_name: str = 'Open WebUI',
) -> dict[str, Any]:
notifications = await _load_notifications(user_id)
item = _find_target(notifications, target)
@@ -383,6 +396,9 @@ async def dispatch_notification_event(app: Any, event: Any) -> None:
from open_webui.events import event_user_ids
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app_name = getattr(getattr(app, 'state', None), 'WEBUI_NAME', 'Open WebUI')
for user_id in event_user_ids(event):
try:
+3
View File
@@ -506,6 +506,9 @@ async def get_oauth_client_info_with_dynamic_client_registration(
redirect_base_url = (str(webui_url or request.base_url)).rstrip('/')
oauth_client_metadata = OAuthClientMetadata(
# LICENSE covers this Open WebUI OAuth client identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
client_name='Open WebUI',
redirect_uris=[f'{redirect_base_url}/oauth/clients/{client_id}/callback'],
grant_types=['authorization_code', 'refresh_token'],
+4 -1
View File
@@ -14,10 +14,13 @@ _USER_PROFILE_IMAGE_RE = re.compile(r'^/api/v1/users/[^/?#]+/profile/image$')
_mime_suffixes = '|'.join(re.escape(t.split('/')[-1]) for t in sorted(PROFILE_IMAGE_ALLOWED_MIME_TYPES))
_SAFE_DATA_URI_RE = re.compile(rf'^data:image/({_mime_suffixes});base64,', re.IGNORECASE)
# Exact relative paths accepted as profile images. These are the only
# Exact relative paths accepted as profile images. These are the only
# static-asset paths OWUI itself assigns; no prefix/wildcard matching is
# used so that arbitrary relative paths cannot trigger authenticated GETs
# against internal endpoints when rendered as ``<img>`` sources.
# LICENSE covers the Open WebUI favicon fallback paths below. Do not alter,
# remove, obscure, or replace them except as LICENSE permits:
# https://docs.openwebui.com/license.
_SAFE_STATIC_PATHS = frozenset(
{
'/user.png',
+3
View File
@@ -69,6 +69,9 @@ async def post_webhook(name: str, url: str, message: str, event_data: dict, desc
{
'activityTitle': message,
'activitySubtitle': f'{name} ({VERSION}) - {action}',
# LICENSE covers this Open WebUI webhook logo.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
'activityImage': WEBUI_FAVICON_URL,
'text': description,
'facts': facts,