diff --git a/backend/open_webui/socket/main.py b/backend/open_webui/socket/main.py index 5aa7a4ff40..781f2cb1ae 100644 --- a/backend/open_webui/socket/main.py +++ b/backend/open_webui/socket/main.py @@ -23,6 +23,7 @@ from open_webui.config import ( ) from open_webui.env import ( + VERSION, ENABLE_WEBSOCKET_SUPPORT, WEBSOCKET_MANAGER, WEBSOCKET_REDIS_URL, diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts index 75a289d631..126c59ad2f 100644 --- a/src/lib/apis/index.ts +++ b/src/lib/apis/index.ts @@ -1401,6 +1401,33 @@ export const getChangelog = async () => { return res; }; +export const getVersion = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/version`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.error(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res?.version ?? null; +}; + export const getVersionUpdates = async (token: string) => { let error = null; diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 5fb3109062..87eb38aef2 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -8,6 +8,7 @@ import emojiShortCodes from '$lib/emoji-shortcodes.json'; // Backend export const WEBUI_NAME = writable(APP_NAME); +export const WEBUI_VERSION = writable(null); export const config: Writable = writable(undefined); export const user: Writable = writable(undefined); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 0ee7a486e7..3985413ebd 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -2,6 +2,7 @@ import { io } from 'socket.io-client'; import { spring } from 'svelte/motion'; import PyodideWorker from '$lib/workers/pyodide.worker?worker'; + import { Toaster, toast } from 'svelte-sonner'; let loadingProgress = spring(0, { stiffness: 0.05 @@ -14,6 +15,7 @@ settings, theme, WEBUI_NAME, + WEBUI_VERSION, mobile, socket, chatId, @@ -29,26 +31,25 @@ } from '$lib/stores'; import { goto } from '$app/navigation'; import { page } from '$app/stores'; - import { Toaster, toast } from 'svelte-sonner'; + import { beforeNavigate } from '$app/navigation'; + import { updated } from '$app/state'; - import { executeToolServer, getBackendConfig } from '$lib/apis'; - import { getSessionUser, userSignOut } from '$lib/apis/auths'; + import i18n, { initI18n, getLanguages, changeLanguage } from '$lib/i18n'; import '../tailwind.css'; import '../app.css'; - import 'tippy.js/dist/tippy.css'; - import { WEBUI_BASE_URL, WEBUI_HOSTNAME } from '$lib/constants'; - import i18n, { initI18n, getLanguages, changeLanguage } from '$lib/i18n'; - import { bestMatchingLanguage } from '$lib/utils'; + import { executeToolServer, getBackendConfig, getVersion } from '$lib/apis'; + import { getSessionUser, userSignOut } from '$lib/apis/auths'; import { getAllTags, getChatList } from '$lib/apis/chats'; - import NotificationToast from '$lib/components/NotificationToast.svelte'; - import AppSidebar from '$lib/components/app/AppSidebar.svelte'; import { chatCompletion } from '$lib/apis/openai'; - import { beforeNavigate } from '$app/navigation'; - import { updated } from '$app/state'; + import { WEBUI_BASE_URL, WEBUI_HOSTNAME } from '$lib/constants'; + import { bestMatchingLanguage } from '$lib/utils'; + + import NotificationToast from '$lib/components/NotificationToast.svelte'; + import AppSidebar from '$lib/components/app/AppSidebar.svelte'; import Spinner from '$lib/components/common/Spinner.svelte'; // handle frontend updates (https://svelte.dev/docs/kit/configuration#version) @@ -79,15 +80,25 @@ transports: enableWebsocket ? ['websocket'] : ['polling', 'websocket'], auth: { token: localStorage.token } }); - await socket.set(_socket); _socket.on('connect_error', (err) => { console.log('connect_error', err); }); - _socket.on('connect', () => { + _socket.on('connect', async () => { console.log('connected', _socket.id); + const version = await getVersion(localStorage.token); + if (version !== null) { + if ($WEBUI_VERSION !== null && version !== $WEBUI_VERSION) { + location.href = location.href; + } else { + WEBUI_VERSION.set(version); + } + } + + console.log('version', version); + if (localStorage.getItem('token')) { // Emit user-join event with auth token _socket.emit('user-join', { auth: { token: localStorage.token } });