forked from open-webui/open-webui
		
	
						commit
						13db1d5063
					
				
					 8 changed files with 110 additions and 9 deletions
				
			
		|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
|  |  | ||||||
|  | @ -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,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", | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -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 w-full justify-between items-center"> | ||||||
| 				<div class="flex-1 text-xs text-gray-700 dark:text-gray-200 flex space-x-1.5 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> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -101,11 +101,10 @@ export const copyToClipboard = (text) => { | ||||||
| 	); | 	); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const checkVersion = (required, current) => { | export const compareVersion = (latest, current) => { | ||||||
| 	// Returns true when current version is below required
 |  | ||||||
| 	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' | ||||||
|  |  | ||||||
|  | @ -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'}`); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek