From 0afe972bc6bf3b52a77832a32d39607570457826 Mon Sep 17 00:00:00 2001 From: hdnh2006 Date: Fri, 14 Feb 2025 17:57:47 +0100 Subject: [PATCH 001/168] embeddings function added 100% OpenAI compatible --- backend/open_webui/main.py | 5 ++ backend/open_webui/routers/openai.py | 74 ++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index a363231512..79d56795d4 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1038,6 +1038,11 @@ async def list_tasks_endpoint(user=Depends(get_verified_user)): return {"tasks": list_tasks()} # Use the function from tasks.py +@app.post("/api/embeddings") +async def api_embeddings(request: Request, user=Depends(get_verified_user)): + return await openai.generate_embeddings(request=request, user=user) + + ################################## # # Config Endpoints diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index afda362373..1b707150ee 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -715,6 +715,80 @@ async def generate_chat_completion( r.close() await session.close() +@router.post("/embeddings") +async def generate_embeddings(request: Request, user=Depends(get_verified_user)): + """ + Call embeddings endpoint + """ + + body = await request.body() + + idx = 0 + url = request.app.state.config.OPENAI_API_BASE_URLS[idx] + key = request.app.state.config.OPENAI_API_KEYS[idx] + + r = None + session = None + streaming = False + + try: + session = aiohttp.ClientSession(trust_env=True) + r = await session.request( + method=request.method, + url=f"{url}/embeddings", + data=body, + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) + r.raise_for_status() + + # Check if response is SSE + if "text/event-stream" in r.headers.get("Content-Type", ""): + streaming = True + return StreamingResponse( + r.content, + status_code=r.status, + headers=dict(r.headers), + background=BackgroundTask( + cleanup_response, response=r, session=session + ), + ) + else: + response_data = await r.json() + return response_data + + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = await r.json() + if "error" in res: + detail = f"External: {res['error']['message'] if 'message' in res['error'] else res['error']}" + except Exception: + detail = f"External: {e}" + raise HTTPException( + status_code=r.status if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + finally: + if not streaming and session: + if r: + r.close() + await session.close() @router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"]) async def proxy(path: str, request: Request, user=Depends(get_verified_user)): From cbc514e68192885f210a7165b844b0eb91a53c34 Mon Sep 17 00:00:00 2001 From: sanae artoria Date: Sat, 31 May 2025 01:13:38 +0800 Subject: [PATCH 002/168] The translation might be confusing, in some cases for example tooltips over a radio button --- src/lib/i18n/locales/zh-CN/translation.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 6b28f9e2a7..f55ed9c754 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -339,7 +339,7 @@ "Direct Tool Servers": "直接连接工具服务器", "Disable Image Extraction": "禁用图像提取", "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "禁用从 PDF 中提取图像。若开启 '使用大语言模型(LLM)' 功能,图像将自动添加描述。默认为关闭", - "Disabled": "禁用", + "Disabled": "已禁用", "Discover a function": "发现更多函数", "Discover a model": "发现更多模型", "Discover a prompt": "发现更多提示词", @@ -421,7 +421,7 @@ "Enable Message Rating": "启用回复评价", "Enable Mirostat sampling for controlling perplexity.": "启用 Mirostat 采样以控制困惑度", "Enable New Sign Ups": "允许新用户注册", - "Enabled": "启用", + "Enabled": "已启用", "Endpoint URL": "端点 URL", "Enforce Temporary Chat": "强制临时对话", "Enhance": "润色", From 96e9bfe0e55a0d0b6fea7c1ef1bd6faa3d4e530c Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 3 Jun 2025 00:19:08 +0200 Subject: [PATCH 003/168] feat: add Perplexity model and search context usage configuration options --- backend/open_webui/config.py | 12 +++++++ backend/open_webui/main.py | 4 +++ .../open_webui/retrieval/web/perplexity.py | 22 +++++++++++-- backend/open_webui/routers/retrieval.py | 19 +++++++---- .../admin/Settings/WebSearch.svelte | 32 +++++++++++++++++++ 5 files changed, 80 insertions(+), 9 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 0e0c08f2bb..c2ca9841cd 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2442,6 +2442,18 @@ PERPLEXITY_API_KEY = PersistentConfig( os.getenv("PERPLEXITY_API_KEY", ""), ) +PERPLEXITY_MODEL = PersistentConfig( + "PERPLEXITY_MODEL", + "rag.web.search.perplexity_model", + os.getenv("PERPLEXITY_MODEL", "sonar"), +) + +PERPLEXITY_SEARCH_CONTEXT_USAGE = PersistentConfig( + "PERPLEXITY_SEARCH_CONTEXT_USAGE", + "rag.web.search.perplexity_search_context_usage", + os.getenv("PERPLEXITY_SEARCH_CONTEXT_USAGE", "medium"), +) + SOUGOU_API_SID = PersistentConfig( "SOUGOU_API_SID", "rag.web.search.sougou_api_sid", diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 6bdcf4957a..545774fc0a 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -268,6 +268,8 @@ from open_webui.config import ( BRAVE_SEARCH_API_KEY, EXA_API_KEY, PERPLEXITY_API_KEY, + PERPLEXITY_MODEL, + PERPLEXITY_SEARCH_CONTEXT_USAGE, SOUGOU_API_SID, SOUGOU_API_SK, KAGI_SEARCH_API_KEY, @@ -771,6 +773,8 @@ app.state.config.BING_SEARCH_V7_ENDPOINT = BING_SEARCH_V7_ENDPOINT app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY app.state.config.EXA_API_KEY = EXA_API_KEY app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY +app.state.config.PERPLEXITY_MODEL = PERPLEXITY_MODEL +app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = PERPLEXITY_SEARCH_CONTEXT_USAGE app.state.config.SOUGOU_API_SID = SOUGOU_API_SID app.state.config.SOUGOU_API_SK = SOUGOU_API_SK app.state.config.EXTERNAL_WEB_SEARCH_URL = EXTERNAL_WEB_SEARCH_URL diff --git a/backend/open_webui/retrieval/web/perplexity.py b/backend/open_webui/retrieval/web/perplexity.py index e5314eb1f7..551cb2c4b4 100644 --- a/backend/open_webui/retrieval/web/perplexity.py +++ b/backend/open_webui/retrieval/web/perplexity.py @@ -1,10 +1,20 @@ import logging -from typing import Optional, List +from typing import Optional, Literal import requests from open_webui.retrieval.web.main import SearchResult, get_filtered_results from open_webui.env import SRC_LOG_LEVELS +MODELS = Literal[ + "sonar", + "sonar-pro", + "sonar-reasoning", + "sonar-reasoning-pro", + "sonar-deep-research", +] +SEARCH_CONTEXT_USAGE_LEVELS = Literal["low", "medium", "high"] + + log = logging.getLogger(__name__) log.setLevel(SRC_LOG_LEVELS["RAG"]) @@ -14,6 +24,8 @@ def search_perplexity( query: str, count: int, filter_list: Optional[list[str]] = None, + model: MODELS = "sonar", + search_context_usage: SEARCH_CONTEXT_USAGE_LEVELS = "medium", ) -> list[SearchResult]: """Search using Perplexity API and return the results as a list of SearchResult objects. @@ -21,6 +33,9 @@ def search_perplexity( api_key (str): A Perplexity API key query (str): The query to search for count (int): Maximum number of results to return + filter_list (Optional[list[str]]): List of domains to filter results + model (str): The Perplexity model to use (sonar, sonar-pro) + search_context_usage (str): Search context usage level (low, medium, high) """ @@ -33,7 +48,7 @@ def search_perplexity( # Create payload for the API call payload = { - "model": "sonar", + "model": model, "messages": [ { "role": "system", @@ -43,6 +58,9 @@ def search_perplexity( ], "temperature": 0.2, # Lower temperature for more factual responses "stream": False, + "web_search_options": { + "search_context_usage": search_context_usage, + } } headers = { diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 343b0513c9..22b264bfad 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -467,6 +467,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): "BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "EXA_API_KEY": request.app.state.config.EXA_API_KEY, "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, + "PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL, + "PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, @@ -520,6 +522,8 @@ class WebConfig(BaseModel): BING_SEARCH_V7_SUBSCRIPTION_KEY: Optional[str] = None EXA_API_KEY: Optional[str] = None PERPLEXITY_API_KEY: Optional[str] = None + PERPLEXITY_MODEL: Optional[str] = None + PERPLEXITY_SEARCH_CONTEXT_USAGE: Optional[str] = None SOUGOU_API_SID: Optional[str] = None SOUGOU_API_SK: Optional[str] = None WEB_LOADER_ENGINE: Optional[str] = None @@ -907,6 +911,10 @@ async def update_rag_config( ) request.app.state.config.EXA_API_KEY = form_data.web.EXA_API_KEY request.app.state.config.PERPLEXITY_API_KEY = form_data.web.PERPLEXITY_API_KEY + request.app.state.config.PERPLEXITY_MODEL = form_data.web.PERPLEXITY_MODEL + request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = ( + form_data.web.PERPLEXITY_SEARCH_CONTEXT_USAGE + ) request.app.state.config.SOUGOU_API_SID = form_data.web.SOUGOU_API_SID request.app.state.config.SOUGOU_API_SK = form_data.web.SOUGOU_API_SK @@ -1030,6 +1038,8 @@ async def update_rag_config( "BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "EXA_API_KEY": request.app.state.config.EXA_API_KEY, "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, + "PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL, + "PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, @@ -1740,19 +1750,14 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]: request.app.state.config.WEB_SEARCH_RESULT_COUNT, request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, ) - elif engine == "exa": - return search_exa( - request.app.state.config.EXA_API_KEY, - query, - request.app.state.config.WEB_SEARCH_RESULT_COUNT, - request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, - ) elif engine == "perplexity": return search_perplexity( request.app.state.config.PERPLEXITY_API_KEY, query, request.app.state.config.WEB_SEARCH_RESULT_COUNT, request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, + model=request.app.state.config.PERPLEXITY_MODEL, + search_context_usage=request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE, ) elif engine == "sougou": if ( diff --git a/src/lib/components/admin/Settings/WebSearch.svelte b/src/lib/components/admin/Settings/WebSearch.svelte index c0712d8ad1..e7630388e9 100644 --- a/src/lib/components/admin/Settings/WebSearch.svelte +++ b/src/lib/components/admin/Settings/WebSearch.svelte @@ -456,6 +456,38 @@ bind:value={webConfig.PERPLEXITY_API_KEY} /> + + +
+
+ {$i18n.t('Perplexity Model')} +
+ +
+ + +
+
+ {$i18n.t('Search Context Usage')} +
+ +
{:else if webConfig.WEB_SEARCH_ENGINE === 'sougou'}
From 77b357c73b1121faabb3300800a4ccbfc11d373a Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 3 Jun 2025 00:27:07 +0200 Subject: [PATCH 004/168] fix: update label for search context usage to clarify its purpose --- backend/open_webui/retrieval/web/perplexity.py | 2 +- src/lib/components/admin/Settings/WebSearch.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/retrieval/web/perplexity.py b/backend/open_webui/retrieval/web/perplexity.py index 551cb2c4b4..4e046668fa 100644 --- a/backend/open_webui/retrieval/web/perplexity.py +++ b/backend/open_webui/retrieval/web/perplexity.py @@ -60,7 +60,7 @@ def search_perplexity( "stream": False, "web_search_options": { "search_context_usage": search_context_usage, - } + }, } headers = { diff --git a/src/lib/components/admin/Settings/WebSearch.svelte b/src/lib/components/admin/Settings/WebSearch.svelte index e7630388e9..f0cc97ffe6 100644 --- a/src/lib/components/admin/Settings/WebSearch.svelte +++ b/src/lib/components/admin/Settings/WebSearch.svelte @@ -477,7 +477,7 @@
- {$i18n.t('Search Context Usage')} + {$i18n.t('Perplexity Search Context Usage')}
+ + + + + + + +
-
-
-
- {$i18n.t('Perplexity Search Context Usage')} +
+
+ {$i18n.t('Perplexity Search Context Usage')} +
+
-
{:else if webConfig.WEB_SEARCH_ENGINE === 'sougou'}
From ab36b8aeaeaaa265e9fe2107da5cadcf70f9c781 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Jun 2025 00:37:31 +0400 Subject: [PATCH 029/168] refac: embeddings endpoint --- backend/open_webui/main.py | 62 +++++++++++++------------- backend/open_webui/utils/embeddings.py | 51 +++------------------ 2 files changed, 38 insertions(+), 75 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 7709f33713..02d5b0d018 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1208,6 +1208,37 @@ async def get_base_models(request: Request, user=Depends(get_admin_user)): return {"data": models} +################################## +# Embeddings +################################## + + +@app.post("/api/embeddings") +async def embeddings( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + """ + OpenAI-compatible embeddings endpoint. + + This handler: + - Performs user/model checks and dispatches to the correct backend. + - Supports OpenAI, Ollama, arena models, pipelines, and any compatible provider. + + Args: + request (Request): Request context. + form_data (dict): OpenAI-like payload (e.g., {"model": "...", "input": [...]}) + user (UserModel): Authenticated user. + + Returns: + dict: OpenAI-compatible embeddings response. + """ + # Make sure models are loaded in app state + if not request.app.state.MODELS: + await get_all_models(request, user=user) + # Use generic dispatcher in utils.embeddings + return await generate_embeddings(request, form_data, user) + + @app.post("/api/chat/completions") async def chat_completion( request: Request, @@ -1550,37 +1581,6 @@ async def get_app_latest_release_version(user=Depends(get_verified_user)): async def get_app_changelog(): return {key: CHANGELOG[key] for idx, key in enumerate(CHANGELOG) if idx < 5} -################################## -# Embeddings -################################## - -@app.post("/api/embeddings") -async def embeddings_endpoint( - request: Request, - form_data: dict, - user=Depends(get_verified_user) -): - """ - OpenAI-compatible embeddings endpoint. - - This handler: - - Performs user/model checks and dispatches to the correct backend. - - Supports OpenAI, Ollama, arena models, pipelines, and any compatible provider. - - Args: - request (Request): Request context. - form_data (dict): OpenAI-like payload (e.g., {"model": "...", "input": [...]}) - user (UserModel): Authenticated user. - - Returns: - dict: OpenAI-compatible embeddings response. - """ - # Make sure models are loaded in app state - if not request.app.state.MODELS: - await get_all_models(request, user=user) - # Use generic dispatcher in utils.embeddings - return await generate_embeddings(request, form_data, user) - ############################ # OAuth Login & Callback diff --git a/backend/open_webui/utils/embeddings.py b/backend/open_webui/utils/embeddings.py index c3fae66022..49ce72c3c5 100644 --- a/backend/open_webui/utils/embeddings.py +++ b/backend/open_webui/utils/embeddings.py @@ -9,9 +9,10 @@ from open_webui.utils.models import check_model_access from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL from open_webui.routers.openai import embeddings as openai_embeddings -from open_webui.routers.ollama import embeddings as ollama_embeddings -from open_webui.routers.ollama import GenerateEmbeddingsForm -from open_webui.routers.pipelines import process_pipeline_inlet_filter +from open_webui.routers.ollama import ( + embeddings as ollama_embeddings, + GenerateEmbeddingsForm, +) from open_webui.utils.payload import convert_embedding_payload_openai_to_ollama @@ -29,7 +30,7 @@ async def generate_embeddings( bypass_filter: bool = False, ): """ - Dispatch and handle embeddings generation based on the model type (OpenAI, Ollama, Arena, pipeline, etc). + Dispatch and handle embeddings generation based on the model type (OpenAI, Ollama). Args: request (Request): The FastAPI request context. @@ -71,50 +72,12 @@ async def generate_embeddings( if not bypass_filter and user.role == "user": check_model_access(user, model) - # Arena "meta-model": select a submodel at random - if model.get("owned_by") == "arena": - model_ids = model.get("info", {}).get("meta", {}).get("model_ids") - filter_mode = model.get("info", {}).get("meta", {}).get("filter_mode") - if model_ids and filter_mode == "exclude": - model_ids = [ - m["id"] - for m in list(models.values()) - if m.get("owned_by") != "arena" and m["id"] not in model_ids - ] - if isinstance(model_ids, list) and model_ids: - selected_model_id = random.choice(model_ids) - else: - model_ids = [ - m["id"] - for m in list(models.values()) - if m.get("owned_by") != "arena" - ] - selected_model_id = random.choice(model_ids) - inner_form = dict(form_data) - inner_form["model"] = selected_model_id - response = await generate_embeddings( - request, inner_form, user, bypass_filter=True - ) - # Tag which concreted model was chosen - if isinstance(response, dict): - response = { - **response, - "selected_model_id": selected_model_id, - } - return response - - # Pipeline/Function models - if model.get("pipe"): - # The pipeline handler should provide OpenAI-compatible schema - return await process_pipeline_inlet_filter(request, form_data, user, models) - # Ollama backend if model.get("owned_by") == "ollama": ollama_payload = convert_embedding_payload_openai_to_ollama(form_data) - form_obj = GenerateEmbeddingsForm(**ollama_payload) response = await ollama_embeddings( request=request, - form_data=form_obj, + form_data=GenerateEmbeddingsForm(**ollama_payload), user=user, ) return convert_embedding_response_ollama_to_openai(response) @@ -124,4 +87,4 @@ async def generate_embeddings( request=request, form_data=form_data, user=user, - ) \ No newline at end of file + ) From ed1db62b1226752320de6cd0dadbb4e4accc5ae4 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Jun 2025 00:44:15 +0400 Subject: [PATCH 030/168] refac --- src/lib/components/admin/Settings.svelte | 28 +++++++++++++++++++ .../settings/{audio => [tab]}/+page.svelte | 0 .../settings/code-execution/+page.svelte | 5 ---- .../admin/settings/connections/+page.svelte | 5 ---- .../(app)/admin/settings/db/+page.svelte | 5 ---- .../admin/settings/documents/+page.svelte | 5 ---- .../admin/settings/evaluations/+page.svelte | 5 ---- .../(app)/admin/settings/general/+page.svelte | 5 ---- .../(app)/admin/settings/images/+page.svelte | 5 ---- .../admin/settings/interface/+page.svelte | 5 ---- .../(app)/admin/settings/models/+page.svelte | 5 ---- .../admin/settings/pipelines/+page.svelte | 5 ---- .../(app)/admin/settings/tools/+page.svelte | 5 ---- .../(app)/admin/settings/web/+page.svelte | 5 ---- 14 files changed, 28 insertions(+), 60 deletions(-) rename src/routes/(app)/admin/settings/{audio => [tab]}/+page.svelte (100%) delete mode 100644 src/routes/(app)/admin/settings/code-execution/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/connections/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/db/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/documents/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/evaluations/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/general/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/images/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/interface/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/models/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/pipelines/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/tools/+page.svelte delete mode 100644 src/routes/(app)/admin/settings/web/+page.svelte diff --git a/src/lib/components/admin/Settings.svelte b/src/lib/components/admin/Settings.svelte index 7e3bf14657..d6a9e8a925 100644 --- a/src/lib/components/admin/Settings.svelte +++ b/src/lib/components/admin/Settings.svelte @@ -51,6 +51,18 @@ : 'general'; } + $: if (selectedTab) { + // scroll to selectedTab + scrollToTab(selectedTab); + } + + const scrollToTab = (tabId) => { + const tabElement = document.getElementById(tabId); + if (tabElement) { + tabElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' }); + } + }; + onMount(() => { const containerElement = document.getElementById('admin-settings-tabs-container'); @@ -62,6 +74,9 @@ } }); } + + // Scroll to the selected tab on mount + scrollToTab(selectedTab); }); @@ -71,6 +86,7 @@ class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none" > - {:else if tabId === 'admin'} - {#if $user?.role === 'admin'} - - {/if} {/if} {/each} {:else} @@ -683,6 +803,32 @@ {$i18n.t('No results found')}
{/if} + + {#if $user?.role === 'admin'} + + {/if}
{#if selectedTab === 'general'} From a8b61204b4dcdd97060b0cc2cc7a5818950e8a11 Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Thu, 5 Jun 2025 23:00:32 +0800 Subject: [PATCH 043/168] i18n: improve zh-TW Traditional Chinese locale --- src/lib/i18n/locales/zh-TW/translation.json | 56 ++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index a0f5aaaaea..30075485c9 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -85,7 +85,7 @@ "Amazing": "很棒", "an assistant": "助理", "Analyzed": "分析完畢", - "Analyzing...": "正在分析……", + "Analyzing...": "正在分析...", "and": "和", "and {{COUNT}} more": "和另外 {{COUNT}} 個", "and create a new shared link.": "並建立新的共用連結。", @@ -160,7 +160,7 @@ "Camera": "相機", "Cancel": "取消", "Capabilities": "功能", - "Capture": "擷取", + "Capture": "相機", "Capture Audio": "錄製音訊", "Certificate Path": "憑證路徑", "Change Password": "修改密碼", @@ -180,8 +180,8 @@ "Chats": "對話", "Check Again": "再次檢查", "Check for updates": "檢查更新", - "Checking for updates...": "正在檢查更新……", - "Choose a model before saving...": "儲存前請選擇一個模型……", + "Checking for updates...": "正在檢查更新...", + "Choose a model before saving...": "儲存前請選擇一個模型...", "Chunk Overlap": "區塊重疊", "Chunk Size": "區塊大小", "Ciphers": "加密方式", @@ -189,18 +189,18 @@ "Citations": "引用文獻", "Clear memory": "清除記憶", "Clear Memory": "清除記憶", - "click here": "點選這裡", - "Click here for filter guides.": "點選這裡檢視篩選器指南。", - "Click here for help.": "點選這裡取得協助。", - "Click here to": "點選這裡", - "Click here to download user import template file.": "點選這裡下載使用者匯入範本檔案。", - "Click here to learn more about faster-whisper and see the available models.": "點選這裡了解更多關於 faster-whisper 的資訊並檢視可用的模型。", - "Click here to see available models.": "點選這裡以檢視可用的模型", - "Click here to select": "點選這裡選擇", - "Click here to select a csv file.": "點選這裡選擇 CSV 檔案。", - "Click here to select a py file.": "點選這裡選擇 Python 檔案。", - "Click here to upload a workflow.json file.": "點選這裡上傳 workflow.json 檔案。", - "click here.": "點選這裡。", + "click here": "點選此處", + "Click here for filter guides.": "點選此處檢視篩選器指南。", + "Click here for help.": "點選此處取得協助。", + "Click here to": "點選此處", + "Click here to download user import template file.": "點選此處下載使用者匯入範本檔案。", + "Click here to learn more about faster-whisper and see the available models.": "點選此處了解更多關於 faster-whisper 的資訊並檢視可用的模型。", + "Click here to see available models.": "點選此處以檢視可用的模型", + "Click here to select": "點選此處選擇", + "Click here to select a csv file.": "點選此處選擇 CSV 檔案。", + "Click here to select a py file.": "點選此處選擇 Python 檔案。", + "Click here to upload a workflow.json file.": "點選此處上傳 workflow.json 檔案。", + "click here.": "點選此處。", "Click on the user role button to change a user's role.": "點選使用者角色按鈕變更使用者的角色。", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "剪貼簿寫入權限遭拒。請檢查您的瀏覽器設定,授予必要的存取權限。", "Clone": "複製", @@ -232,8 +232,8 @@ "Confirm Password": "確認密碼", "Confirm your action": "確認您的操作", "Confirm your new password": "確認您的新密碼", - "Connect to your own OpenAI compatible API endpoints.": "連線到您自己的 OpenAI 相容 API 端點。", - "Connect to your own OpenAPI compatible external tool servers.": "連接至您自己的與 OpenAPI 相容的外部工具伺服器。", + "Connect to your own OpenAI compatible API endpoints.": "連線至您自有或其他與 OpenAI API 相容的端點。", + "Connect to your own OpenAPI compatible external tool servers.": "連線至您自有或其他與 OpenAPI 相容的外部工具伺服器。", "Connection failed": "連線失敗", "Connection successful": "連線成功", "Connection Type": "連線類型", @@ -329,11 +329,11 @@ "Describe your knowledge base and objectives": "描述您的知識庫和目標", "Description": "描述", "Detect Artifacts Automatically": "自動偵測 Artifacts", - "Dictate": "聽寫", + "Dictate": "語音輸入", "Didn't fully follow instructions": "未完全遵循指示", "Direct": "直接", "Direct Connections": "直接連線", - "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "直接連線允許使用者連接到自己的 OpenAI 相容 API 端點。", + "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "直接連線允許使用者連線至自有或其他與 OpenAI API 相容的端點。", "Direct Connections settings updated": "直接連線設定已更新。", "Direct Tool Servers": "直連工具伺服器", "Disable Image Extraction": "停用圖片擷取", @@ -546,7 +546,7 @@ "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "您的授權名額已超過上限。請聯絡支援以增加授權名額。", "Exclude": "排除", "Execute code for analysis": "執行程式碼以進行分析", - "Executing **{{NAME}}**...": "正在執行 **{{NAME}}** ……", + "Executing **{{NAME}}**...": "正在執行 **{{NAME}}** ...", "Expand": "展開", "Experimental": "實驗性功能", "Explain": "解釋", @@ -645,7 +645,7 @@ "Generate Image": "生成圖片", "Generate prompt pair": "生成提示配對", "Generating search query": "正在生成搜尋查詢", - "Generating...": "正在生成……", + "Generating...": "正在生成...", "Get started": "開始使用", "Get started with {{WEBUI_NAME}}": "開始使用 {{WEBUI_NAME}}", "Global": "全域", @@ -716,7 +716,7 @@ "Invalid JSON file": "JSON 檔案無效", "Invalid JSON schema": "JSON Schema 無效", "Invalid Tag": "無效標籤", - "is typing...": "正在輸入……", + "is typing...": "正在輸入...", "January": "1 月", "Jina API Key": "Jina API 金鑰", "join our Discord for help.": "加入我們的 Discord 以取得協助。", @@ -762,11 +762,11 @@ "Leave model field empty to use the default model.": "留空模型欄位以使用預設模型。", "License": "授權", "Light": "淺色", - "Listening...": "正在聆聽……", + "Listening...": "正在聆聽...", "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "大型語言模型可能會犯錯。請自行驗證重要資訊。", "Loader": "載入工具", - "Loading Kokoro.js...": "Kokoro.js 載入中……", + "Loading Kokoro.js...": "Kokoro.js 載入中...", "Local": "本機", "Local Task Model": "本機任務模型", "Location access not allowed": "位置存取未獲允許", @@ -1059,10 +1059,10 @@ "Search Tools": "搜尋工具", "SearchApi API Key": "SearchApi API 金鑰", "SearchApi Engine": "SearchApi 引擎", - "Searched {{count}} sites": "搜尋到 {{count}} 個站點", + "Searched {{count}} sites": "搜尋到 {{count}} 個網站", "Searching \"{{searchQuery}}\"": "正在搜尋「{{searchQuery}}」", "Searching Knowledge for \"{{searchQuery}}\"": "正在搜尋知識庫中的「{{searchQuery}}」", - "Searching the web...": "正在搜尋網路……", + "Searching the web...": "正在搜尋網路...", "Searxng Query URL": "Searxng 查詢 URL", "See readme.md for instructions": "檢視 readme.md 以取得說明", "See what's new": "檢視新功能", @@ -1361,7 +1361,7 @@ "Write": "撰寫", "Write a prompt suggestion (e.g. Who are you?)": "撰寫提示詞建議(例如:你是誰?)", "Write a summary in 50 words that summarizes [topic or keyword].": "用 50 字寫一篇總結 [主題或關鍵字] 的摘要。", - "Write something...": "寫一些什麼……", + "Write something...": "寫一些什麼...", "Yacy Instance URL": "Yacy 執行個體 URL", "Yacy Password": "Yacy 密碼", "Yacy Username": "Yacy 使用者名稱", From 543ed432b1e4d5a12d59220eb35e8df410ac5127 Mon Sep 17 00:00:00 2001 From: Silentoplayz <50341825+Silentoplayz@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:42:05 -0400 Subject: [PATCH 044/168] Update SettingsModal.svelte --- src/lib/components/chat/SettingsModal.svelte | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/lib/components/chat/SettingsModal.svelte b/src/lib/components/chat/SettingsModal.svelte index e43e9d07ea..c97c417a73 100644 --- a/src/lib/components/chat/SettingsModal.svelte +++ b/src/lib/components/chat/SettingsModal.svelte @@ -34,7 +34,9 @@ id: 'general', title: 'General', keywords: [ + 'advancedparams', 'advancedparameters', + 'advanced params', 'advanced parameters', 'configuration', 'defaultparameters', @@ -72,9 +74,11 @@ 'always collapse code blocks', 'always expand details', 'always on web search', + 'always play notification sound', 'alwayscollapsecodeblocks', 'alwaysexpanddetails', 'alwaysonwebsearch', + 'alwaysplaynotificationsound', 'android', 'auto chat tags', 'auto copy response to clipboard', @@ -127,6 +131,8 @@ 'iframesandboxallowsameorigin', 'imagecompression', 'image compression', + 'imagemaxcompressionsize', + 'image max compression size', 'interface customization', 'interface options', 'interfacecustomization', @@ -138,8 +144,6 @@ 'left-to-right', 'lefttoright', 'ltr', - 'notification sound', - 'notificationsound', 'paste large text as file', 'pastelargetextasfile', 'reset background', @@ -193,9 +197,10 @@ id: 'connections', title: 'Connections', keywords: [ - 'connections', - 'direct connections', - 'directconnections', + 'addconnection', + 'add connection', + 'manageconnections', + 'manage connections', 'manage direct connections', 'managedirectconnections', 'settings' @@ -211,9 +216,10 @@ id: 'tools', title: 'Tools', keywords: [ - 'tools', - 'tool servers', - 'toolservers', + 'addconnection', + 'add connection', + 'managetools', + 'manage tools', 'manage tool servers', 'managetoolservers', 'settings' @@ -303,6 +309,8 @@ 'text to speech', 'textospeechengine', 'texttospeech', + 'texttospeechvoice', + 'text to speech voice', 'voice control', 'voice modes', 'voice options', From 3c5ae1f62eecace881e8c3c7c75821e0176cc534 Mon Sep 17 00:00:00 2001 From: Silentoplayz <50341825+Silentoplayz@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:02:31 -0400 Subject: [PATCH 045/168] chore: Also define the standard property 'appearance' for compatibilitycss(vendorPrefix) --- src/lib/components/chat/SettingsModal.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/components/chat/SettingsModal.svelte b/src/lib/components/chat/SettingsModal.svelte index c97c417a73..16303834c3 100644 --- a/src/lib/components/chat/SettingsModal.svelte +++ b/src/lib/components/chat/SettingsModal.svelte @@ -917,6 +917,7 @@ } input[type='number'] { + appearance: textfield; -moz-appearance: textfield; /* Firefox */ } From 12cfb7b0f012038c466314b469fd62f0f7e23d42 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Jun 2025 21:43:43 +0400 Subject: [PATCH 046/168] refac: admin evaluation pages --- src/lib/components/admin/Evaluations.svelte | 32 ++++++++++++++++--- .../(app)/admin/evaluations/+page.svelte | 7 ++++ .../admin/evaluations/[tab]/+page.svelte | 5 +++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/routes/(app)/admin/evaluations/[tab]/+page.svelte diff --git a/src/lib/components/admin/Evaluations.svelte b/src/lib/components/admin/Evaluations.svelte index a5532ae2f2..d223db57ce 100644 --- a/src/lib/components/admin/Evaluations.svelte +++ b/src/lib/components/admin/Evaluations.svelte @@ -1,6 +1,8 @@ @@ -37,12 +59,13 @@ class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none" >
From 92c7549b0649f0e76932bbbd2e2dd43826e280b1 Mon Sep 17 00:00:00 2001 From: Silentoplayz <50341825+Silentoplayz@users.noreply.github.com> Date: Sun, 8 Jun 2025 01:50:11 -0400 Subject: [PATCH 058/168] fix: remove newline --- src/lib/components/admin/Settings/General.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/components/admin/Settings/General.svelte b/src/lib/components/admin/Settings/General.svelte index df79249b0c..7b9e094d05 100644 --- a/src/lib/components/admin/Settings/General.svelte +++ b/src/lib/components/admin/Settings/General.svelte @@ -311,7 +311,6 @@ {$i18n.t('Pending User Overlay Title')}