From 4b91ac352a9ab069bf8e34a3dd36336e50255b11 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 18:52:24 -0700 Subject: [PATCH 1/6] chore: i18n alphabetically ordering --- src/lib/i18n/locales/languages.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lib/i18n/locales/languages.json b/src/lib/i18n/locales/languages.json index c8de3e2e2..7e30ed926 100644 --- a/src/lib/i18n/locales/languages.json +++ b/src/lib/i18n/locales/languages.json @@ -4,8 +4,8 @@ "title": "English (US)" }, { - "code": "fa-IR", - "title": "فارسی (Farsi)" + "code": "ca-ES", + "title": "Catalan" }, { "code": "de-DE", @@ -16,13 +16,17 @@ "title": "Spanish" }, { - "code": "fr-FR", - "title": "French (France)" + "code": "fa-IR", + "title": "فارسی (Farsi)" }, { "code": "fr-CA", "title": "French (Canada)" }, + { + "code": "fr-FR", + "title": "French (France)" + }, { "code": "ru-RU", "title": "Russian (Russia)" @@ -32,19 +36,15 @@ "title": "Ukrainian" }, { - "code": "zh-TW", - "title": "Chinese (Traditional)" + "code": "vi-VN", + "title": "Tiếng Việt" }, { "code": "zh-CN", "title": "Chinese (Simplified)" }, - { - "code": "vi-VN", - "title": "Tiếng Việt" - }, { - "code": "ca-ES", - "title": "Catalan" + "code": "zh-TW", + "title": "Chinese (Traditional)" } -] +] \ No newline at end of file From 8cb7127fbca849f76324de791d8686ba2865ba1f Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 19:01:20 -0700 Subject: [PATCH 2/6] doc: changelog --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e6cfb87e..3d4d959df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ 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/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.114] - 2024-03-20 + +### Added + +- **🎉 Webhook Feature**: You can now subscribe to new user sign-up events by adding a webhook URL. Access it through the admin panel > admin settings > webhook URL. +- **🌍 Language Support**: Spanish, Catalan, and Vietnamese languages have been added, with enhancements made to existing languages. + +### Fixed + +- **🔧 Input Field Spelling**: Resolved issue with spelling mistakes in input fields. +- **🖊️ Light Mode Styling**: Fixed styling issue with light mode in document adding. + +### Changed + +- **🔄 Language Sorting**: Languages are now sorted alphabetically by their code for improved organization. + ## [0.1.113] - 2024-03-18 ### Added diff --git a/package.json b/package.json index bd1586ce5..e9e1fecf1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.1.113", + "version": "0.1.114", "private": true, "scripts": { "dev": "vite dev --host", From 93c90dc1860b54f998eb13f5daff856add9be38b Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 19:28:33 -0700 Subject: [PATCH 3/6] feat: litellm model filter support --- backend/apps/litellm/main.py | 65 +++++++++++++++++++++++++++++++++++- backend/config.py | 2 +- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/backend/apps/litellm/main.py b/backend/apps/litellm/main.py index 21b9e58a7..f7936398e 100644 --- a/backend/apps/litellm/main.py +++ b/backend/apps/litellm/main.py @@ -1,11 +1,23 @@ from litellm.proxy.proxy_server import ProxyConfig, initialize from litellm.proxy.proxy_server import app -from fastapi import FastAPI, Request, Depends, status +from fastapi import FastAPI, Request, Depends, status, Response from fastapi.responses import JSONResponse + +from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint +from starlette.responses import StreamingResponse +import json + from utils.utils import get_http_authorization_cred, get_current_user from config import ENV + +from config import ( + MODEL_FILTER_ENABLED, + MODEL_FILTER_LIST, +) + + proxy_config = ProxyConfig() @@ -26,16 +38,67 @@ async def on_startup(): await startup() +app.state.MODEL_FILTER_ENABLED = MODEL_FILTER_ENABLED +app.state.MODEL_FILTER_LIST = MODEL_FILTER_LIST + + @app.middleware("http") async def auth_middleware(request: Request, call_next): auth_header = request.headers.get("Authorization", "") + request.state.user = None if ENV != "dev": try: user = get_current_user(get_http_authorization_cred(auth_header)) print(user) + request.state.user = user except Exception as e: return JSONResponse(status_code=400, content={"detail": str(e)}) response = await call_next(request) return response + + +class ModifyModelsResponseMiddleware(BaseHTTPMiddleware): + async def dispatch( + self, request: Request, call_next: RequestResponseEndpoint + ) -> Response: + + response = await call_next(request) + user = request.state.user + + # Check if the request is for the `/models` route + if "/models" in request.url.path: + # Ensure the response is a StreamingResponse + if isinstance(response, StreamingResponse): + # Read the content of the streaming response + body = b"" + async for chunk in response.body_iterator: + body += chunk + + # Modify the content as needed + data = json.loads(body.decode("utf-8")) + + print(data) + + if app.state.MODEL_FILTER_ENABLED: + if user and user.role == "user": + data["data"] = list( + filter( + lambda model: model["id"] + in app.state.MODEL_FILTER_LIST, + data["data"], + ) + ) + + # Example modification: Add a new key-value pair + data["modified"] = True + + # Return a new JSON response with the modified content + return JSONResponse(content=data) + + return response + + +# Add the middleware to the app +app.add_middleware(ModifyModelsResponseMiddleware) diff --git a/backend/config.py b/backend/config.py index e99e248c5..9236e8a86 100644 --- a/backend/config.py +++ b/backend/config.py @@ -298,7 +298,7 @@ USER_PERMISSIONS_CHAT_DELETION = ( USER_PERMISSIONS = {"chat": {"deletion": USER_PERMISSIONS_CHAT_DELETION}} -MODEL_FILTER_ENABLED = os.environ.get("MODEL_FILTER_ENABLED", False) +MODEL_FILTER_ENABLED = os.environ.get("MODEL_FILTER_ENABLED", "False").lower() == "true" MODEL_FILTER_LIST = os.environ.get("MODEL_FILTER_LIST", "") MODEL_FILTER_LIST = [model.strip() for model in MODEL_FILTER_LIST.split(";")] From 1a240e103e4ed3567d679174cc2c8e0c79b166fe Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 19:31:15 -0700 Subject: [PATCH 4/6] doc: changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4d959df..3956e566c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- **🎉 Webhook Feature**: You can now subscribe to new user sign-up events by adding a webhook URL. Access it through the admin panel > admin settings > webhook URL. -- **🌍 Language Support**: Spanish, Catalan, and Vietnamese languages have been added, with enhancements made to existing languages. +- **🔗 Webhook Integration**: Now you can subscribe to new user sign-up events via webhook. Simply navigate to the admin panel > admin settings > webhook URL. +- **🛡️ Enhanced Model Filtering**: Alongside Ollama, OpenAI proxy model whitelisting, we've added model filtering functionality for LiteLLM proxy. +- **🌍 Expanded Language Support**: Spanish, Catalan, and Vietnamese languages are now available, with improvements made to others. ### Fixed From ed0d4b5a2aab93b802ee625d3e759e857bb07c43 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 19:32:25 -0700 Subject: [PATCH 5/6] chore: comment clean up --- backend/apps/litellm/main.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/backend/apps/litellm/main.py b/backend/apps/litellm/main.py index f7936398e..184212ee0 100644 --- a/backend/apps/litellm/main.py +++ b/backend/apps/litellm/main.py @@ -67,20 +67,15 @@ class ModifyModelsResponseMiddleware(BaseHTTPMiddleware): response = await call_next(request) user = request.state.user - # Check if the request is for the `/models` route if "/models" in request.url.path: - # Ensure the response is a StreamingResponse if isinstance(response, StreamingResponse): # Read the content of the streaming response body = b"" async for chunk in response.body_iterator: body += chunk - # Modify the content as needed data = json.loads(body.decode("utf-8")) - print(data) - if app.state.MODEL_FILTER_ENABLED: if user and user.role == "user": data["data"] = list( @@ -91,14 +86,11 @@ class ModifyModelsResponseMiddleware(BaseHTTPMiddleware): ) ) - # Example modification: Add a new key-value pair + # Modified Flag data["modified"] = True - - # Return a new JSON response with the modified content return JSONResponse(content=data) return response -# Add the middleware to the app app.add_middleware(ModifyModelsResponseMiddleware) From 8e52ba8b913264025322e31a0e8b94c5f9f6608b Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 20 Mar 2024 19:33:27 -0700 Subject: [PATCH 6/6] refac: auth required for litellm in dev --- backend/apps/litellm/main.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/backend/apps/litellm/main.py b/backend/apps/litellm/main.py index 184212ee0..838b47074 100644 --- a/backend/apps/litellm/main.py +++ b/backend/apps/litellm/main.py @@ -47,13 +47,12 @@ async def auth_middleware(request: Request, call_next): auth_header = request.headers.get("Authorization", "") request.state.user = None - if ENV != "dev": - try: - user = get_current_user(get_http_authorization_cred(auth_header)) - print(user) - request.state.user = user - except Exception as e: - return JSONResponse(status_code=400, content={"detail": str(e)}) + try: + user = get_current_user(get_http_authorization_cred(auth_header)) + print(user) + request.state.user = user + except Exception as e: + return JSONResponse(status_code=400, content={"detail": str(e)}) response = await call_next(request) return response