Merge branch 'main' into doc

This commit is contained in:
Timothy Jaeryang Baek 2024-02-24 16:39:18 -05:00 committed by GitHub
commit 384f79dcb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 436 additions and 176 deletions

View file

@ -423,7 +423,7 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
] or file_ext in ["xls", "xlsx"]: ] or file_ext in ["xls", "xlsx"]:
loader = UnstructuredExcelLoader(file_path) loader = UnstructuredExcelLoader(file_path)
elif file_ext in known_source_ext or file_content_type.find("text/") >= 0: elif file_ext in known_source_ext or (file_content_type and file_content_type.find("text/") >= 0):
loader = TextLoader(file_path) loader = TextLoader(file_path)
else: else:
loader = TextLoader(file_path) loader = TextLoader(file_path)
@ -486,8 +486,8 @@ def store_doc(
@app.get("/scan") @app.get("/scan")
def scan_docs_dir(user=Depends(get_admin_user)): def scan_docs_dir(user=Depends(get_admin_user)):
try:
for path in Path(DOCS_DIR).rglob("./**/*"): for path in Path(DOCS_DIR).rglob("./**/*"):
try:
if path.is_file() and not path.name.startswith("."): if path.is_file() and not path.name.startswith("."):
tags = extract_folders_after_data_docs(path) tags = extract_folders_after_data_docs(path)
filename = path.name filename = path.name

View file

@ -1,13 +1,17 @@
import os import os
import chromadb import chromadb
from chromadb import Settings from chromadb import Settings
from secrets import token_bytes
from base64 import b64encode from base64 import b64encode
from constants import ERROR_MESSAGES from bs4 import BeautifulSoup
from pathlib import Path from pathlib import Path
import json import json
import markdown import markdown
from bs4 import BeautifulSoup import requests
import shutil
from secrets import token_bytes
from constants import ERROR_MESSAGES
try: try:
@ -17,6 +21,8 @@ try:
except ImportError: except ImportError:
print("dotenv not installed, skipping...") print("dotenv not installed, skipping...")
WEBUI_NAME = "Open WebUI"
shutil.copyfile("../build/favicon.png", "./static/favicon.png")
#################################### ####################################
# ENV (dev,test,prod) # ENV (dev,test,prod)
@ -24,7 +30,6 @@ except ImportError:
ENV = os.environ.get("ENV", "dev") ENV = os.environ.get("ENV", "dev")
try: try:
with open(f"../package.json", "r") as f: with open(f"../package.json", "r") as f:
PACKAGE_DATA = json.load(f) PACKAGE_DATA = json.load(f)
@ -94,6 +99,36 @@ for version in soup.find_all("h2"):
CHANGELOG = changelog_json CHANGELOG = changelog_json
####################################
# CUSTOM_NAME
####################################
CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "")
if CUSTOM_NAME:
try:
r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}")
data = r.json()
if r.ok:
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"]
except Exception as e:
print(e)
pass
#################################### ####################################
# DATA/FRONTEND BUILD DIR # DATA/FRONTEND BUILD DIR
#################################### ####################################
@ -187,7 +222,7 @@ DEFAULT_PROMPT_SUGGESTIONS = (
) )
DEFAULT_USER_ROLE = "pending" DEFAULT_USER_ROLE = os.getenv("DEFAULT_USER_ROLE", "pending")
USER_PERMISSIONS = {"chat": {"deletion": True}} USER_PERMISSIONS = {"chat": {"deletion": True}}

View file

@ -20,7 +20,7 @@ from apps.rag.main import app as rag_app
from apps.web.main import app as webui_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): class SPAStaticFiles(StaticFiles):
@ -72,6 +72,7 @@ async def get_app_config():
return { return {
"status": True, "status": True,
"name": WEBUI_NAME,
"version": VERSION, "version": VERSION,
"images": images_app.state.ENABLED, "images": images_app.state.ENABLED,
"default_models": webui_app.state.DEFAULT_MODELS, "default_models": webui_app.state.DEFAULT_MODELS,
@ -84,6 +85,9 @@ async def get_app_changelog():
return CHANGELOG return CHANGELOG
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount( app.mount(
"/", "/",
SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True), SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True),

BIN
backend/static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -0,0 +1 @@
values-minikube.yaml

View file

@ -1,5 +1,21 @@
apiVersion: v2 apiVersion: v2
name: open-webui name: open-webui
description: "Open WebUI: A User-Friendly Web Interface for Chat Interactions 👋"
version: 1.0.0 version: 1.0.0
appVersion: "latest"
home: https://www.openwebui.com/
icon: https://raw.githubusercontent.com/open-webui/open-webui/main/static/favicon.png icon: https://raw.githubusercontent.com/open-webui/open-webui/main/static/favicon.png
description: "Open WebUI: A User-Friendly Web Interface for Chat Interactions 👋"
keywords:
- llm
- chat
- web-ui
sources:
- https://github.com/open-webui/open-webui/tree/main/kubernetes/helm
- https://hub.docker.com/r/ollama/ollama
- https://github.com/open-webui/open-webui/pkgs/container/open-webui
annotations:
licenses: MIT

View file

@ -0,0 +1,47 @@
{{- define "open-webui.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{- define "ollama.name" -}}
ollama
{{- end -}}
{{- define "ollama.url" -}}
{{- printf "http://%s.%s.svc.cluster.local:%d/api" (include "ollama.name" .) (.Release.Namespace) (.Values.ollama.service.port | int) }}
{{- end }}
{{- define "chart.name" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "base.labels" -}}
helm.sh/chart: {{ include "chart.name" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "base.selectorLabels" -}}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "open-webui.selectorLabels" -}}
{{ include "base.selectorLabels" . }}
app.kubernetes.io/component: {{ .Chart.Name }}
{{- end }}
{{- define "open-webui.labels" -}}
{{ include "base.labels" . }}
{{ include "open-webui.selectorLabels" . }}
{{- end }}
{{- define "ollama.selectorLabels" -}}
{{ include "base.selectorLabels" . }}
app.kubernetes.io/component: {{ include "ollama.name" . }}
{{- end }}
{{- define "ollama.labels" -}}
{{ include "base.labels" . }}
{{ include "ollama.selectorLabels" . }}
{{- end }}

View file

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace }}

View file

@ -1,13 +1,21 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: ollama-service name: {{ include "ollama.name" . }}
namespace: {{ .Values.namespace }} labels:
{{- include "ollama.labels" . | nindent 4 }}
{{- with .Values.ollama.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
type: {{ .Values.ollama.service.type }}
selector: selector:
app: ollama {{- include "ollama.selectorLabels" . | nindent 4 }}
{{- with .Values.ollama.service }}
type: {{ .type }}
ports: ports:
- protocol: TCP - protocol: TCP
port: {{ .Values.ollama.servicePort }} name: http
targetPort: {{ .Values.ollama.servicePort }} port: {{ .port }}
targetPort: http
{{- end }}

View file

@ -1,24 +1,43 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
name: ollama name: {{ include "ollama.name" . }}
namespace: {{ .Values.namespace }} labels:
{{- include "ollama.labels" . | nindent 4 }}
{{- with .Values.ollama.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
serviceName: "ollama" serviceName: {{ include "ollama.name" . }}
replicas: {{ .Values.ollama.replicaCount }} replicas: {{ .Values.ollama.replicaCount }}
selector: selector:
matchLabels: matchLabels:
app: ollama {{- include "ollama.selectorLabels" . | nindent 6 }}
template: template:
metadata: metadata:
labels: labels:
app: ollama {{- include "ollama.labels" . | nindent 8 }}
{{- with .Values.ollama.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec: spec:
enableServiceLinks: false
automountServiceAccountToken: false
{{- with .Values.ollama.runtimeClassName }}
runtimeClassName: {{ . }}
{{- end }}
containers: containers:
- name: ollama - name: {{ include "ollama.name" . }}
image: {{ .Values.ollama.image }} {{- with .Values.ollama.image }}
image: {{ .repository }}:{{ .tag }}
imagePullPolicy: {{ .pullPolicy }}
{{- end }}
tty: true
ports: ports:
- containerPort: {{ .Values.ollama.servicePort }} - name: http
containerPort: {{ .Values.ollama.service.containerPort }}
env: env:
{{- if .Values.ollama.gpu.enabled }} {{- if .Values.ollama.gpu.enabled }}
- name: PATH - name: PATH
@ -28,28 +47,50 @@ spec:
- name: NVIDIA_DRIVER_CAPABILITIES - name: NVIDIA_DRIVER_CAPABILITIES
value: compute,utility value: compute,utility
{{- end }} {{- end }}
{{- if .Values.ollama.resources }} {{- with .Values.ollama.resources }}
resources: {{- toYaml .Values.ollama.resources | nindent 10 }} resources: {{- toYaml . | nindent 10 }}
{{- end }} {{- end }}
volumeMounts: volumeMounts:
- name: ollama-volume - name: data
mountPath: /root/.ollama mountPath: /root/.ollama
tty: true
{{- with .Values.ollama.nodeSelector }} {{- with .Values.ollama.nodeSelector }}
nodeSelector: nodeSelector:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
{{- with .Values.ollama.tolerations }}
tolerations: tolerations:
{{- if .Values.ollama.gpu.enabled }} {{- toYaml . | nindent 8 }}
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
{{- end }} {{- end }}
volumes:
{{- if and .Values.ollama.persistence.enabled .Values.ollama.persistence.existingClaim }}
- name: data
persistentVolumeClaim:
claimName: {{ .Values.ollama.persistence.existingClaim }}
{{- else if not .Values.ollama.persistence.enabled }}
- name: data
emptyDir: {}
{{- else if and .Values.ollama.persistence.enabled (not .Values.ollama.persistence.existingClaim) }}
[]
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: ollama-volume name: data
labels:
{{- include "ollama.selectorLabels" . | nindent 8 }}
{{- with .Values.ollama.persistence.annotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec: spec:
accessModes: [ "ReadWriteOnce" ] accessModes:
{{- range .Values.ollama.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources: resources:
requests: requests:
storage: {{ .Values.ollama.volumeSize }} storage: {{ .Values.ollama.persistence.size | quote }}
storageClass: {{ .Values.ollama.persistence.storageClass }}
{{- with .Values.ollama.persistence.selector }}
selector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}

View file

@ -1,38 +1,62 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: open-webui-deployment name: {{ include "open-webui.name" . }}
namespace: {{ .Values.namespace }} labels:
{{- include "open-webui.labels" . | nindent 4 }}
{{- with .Values.webui.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
replicas: 1 replicas: {{ .Values.webui.replicaCount }}
selector: selector:
matchLabels: matchLabels:
app: open-webui {{- include "open-webui.selectorLabels" . | nindent 6 }}
template: template:
metadata: metadata:
labels: labels:
app: open-webui {{- include "open-webui.labels" . | nindent 8 }}
{{- with .Values.webui.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec: spec:
enableServiceLinks: false
automountServiceAccountToken: false
containers: containers:
- name: open-webui - name: {{ .Chart.Name }}
image: {{ .Values.webui.image }} {{- with .Values.webui.image }}
image: {{ .repository }}:{{ .tag | default $.Chart.AppVersion }}
imagePullPolicy: {{ .pullPolicy }}
{{- end }}
ports: ports:
- containerPort: 8080 - name: http
{{- if .Values.webui.resources }} containerPort: {{ .Values.webui.service.containerPort }}
resources: {{- toYaml .Values.webui.resources | nindent 10 }} {{- with .Values.webui.resources }}
resources: {{- toYaml . | nindent 10 }}
{{- end }} {{- end }}
volumeMounts: volumeMounts:
- name: webui-volume - name: data
mountPath: /app/backend/data mountPath: /app/backend/data
env: env:
- name: OLLAMA_API_BASE_URL - name: OLLAMA_API_BASE_URL
value: "http://ollama-service.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.ollama.servicePort }}/api" value: {{ include "ollama.url" . | quote }}
tty: true tty: true
{{- with .Values.webui.nodeSelector }} {{- with .Values.webui.nodeSelector }}
nodeSelector: nodeSelector:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
volumes: volumes:
- name: webui-volume {{- if and .Values.webui.persistence.enabled .Values.webui.persistence.existingClaim }}
- name: data
persistentVolumeClaim: persistentVolumeClaim:
claimName: open-webui-pvc claimName: {{ .Values.webui.persistence.existingClaim }}
{{- else if not .Values.webui.persistence.enabled }}
- name: data
emptyDir: {}
{{- else if and .Values.webui.persistence.enabled (not .Values.webui.persistence.existingClaim) }}
- name: data
persistentVolumeClaim:
claimName: {{ include "open-webui.name" . }}
{{- end }}

View file

@ -2,13 +2,23 @@
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: open-webui-ingress name: {{ include "open-webui.name" . }}
namespace: {{ .Values.namespace }} labels:
{{- if .Values.webui.ingress.annotations }} {{- include "open-webui.labels" . | nindent 4 }}
{{- with .Values.webui.ingress.annotations }}
annotations: annotations:
{{ toYaml .Values.webui.ingress.annotations | trimSuffix "\n" | indent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
spec: spec:
{{- with .Values.webui.ingress.class }}
ingressClassName: {{ . }}
{{- end }}
{{- if .Values.webui.ingress.tls }}
tls:
- hosts:
- {{ .Values.webui.ingress.host | quote }}
secretName: {{ default (printf "%s-tls" .Release.Name) .Values.webui.ingress.existingSecret }}
{{- end }}
rules: rules:
- host: {{ .Values.webui.ingress.host }} - host: {{ .Values.webui.ingress.host }}
http: http:
@ -17,7 +27,7 @@ spec:
pathType: Prefix pathType: Prefix
backend: backend:
service: service:
name: open-webui-service name: {{ include "open-webui.name" . }}
port: port:
number: {{ .Values.webui.servicePort }} name: http
{{- end }} {{- end }}

View file

@ -1,12 +1,25 @@
{{- if and .Values.webui.persistence.enabled (not .Values.webui.persistence.existingClaim) }}
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: {{ include "open-webui.name" . }}
labels: labels:
app: open-webui {{- include "open-webui.selectorLabels" . | nindent 4 }}
name: open-webui-pvc {{- with .Values.webui.persistence.annotations }}
namespace: {{ .Values.namespace }} annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec: spec:
accessModes: [ "ReadWriteOnce" ] accessModes:
{{- range .Values.webui.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources: resources:
requests: requests:
storage: {{ .Values.webui.volumeSize }} storage: {{ .Values.webui.persistence.size }}
storageClass: {{ .Values.webui.persistence.storageClass }}
{{- with .Values.webui.persistence.selector }}
selector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View file

@ -1,15 +1,24 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: open-webui-service name: {{ include "open-webui.name" . }}
namespace: {{ .Values.namespace }} labels:
{{- include "open-webui.labels" . | nindent 4 }}
{{- with .Values.webui.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
type: {{ .Values.webui.service.type }} # Default: NodePort # Use LoadBalancer if you're on a cloud that supports it
selector: selector:
app: open-webui {{- include "open-webui.selectorLabels" . | nindent 4 }}
{{- with .Values.webui.service }}
type: {{ .type }}
ports: ports:
- protocol: TCP - protocol: TCP
port: {{ .Values.webui.servicePort }} name: http
targetPort: {{ .Values.webui.servicePort }} port: {{ .port }}
# If using NodePort, you can optionally specify the nodePort: targetPort: http
# nodePort: 30000 {{- if .nodePort }}
nodePort: {{ .nodePort | int }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,27 @@
ollama:
resources:
requests:
cpu: "2000m"
memory: "2Gi"
limits:
cpu: "4000m"
memory: "4Gi"
nvidia.com/gpu: "0"
service:
type: ClusterIP
gpu:
enabled: false
webui:
resources:
requests:
cpu: "500m"
memory: "500Mi"
limits:
cpu: "1000m"
memory: "1Gi"
ingress:
enabled: true
host: open-webui.minikube.local
service:
type: NodePort

View file

@ -1,44 +1,72 @@
namespace: open-webui nameOverride: ""
ollama: ollama:
annotations: {}
podAnnotations: {}
replicaCount: 1 replicaCount: 1
image: ollama/ollama:latest image:
servicePort: 11434 repository: ollama/ollama
resources: tag: latest
requests: pullPolicy: Always
cpu: "2000m" resources: {}
memory: "2Gi" persistence:
limits: enabled: true
cpu: "4000m" size: 30Gi
memory: "4Gi" existingClaim: ""
nvidia.com/gpu: "0" accessModes:
volumeSize: 30Gi - ReadWriteOnce
storageClass: ""
selector: {}
annotations: {}
nodeSelector: {}
# -- If using a special runtime container such as nvidia, set it here.
runtimeClassName: ""
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
service:
type: ClusterIP
annotations: {}
port: 80
containerPort: 11434
gpu:
# -- Enable additional ENV values to help Ollama discover GPU usage
enabled: false
webui:
annotations: {}
podAnnotations: {}
replicaCount: 1
image:
repository: ghcr.io/open-webui/open-webui
tag: ""
pullPolicy: Always
resources: {}
ingress:
enabled: false
class: ""
# -- Use appropriate annotations for your Ingress controller, e.g., for NGINX:
# nginx.ingress.kubernetes.io/rewrite-target: /
annotations: {}
host: ""
tls: false
existingSecret: ""
persistence:
enabled: true
size: 2Gi
existingClaim: ""
# -- If using multiple replicas, you must update accessModes to ReadWriteMany
accessModes:
- ReadWriteOnce
storageClass: ""
selector: {}
annotations: {}
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
service: service:
type: ClusterIP type: ClusterIP
gpu: annotations: {}
enabled: false port: 80
containerPort: 8080
webui: nodePort: ""
replicaCount: 1
image: ghcr.io/open-webui/open-webui:main
servicePort: 8080
resources:
requests:
cpu: "500m"
memory: "500Mi"
limits:
cpu: "1000m"
memory: "1Gi"
ingress:
enabled: true
annotations:
# Use appropriate annotations for your Ingress controller, e.g., for NGINX:
# nginx.ingress.kubernetes.io/rewrite-target: /
host: open-webui.minikube.local
volumeSize: 2Gi
nodeSelector: {}
tolerations: []
service:
type: NodePort

View file

@ -4,7 +4,7 @@ metadata:
labels: labels:
app: ollama-webui app: ollama-webui
name: ollama-webui-pvc name: ollama-webui-pvc
namespace: ollama-namespace namespace: open-webui
spec: spec:
accessModes: ["ReadWriteOnce"] accessModes: ["ReadWriteOnce"]
resources: resources:

View file

@ -5,6 +5,7 @@ resources:
- base/webui-deployment.yaml - base/webui-deployment.yaml
- base/webui-service.yaml - base/webui-service.yaml
- base/webui-ingress.yaml - base/webui-ingress.yaml
- base/webui-pvc.yaml
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization

View file

@ -37,8 +37,8 @@ math {
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
height: 0.45rem; height: 0.4rem;
width: 0.35rem; width: 0.4rem;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {

View file

@ -2,9 +2,9 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { Confetti } from 'svelte-confetti'; 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 { getChangelog } from '$lib/apis';
import Modal from './common/Modal.svelte'; import Modal from './common/Modal.svelte';
@ -23,7 +23,7 @@
<div class="px-5 py-4 dark:text-gray-300"> <div class="px-5 py-4 dark:text-gray-300">
<div class="flex justify-between items-start"> <div class="flex justify-between items-start">
<div class="text-xl font-bold"> <div class="text-xl font-bold">
Whats New in {WEBUI_NAME} Whats New in {$WEBUI_NAME}
<Confetti x={[-1, -0.25]} y={[0, 0.5]} /> <Confetti x={[-1, -0.25]} y={[0, 0.5]} />
</div> </div>
<button <button
@ -48,7 +48,7 @@
<div class="text-sm dark:text-gray-200">Release Notes</div> <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="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"> <div class="text-sm dark:text-gray-200">
v{WEB_UI_VERSION} v{WEBUI_VERSION}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { WEBUI_BASE_URL } from '$lib/constants';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
export let models = []; export let models = [];
@ -27,14 +28,16 @@
> >
{#if model in modelfiles} {#if model in modelfiles}
<img <img
src={modelfiles[model]?.imageUrl ?? './favicon.png'} src={modelfiles[model]?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png`}
alt="modelfile" alt="modelfile"
class=" w-14 rounded-full border-[1px] border-gray-200 dark:border-none" class=" w-14 rounded-full border-[1px] border-gray-200 dark:border-none"
draggable="false" draggable="false"
/> />
{:else} {:else}
<img <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" class=" w-14 rounded-full border-[1px] border-gray-200 dark:border-none"
alt="logo" alt="logo"
draggable="false" draggable="false"

View file

@ -21,6 +21,7 @@
import Skeleton from './Skeleton.svelte'; import Skeleton from './Skeleton.svelte';
import CodeBlock from './CodeBlock.svelte'; import CodeBlock from './CodeBlock.svelte';
import Image from '$lib/components/common/Image.svelte'; import Image from '$lib/components/common/Image.svelte';
import { WEBUI_BASE_URL } from '$lib/constants';
export let modelfiles = []; export let modelfiles = [];
export let message; export let message;
@ -298,7 +299,9 @@
{#key message.id} {#key message.id}
<div class=" flex w-full message-{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"> <div class="w-full overflow-hidden">
<Name> <Name>

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { getOllamaVersion } from '$lib/apis/ollama'; import { getOllamaVersion } from '$lib/apis/ollama';
import { WEBUI_NAME, WEB_UI_VERSION } from '$lib/constants'; import { WEBUI_VERSION } from '$lib/constants';
import { config, showChangelog } from '$lib/stores'; import { WEBUI_NAME, config, showChangelog } from '$lib/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
let ollamaVersion = ''; let ollamaVersion = '';
@ -17,13 +17,13 @@
<div> <div>
<div class=" mb-2.5 text-sm font-medium flex space-x-2 items-center"> <div class=" mb-2.5 text-sm font-medium flex space-x-2 items-center">
<div> <div>
{WEBUI_NAME} Version {$WEBUI_NAME} Version
</div> </div>
</div> </div>
<div class="flex w-full"> <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 class="flex-1 text-xs text-gray-700 dark:text-gray-200 flex space-x-1.5 items-center">
<div> <div>
v{WEB_UI_VERSION} v{WEBUI_VERSION}
</div> </div>
<button <button

View file

@ -3,8 +3,8 @@
import toast from 'svelte-french-toast'; import toast from 'svelte-french-toast';
import { createModel, deleteModel, pullModel } from '$lib/apis/ollama'; import { createModel, deleteModel, pullModel } from '$lib/apis/ollama';
import { WEBUI_API_BASE_URL, WEBUI_NAME } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { models, user } from '$lib/stores'; import { WEBUI_NAME, models, user } from '$lib/stores';
import { splitStream } from '$lib/utils'; import { splitStream } from '$lib/utils';
export let getModels: Function; export let getModels: Function;
@ -59,9 +59,9 @@
} else { } else {
toast.success(`Model '${modelName}' has been successfully downloaded.`); 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.`, body: `Model '${modelName}' has been successfully downloaded.`,
icon: '/favicon.png' icon: `${WEBUI_BASE_URL}/static/favicon.png`
}); });
models.set(await getModels()); models.set(await getModels());

View file

@ -4,14 +4,13 @@
const { saveAs } = fileSaver; const { saveAs } = fileSaver;
import { getChatById } from '$lib/apis/chats'; 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 ShareChatModal from '../chat/ShareChatModal.svelte';
import TagInput from '../common/Tags/TagInput.svelte'; import TagInput from '../common/Tags/TagInput.svelte';
import Tags from '../common/Tags.svelte'; import Tags from '../common/Tags.svelte';
import { WEBUI_NAME } from '$lib/constants';
export let initNewChat: Function; export let initNewChat: Function;
export let title: string = WEBUI_NAME; export let title: string = $WEBUI_NAME;
export let shareEnabled: boolean = false; export let shareEnabled: boolean = false;
export let tags = []; export let tags = [];
@ -102,7 +101,7 @@
</div> </div>
<div class=" flex-1 self-center font-medium line-clamp-1"> <div class=" flex-1 self-center font-medium line-clamp-1">
<div> <div>
{title != '' ? title : WEBUI_NAME} {title != '' ? title : $WEBUI_NAME}
</div> </div>
</div> </div>

View file

@ -17,6 +17,7 @@
} from '$lib/apis/chats'; } from '$lib/apis/chats';
import toast from 'svelte-french-toast'; import toast from 'svelte-french-toast';
import { slide } from 'svelte/transition'; import { slide } from 'svelte/transition';
import { WEBUI_BASE_URL } from '$lib/constants';
let show = false; let show = false;
let navElement; let navElement;
@ -114,7 +115,11 @@
> >
<div class="flex self-center"> <div class="flex self-center">
<div class="self-center mr-1.5"> <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>
<div class=" self-center font-medium text-sm">New Chat</div> <div class=" self-center font-medium text-sm">New Chat</div>
@ -362,27 +367,11 @@
: ''} transition whitespace-nowrap text-ellipsis" : ''} transition whitespace-nowrap text-ellipsis"
href="/c/{chat.id}" href="/c/{chat.id}"
> >
<div class=" flex self-center flex-1"> <div class=" flex self-center flex-1 w-full">
<div class=" self-center mr-3">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 011.037-.443 48.282 48.282 0 005.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"
/>
</svg>
</div>
<div <div
class=" text-left self-center overflow-hidden {chat.id === $chatId class=" text-left self-center overflow-hidden {chat.id === $chatId
? 'w-[120px]' ? 'w-[160px]'
: 'w-[180px]'} " : 'w-full'} "
> >
{#if chatTitleEditId === chat.id} {#if chatTitleEditId === chat.id}
<input bind:value={chatTitle} class=" bg-transparent w-full" /> <input bind:value={chatTitle} class=" bg-transparent w-full" />

View file

@ -1,7 +1,7 @@
import { dev } from '$app/environment'; import { dev } from '$app/environment';
// import { version } from '../../package.json'; // 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_BASE_URL = dev ? `http://${location.hostname}:8080` : ``;
export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`; 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 IMAGES_API_BASE_URL = `${WEBUI_BASE_URL}/images/api/v1`;
export const RAG_API_BASE_URL = `${WEBUI_BASE_URL}/rag/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 REQUIRED_OLLAMA_VERSION = '0.1.16';
export const SUPPORTED_FILE_TYPE = [ export const SUPPORTED_FILE_TYPE = [

View file

@ -1,6 +1,8 @@
import { APP_NAME } from '$lib/constants';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
// Backend // Backend
export const WEBUI_NAME = writable(APP_NAME);
export const config = writable(undefined); export const config = writable(undefined);
export const user = writable(undefined); export const user = writable(undefined);

View file

@ -36,6 +36,7 @@
import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; import ModelSelector from '$lib/components/chat/ModelSelector.svelte';
import Navbar from '$lib/components/layout/Navbar.svelte'; import Navbar from '$lib/components/layout/Navbar.svelte';
import { RAGTemplate } from '$lib/utils/rag'; import { RAGTemplate } from '$lib/utils/rag';
import { WEBUI_BASE_URL } from '$lib/constants';
let stopResponseFlag = false; let stopResponseFlag = false;
let autoScroll = true; let autoScroll = true;
@ -334,7 +335,7 @@
content: $settings.system content: $settings.system
} }
: undefined, : undefined,
...messages.filter(message => !message.deleted) ...messages.filter((message) => !message.deleted)
] ]
.filter((message) => message) .filter((message) => message)
.map((message, idx, arr) => ({ .map((message, idx, arr) => ({
@ -452,7 +453,7 @@
: `${model}`, : `${model}`,
{ {
body: responseMessage.content, body: responseMessage.content,
icon: selectedModelfile?.imageUrl ?? '/favicon.png' icon: selectedModelfile?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png`
} }
); );
} }
@ -540,7 +541,7 @@
content: $settings.system content: $settings.system
} }
: undefined, : undefined,
...messages.filter(message => !message.deleted) ...messages.filter((message) => !message.deleted)
] ]
.filter((message) => message) .filter((message) => message)
.map((message, idx, arr) => ({ .map((message, idx, arr) => ({
@ -622,7 +623,7 @@
if ($settings.notificationEnabled && !document.hasFocus()) { if ($settings.notificationEnabled && !document.hasFocus()) {
const notification = new Notification(`OpenAI ${model}`, { const notification = new Notification(`OpenAI ${model}`, {
body: responseMessage.content, body: responseMessage.content,
icon: '/favicon.png' icon: `${WEBUI_BASE_URL}/static/favicon.png`
}); });
} }

View file

@ -37,6 +37,7 @@
import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; import ModelSelector from '$lib/components/chat/ModelSelector.svelte';
import Navbar from '$lib/components/layout/Navbar.svelte'; import Navbar from '$lib/components/layout/Navbar.svelte';
import { RAGTemplate } from '$lib/utils/rag'; import { RAGTemplate } from '$lib/utils/rag';
import { WEBUI_BASE_URL } from '$lib/constants';
let loaded = false; let loaded = false;
@ -466,7 +467,7 @@
: `${model}`, : `${model}`,
{ {
body: responseMessage.content, 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()) { if ($settings.notificationEnabled && !document.hasFocus()) {
const notification = new Notification(`OpenAI ${model}`, { const notification = new Notification(`OpenAI ${model}`, {
body: responseMessage.content, body: responseMessage.content,
icon: '/favicon.png' icon: `${WEBUI_BASE_URL}/static/favicon.png`
}); });
} }

View file

@ -1,6 +1,6 @@
<script> <script>
import { onMount, tick } from 'svelte'; 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 { goto } from '$app/navigation';
import toast, { Toaster } from 'svelte-french-toast'; import toast, { Toaster } from 'svelte-french-toast';
@ -10,7 +10,7 @@
import '../app.css'; import '../app.css';
import '../tailwind.css'; import '../tailwind.css';
import 'tippy.js/dist/tippy.css'; import 'tippy.js/dist/tippy.css';
import { WEBUI_NAME } from '$lib/constants'; import { WEBUI_BASE_URL } from '$lib/constants';
let loaded = false; let loaded = false;
@ -22,6 +22,8 @@
if (backendConfig) { if (backendConfig) {
// Save Backend Status to Store // Save Backend Status to Store
await config.set(backendConfig); await config.set(backendConfig);
await WEBUI_NAME.set(backendConfig.name);
console.log(backendConfig); console.log(backendConfig);
if ($config) { if ($config) {
@ -55,7 +57,8 @@
</script> </script>
<svelte:head> <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.css" />
<link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" /> <link rel="stylesheet" type="text/css" href="/themes/rosepine-dawn.css" />

View file

@ -1,8 +1,8 @@
<script> <script>
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { userSignIn, userSignUp } from '$lib/apis/auths'; import { userSignIn, userSignUp } from '$lib/apis/auths';
import { WEBUI_API_BASE_URL, WEBUI_NAME } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { config, user } from '$lib/stores'; import { WEBUI_NAME, config, user } from '$lib/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import toast from 'svelte-french-toast'; import toast from 'svelte-french-toast';
@ -61,7 +61,7 @@
<div class="fixed m-10 z-50"> <div class="fixed m-10 z-50">
<div class="flex space-x-2"> <div class="flex space-x-2">
<div class=" self-center"> <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> </div>
</div> </div>
@ -90,12 +90,12 @@
}} }}
> >
<div class=" text-xl md:text-2xl font-bold"> <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> </div>
{#if mode === 'signup'} {#if mode === 'signup'}
<div class=" mt-1 text-xs font-medium text-gray-500"> <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. your locally hosted server.
</div> </div>
{/if} {/if}

View file

@ -1,7 +1,6 @@
<script> <script>
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { WEBUI_NAME } from '$lib/constants'; import { WEBUI_NAME, config } from '$lib/stores';
import { config } from '$lib/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
let loaded = false; let loaded = false;
@ -20,7 +19,7 @@
<div class="absolute rounded-xl w-full h-full backdrop-blur flex justify-center"> <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="m-auto pb-44 flex flex-col justify-center">
<div class="max-w-md"> <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"> <div class=" mt-4 text-center text-sm w-full">
Oops! You're using an unsupported method (frontend only). Please serve the WebUI from Oops! You're using an unsupported method (frontend only). Please serve the WebUI from