Browse Source

Merge pull request #909 from open-webui/check-updates

Check updates
Timothy Jaeryang Baek 1 năm trước cách đây
mục cha
commit
13db1d5063

+ 6 - 0
CHANGELOG.md

@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 
+## [0.1.104] - UNRELEASED
+
+### Added
+
+- Check for updates in Settings > About.
+
 ## [0.1.103] - 2024-02-25
 ## [0.1.103] - 2024-02-25
 
 
 ### Added
 ### Added

+ 1 - 0
backend/constants.py

@@ -47,3 +47,4 @@ class ERROR_MESSAGES(str, Enum):
     INCORRECT_FORMAT = (
     INCORRECT_FORMAT = (
         lambda err="": f"Invalid format. Please use the correct format{err if err else ''}"
         lambda err="": f"Invalid format. Please use the correct format{err if err else ''}"
     )
     )
+    RATE_LIMIT_EXCEEDED = "API rate limit exceeded"

+ 21 - 1
backend/main.py

@@ -4,8 +4,9 @@ import markdown
 import time
 import time
 import os
 import os
 import sys
 import sys
+import requests
 
 
-from fastapi import FastAPI, Request, Depends
+from fastapi import FastAPI, Request, Depends, status
 from fastapi.staticfiles import StaticFiles
 from fastapi.staticfiles import StaticFiles
 from fastapi import HTTPException
 from fastapi import HTTPException
 from fastapi.responses import JSONResponse
 from fastapi.responses import JSONResponse
@@ -26,6 +27,8 @@ from apps.web.main import app as webui_app
 
 
 
 
 from config import WEBUI_NAME, ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR
 from config import WEBUI_NAME, ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR
+from constants import ERROR_MESSAGES
+
 from utils.utils import get_http_authorization_cred, get_current_user
 from utils.utils import get_http_authorization_cred, get_current_user
 
 
 
 
@@ -127,6 +130,23 @@ async def get_app_changelog():
     return CHANGELOG
     return CHANGELOG
 
 
 
 
+@app.get("/api/version/updates")
+async def get_app_latest_release_version():
+    try:
+        response = requests.get(
+            f"https://api.github.com/repos/open-webui/open-webui/releases/latest"
+        )
+        response.raise_for_status()
+        latest_version = response.json()["tag_name"]
+
+        return {"current": VERSION, "latest": latest_version[1:]}
+    except Exception as e:
+        raise HTTPException(
+            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
+            detail=ERROR_MESSAGES.RATE_LIMIT_EXCEEDED,
+        )
+
+
 app.mount("/static", StaticFiles(directory="static"), name="static")
 app.mount("/static", StaticFiles(directory="static"), name="static")
 
 
 
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
 	"name": "open-webui",
 	"name": "open-webui",
-	"version": "0.1.103",
+	"version": "0.1.104",
 	"private": true,
 	"private": true,
 	"scripts": {
 	"scripts": {
 		"dev": "vite dev --host",
 		"dev": "vite dev --host",

+ 34 - 0
src/lib/apis/index.ts

@@ -19,6 +19,10 @@ export const getBackendConfig = async () => {
 			return null;
 			return null;
 		});
 		});
 
 
+	if (error) {
+		throw error;
+	}
+
 	return res;
 	return res;
 };
 };
 
 
@@ -41,5 +45,35 @@ export const getChangelog = async () => {
 			return null;
 			return null;
 		});
 		});
 
 
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getVersionUpdates = async () => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/version/updates`, {
+		method: 'GET',
+		headers: {
+			'Content-Type': 'application/json'
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = err;
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
 	return res;
 	return res;
 };
 };

+ 43 - 2
src/lib/components/chat/Settings/About.svelte

@@ -1,14 +1,39 @@
 <script lang="ts">
 <script lang="ts">
+	import { getVersionUpdates } from '$lib/apis';
 	import { getOllamaVersion } from '$lib/apis/ollama';
 	import { getOllamaVersion } from '$lib/apis/ollama';
 	import { WEBUI_VERSION } from '$lib/constants';
 	import { WEBUI_VERSION } from '$lib/constants';
 	import { WEBUI_NAME, config, showChangelog } from '$lib/stores';
 	import { WEBUI_NAME, config, showChangelog } from '$lib/stores';
+	import { compareVersion } from '$lib/utils';
 	import { onMount } from 'svelte';
 	import { onMount } from 'svelte';
 
 
 	let ollamaVersion = '';
 	let ollamaVersion = '';
+
+	let updateAvailable = false;
+	let version = {
+		current: '',
+		latest: ''
+	};
+
+	const checkForVersionUpdates = async () => {
+		version = await getVersionUpdates(localStorage.token).catch((error) => {
+			return {
+				current: WEBUI_VERSION,
+				latest: WEBUI_VERSION
+			};
+		});
+
+		console.log(version);
+
+		updateAvailable = compareVersion(version.latest, version.current);
+		console.log(updateAvailable);
+	};
+
 	onMount(async () => {
 	onMount(async () => {
 		ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => {
 		ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => {
 			return '';
 			return '';
 		});
 		});
+
+		checkForVersionUpdates();
 	});
 	});
 </script>
 </script>
 
 
@@ -20,10 +45,17 @@
 					{$WEBUI_NAME} Version
 					{$WEBUI_NAME} Version
 				</div>
 				</div>
 			</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 class="flex w-full justify-between items-center">
+				<div class="flex flex-col text-xs text-gray-700 dark:text-gray-200">
 					<div>
 					<div>
 						v{WEBUI_VERSION}
 						v{WEBUI_VERSION}
+
+						<a
+							href="https://github.com/open-webui/open-webui/releases/tag/v{version.latest}"
+							target="_blank"
+						>
+							{updateAvailable ? `(v${version.latest} available!)` : '(latest)'}
+						</a>
 					</div>
 					</div>
 
 
 					<button
 					<button
@@ -35,6 +67,15 @@
 						<div>See what's new</div>
 						<div>See what's new</div>
 					</button>
 					</button>
 				</div>
 				</div>
+
+				<button
+					class=" text-xs px-3 py-1.5 bg-gray-100 hover:bg-gray-200 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-lg font-medium"
+					on:click={() => {
+						checkForVersionUpdates();
+					}}
+				>
+					Check for updates
+				</button>
 			</div>
 			</div>
 		</div>
 		</div>
 
 

+ 2 - 3
src/lib/utils/index.ts

@@ -101,11 +101,10 @@ export const copyToClipboard = (text) => {
 	);
 	);
 };
 };
 
 
-export const checkVersion = (required, current) => {
-	// Returns true when current version is below required
+export const compareVersion = (latest, current) => {
 	return current === '0.0.0'
 	return current === '0.0.0'
 		? false
 		? false
-		: current.localeCompare(required, undefined, {
+		: current.localeCompare(latest, undefined, {
 				numeric: true,
 				numeric: true,
 				sensitivity: 'case',
 				sensitivity: 'case',
 				caseFirst: 'upper'
 				caseFirst: 'upper'

+ 2 - 2
src/routes/(app)/+layout.svelte

@@ -28,7 +28,7 @@
 		config
 		config
 	} from '$lib/stores';
 	} from '$lib/stores';
 	import { REQUIRED_OLLAMA_VERSION, WEBUI_API_BASE_URL } from '$lib/constants';
 	import { REQUIRED_OLLAMA_VERSION, WEBUI_API_BASE_URL } from '$lib/constants';
-	import { checkVersion } from '$lib/utils';
+	import { compareVersion } from '$lib/utils';
 
 
 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
 	import Sidebar from '$lib/components/layout/Sidebar.svelte';
 	import Sidebar from '$lib/components/layout/Sidebar.svelte';
@@ -79,7 +79,7 @@
 		ollamaVersion = version;
 		ollamaVersion = version;
 
 
 		console.log(ollamaVersion);
 		console.log(ollamaVersion);
-		if (checkVersion(REQUIRED_OLLAMA_VERSION, ollamaVersion)) {
+		if (compareVersion(REQUIRED_OLLAMA_VERSION, ollamaVersion)) {
 			toast.error(`Ollama Version: ${ollamaVersion !== '' ? ollamaVersion : 'Not Detected'}`);
 			toast.error(`Ollama Version: ${ollamaVersion !== '' ? ollamaVersion : 'Not Detected'}`);
 		}
 		}
 	};
 	};