From e214d59d109a11eb61bad1a58208d6ae89d66a5b Mon Sep 17 00:00:00 2001 From: Andrew Baek Date: Wed, 27 Aug 2025 01:04:27 +0900 Subject: [PATCH 001/154] Update groups.py fix issue #16870 --- backend/open_webui/models/groups.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/groups.py b/backend/open_webui/models/groups.py index 6615f95142..1c84f4c1ae 100644 --- a/backend/open_webui/models/groups.py +++ b/backend/open_webui/models/groups.py @@ -12,6 +12,7 @@ from open_webui.models.files import FileMetadataResponse from pydantic import BaseModel, ConfigDict from sqlalchemy import BigInteger, Column, String, Text, JSON, func +from sqlalchemy.ext.mutable import MutableList log = logging.getLogger(__name__) @@ -35,7 +36,7 @@ class Group(Base): meta = Column(JSON, nullable=True) permissions = Column(JSON, nullable=True) - user_ids = Column(JSON, nullable=True) + user_ids = Column(MutableList.as_mutable(JSON), nullable=True) created_at = Column(BigInteger) updated_at = Column(BigInteger) From ceaafbbfd21dc3ab766066a1b6253f05560361b1 Mon Sep 17 00:00:00 2001 From: Andrew Baek Date: Wed, 27 Aug 2025 03:22:34 +0900 Subject: [PATCH 002/154] Update groups.py --- backend/open_webui/models/groups.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/open_webui/models/groups.py b/backend/open_webui/models/groups.py index 4c636b4f0f..a09b2b73f9 100644 --- a/backend/open_webui/models/groups.py +++ b/backend/open_webui/models/groups.py @@ -12,7 +12,6 @@ from open_webui.models.files import FileMetadataResponse from pydantic import BaseModel, ConfigDict from sqlalchemy import BigInteger, Column, String, Text, JSON, func -from sqlalchemy.ext.mutable import MutableList log = logging.getLogger(__name__) @@ -36,7 +35,7 @@ class Group(Base): meta = Column(JSON, nullable=True) permissions = Column(JSON, nullable=True) - user_ids = Column(MutableList.as_mutable(JSON), nullable=True) + user_ids = Column(JSON, nullable=True) created_at = Column(BigInteger) updated_at = Column(BigInteger) From b50ae5bf694a070147ea770e27bb1c146dbfacdf Mon Sep 17 00:00:00 2001 From: Andrew Baek Date: Sun, 31 Aug 2025 14:48:37 +0900 Subject: [PATCH 003/154] Update MessageInput.svelte --- src/lib/components/chat/MessageInput.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index adea345ed0..407cb2262f 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -1051,6 +1051,7 @@
{#if files.length > 0}
From 7c0bf59c7c42d882edd9ed001949c65def889945 Mon Sep 17 00:00:00 2001 From: Aleix Dorca Date: Fri, 5 Sep 2025 17:17:20 +0200 Subject: [PATCH 004/154] Update catalan translation.json --- src/lib/i18n/locales/ca-ES/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index d83fd1c8c4..0915b05f0a 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -237,7 +237,7 @@ "Clear memory": "Esborrar la memòria", "Clear Memory": "Esborrar la memòria", "click here": "prem aquí", - "Click here for filter guides.": "Clica aquí per filtrar les guies.", + "Click here for filter guides.": "Clica aquí per l'ajuda dels filtres.", "Click here for help.": "Clica aquí per obtenir ajuda.", "Click here to": "Clic aquí per", "Click here to download user import template file.": "Fes clic aquí per descarregar l'arxiu de plantilla d'importació d'usuaris", From 4ca43004edcb47332aac3dad3817df967ee5817a Mon Sep 17 00:00:00 2001 From: Jesper Kristensen Date: Fri, 5 Sep 2025 12:50:27 +0200 Subject: [PATCH 005/154] feat: Added support for redis as session storage --- backend/open_webui/main.py | 48 ++++++++++++++++++++++++++++++++------ backend/requirements.txt | 1 + 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index a5d55f75ab..1153692fb3 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -50,6 +50,11 @@ from starlette.middleware.sessions import SessionMiddleware from starlette.responses import Response, StreamingResponse from starlette.datastructures import Headers +from starsessions import ( + SessionMiddleware as StarSessionsMiddleware, + SessionAutoloadMiddleware, +) +from starsessions.stores.redis import RedisStore from open_webui.utils import logger from open_webui.utils.audit import AuditLevel, AuditLoggingMiddleware @@ -1897,13 +1902,42 @@ async def get_current_usage(user=Depends(get_verified_user)): # SessionMiddleware is used by authlib for oauth if len(OAUTH_PROVIDERS) > 0: - app.add_middleware( - SessionMiddleware, - secret_key=WEBUI_SECRET_KEY, - session_cookie="oui-session", - same_site=WEBUI_SESSION_COOKIE_SAME_SITE, - https_only=WEBUI_SESSION_COOKIE_SECURE, - ) + try: + # Try to create Redis store for sessions + if REDIS_URL: + redis_session_store = RedisStore( + url=REDIS_URL, + prefix=( + f"{REDIS_KEY_PREFIX}:session:" if REDIS_KEY_PREFIX else "session:" + ), + ) + + # Add SessionAutoloadMiddleware first to handle session loading + app.add_middleware(SessionAutoloadMiddleware) + + app.add_middleware( + StarSessionsMiddleware, + store=redis_session_store, + cookie_name="oui-session", + cookie_same_site=WEBUI_SESSION_COOKIE_SAME_SITE, + cookie_https_only=WEBUI_SESSION_COOKIE_SECURE, + ) + log.info("Using StarSessions with Redis for session management") + else: + raise ValueError("Redis URL not configured") + + except Exception as e: + log.warning( + f"Failed to initialize Redis sessions, falling back to cookie based sessions: {e}" + ) + # Fallback to existing SessionMiddleware + app.add_middleware( + SessionMiddleware, + secret_key=WEBUI_SECRET_KEY, + session_cookie="oui-session", + same_site=WEBUI_SESSION_COOKIE_SAME_SITE, + https_only=WEBUI_SESSION_COOKIE_SECURE, + ) @app.get("/oauth/{provider}/login") diff --git a/backend/requirements.txt b/backend/requirements.txt index 5871015075..f712423631 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -15,6 +15,7 @@ aiocache aiofiles starlette-compress==1.6.0 httpx[socks,http2,zstd,cli,brotli]==0.28.1 +starsessions[redis]==2.2.1 sqlalchemy==2.0.38 alembic==1.14.0 From 7735a0478393285d0f887ebfe4438a327df8694f Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Thu, 18 Sep 2025 11:50:00 +0800 Subject: [PATCH 006/154] feat: do not initiate requests when the ChangelogModal is not open --- src/lib/components/ChangelogModal.svelte | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/components/ChangelogModal.svelte b/src/lib/components/ChangelogModal.svelte index 6f94604889..c8270b0241 100644 --- a/src/lib/components/ChangelogModal.svelte +++ b/src/lib/components/ChangelogModal.svelte @@ -19,10 +19,11 @@ let changelog = null; - onMount(async () => { - const res = await getChangelog(); - changelog = res; - }); + const init = async () => { + changelog = await getChangelog(); + }; + + $: show && init(); From 52e8c6c998cb10b008a1ec47afa24b1e1809dfed Mon Sep 17 00:00:00 2001 From: bglee Date: Thu, 18 Sep 2025 15:09:43 +0900 Subject: [PATCH 007/154] Update on the Korean translation --- src/lib/i18n/locales/ko-KR/translation.json | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/lib/i18n/locales/ko-KR/translation.json b/src/lib/i18n/locales/ko-KR/translation.json index 996516f334..537e1002ce 100644 --- a/src/lib/i18n/locales/ko-KR/translation.json +++ b/src/lib/i18n/locales/ko-KR/translation.json @@ -146,9 +146,9 @@ "Ask": "질문", "Ask a question": "질문하기", "Assistant": "어시스턴트", - "Attach file from knowledge": "지식 베이스에서 파일 첨부", - "Attach Knowledge": "", - "Attach Notes": "", + "Attach file from knowledge": "지식 기반에서 파일 첨부", + "Attach Knowledge": "지식 기반 첨부", + "Attach Notes": "노트 첨부", "Attention to detail": "세부 사항에 대한 주의", "Attribute for Mail": "메일 속성", "Attribute for Username": "사용자 이름 속성", @@ -212,10 +212,10 @@ "Capture Audio": "오디오 캡처", "Certificate Path": "인증서 경로", "Change Password": "비밀번호 변경", - "Channel": "", - "Channel deleted successfully": "", + "Channel": "채널", + "Channel deleted successfully": "채널 삭제 성공", "Channel Name": "채널 이름", - "Channel updated successfully": "", + "Channel updated successfully": "채널 업데이트 성공", "Channels": "채널", "Character": "캐릭터", "Character limit for autocomplete generation input": "자동 완성 생성 입력 문자 제한", @@ -706,7 +706,7 @@ "Feedback History": "피드백 기록", "Feedbacks": "피드백", "Feel free to add specific details": "자세한 내용을 자유롭게 추가하세요.", - "Female": "", + "Female": "여성", "File": "파일", "File added successfully.": "파일이 성공적으로 추가되었습니다", "File content updated successfully.": "내용이 성공적으로 업데이트되었습니다", @@ -726,13 +726,13 @@ "Firecrawl API Key": "Firecrawl API 키", "Floating Quick Actions": "", "Focus chat input": "채팅 입력창에 포커스", - "Folder Background Image": "", + "Folder Background Image": "폴더 배경 이미지", "Folder deleted successfully": "성공적으로 폴더가 삭제되었습니다", "Folder Name": "폴더 이름", "Folder name cannot be empty.": "폴더 이름을 작성해주세요", "Folder name updated successfully": "성공적으로 폴더 이름이 저장되었습니다", "Folder updated successfully": "폴더가 성공적으로 업데이트되었습니다", - "Folders": "", + "Folders": "폴더", "Follow up": "후속 질문", "Follow Up Generation": "후속 질문 생성", "Follow Up Generation Prompt": "후속 질문 생성 프롬프트", @@ -766,7 +766,7 @@ "Gemini": "Gemini", "Gemini API Config": "Gemini API 구성", "Gemini API Key is required.": "Gemini API 키가 필요합니다.", - "Gender": "", + "Gender": "성별", "General": "일반", "Generate": "생성", "Generate an image": "이미지 생성", @@ -942,7 +942,7 @@ "Make password visible in the user interface": "비밀번호 보이기", "Make sure to enclose them with": "꼭 다음으로 감싸세요:", "Make sure to export a workflow.json file as API format from ComfyUI.": "꼭 workflow.json 파일을 ComfyUI의 API 형식대로 내보내세요", - "Male": "", + "Male": "남성", "Manage": "관리", "Manage Direct Connections": "다이렉트 연결 관리", "Manage Models": "모델 관리", @@ -1272,7 +1272,7 @@ "Save & Create": "저장 및 생성", "Save & Update": "저장 및 업데이트", "Save As Copy": "다른 이름으로 저장", - "Save Chat": "", + "Save Chat": "채팅 저장", "Save Tag": "태그 저장", "Saved": "저장됨", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "브라우저의 저장소에 채팅 로그를 직접 저장하는 것은 더 이상 지원되지 않습니다. 아래 버튼을 클릭하여 채팅 로그를 다운로드하고 삭제하세요. 걱정 마세요. 백엔드를 통해 채팅 로그를 쉽게 다시 가져올 수 있습니다.", @@ -1312,20 +1312,20 @@ "Seed": "시드", "Select": "", "Select a base model": "기본 모델 선택", - "Select a base model (e.g. llama3, gpt-4o)": "", + "Select a base model (e.g. llama3, gpt-4o)": "기본 모델 선택 (예시: llama3, gpt-4o)", "Select a conversation to preview": "대화를 선택하여 미리 보기", "Select a engine": "엔진 선택", "Select a function": "함수 선택", "Select a group": "그룹 선택", - "Select a language": "", - "Select a mode": "", + "Select a language": "언어 선택", + "Select a mode": "모드 선택", "Select a model": "모델 선택", - "Select a model (optional)": "", + "Select a model (optional)": "모델 선택 (선택 사항)", "Select a pipeline": "파이프라인 선택", "Select a pipeline url": "파이프라인 URL 선택", "Select a reranking model engine": "", "Select a role": "", - "Select a theme": "", + "Select a theme": "테마 선택", "Select a tool": "도구 선택", "Select a voice": "", "Select an auth method": "인증 방법 선택", @@ -1351,7 +1351,7 @@ "Serply API Key": "Serply API 키", "Serpstack API Key": "Serpstack API 키", "Server connection verified": "서버 연결 확인됨", - "Session": "", + "Session": "세션", "Set as default": "기본값으로 설정", "Set CFG Scale": "CFG Scale 설정", "Set Default Model": "기본 모델 설정", @@ -1477,7 +1477,7 @@ "The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "최대 파일 크기(MB). 만약 파일 크기가 한도를 초과할 시, 파일은 업로드되지 않습니다", "The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "하나의 채팅에서는 사용가능한 최대 파일 수가 있습니다. 만약 파일 수가 한도를 초과할 시, 파일은 업로드되지 않습니다.", "The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'.": "텍스트의 출력 형식입니다. 'json', 'markdown', 또는 'html'이 될 수 있습니다. 기본값은 'markdown'입니다.", - "The passwords you entered don't quite match. Please double-check and try again.": "", + "The passwords you entered don't quite match. Please double-check and try again.": "입력한 비밀번호가 일치하지 않습니다. 확인 후 다시 시도해 주세요.", "The score should be a value between 0.0 (0%) and 1.0 (100%).": "점수는 0.0(0%)에서 1.0(100%) 사이의 값이어야 합니다.", "The stream delta chunk size for the model. Increasing the chunk size will make the model respond with larger pieces of text at once.": "", "The temperature of the model. Increasing the temperature will make the model answer more creatively.": "모델의 온도. 온도를 높이면 모델이 더 창의적으로 답변할 수 있습니다.", From f188d570f7497c742b68a5ebef46995150be2879 Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Thu, 18 Sep 2025 07:48:19 +0000 Subject: [PATCH 008/154] feat: improve Chinese translation --- src/lib/i18n/locales/zh-CN/translation.json | 6 +++--- src/lib/i18n/locales/zh-TW/translation.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index f65dc8dd0f..c71d9ec378 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -487,7 +487,7 @@ "Edit Memory": "编辑记忆", "Edit User": "编辑用户", "Edit User Group": "编辑用户组", - "edited": "", + "edited": "已编辑", "Edited": "已编辑", "Editing": "编辑中", "Eject": "弹出", @@ -630,7 +630,7 @@ "Enter Your Role": "输入您的权限组", "Enter Your Username": "输入您的用户名", "Enter your webhook URL": "输入您的 Webhook URL", - "Entra ID": "", + "Entra ID": "Entra ID", "Error": "错误", "ERROR": "错误", "Error accessing directory": "访问目录时出错", @@ -1608,7 +1608,7 @@ "User Webhooks": "用户 Webhook", "Username": "用户名", "Users": "用户", - "Uses DefaultAzureCredential to authenticate": "", + "Uses DefaultAzureCredential to authenticate": "使用 DefaultAzureCredential 进行身份验证", "Using Entire Document": "使用完整文档", "Using Focused Retrieval": "使用聚焦检索", "Using the default arena model with all models. Click the plus button to add custom models.": "竞技场模型默认使用所有模型。点击上方的“+”按钮以添加自定义模型", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index 0360dc9ce6..0f04434e0f 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -487,7 +487,7 @@ "Edit Memory": "編輯記憶", "Edit User": "編輯使用者", "Edit User Group": "編輯使用者群組", - "edited": "", + "edited": "已編輯", "Edited": "已編輯", "Editing": "編輯中", "Eject": "卸載", @@ -630,7 +630,7 @@ "Enter Your Role": "輸入您的角色", "Enter Your Username": "輸入您的使用者名稱", "Enter your webhook URL": "輸入您的 webhook URL", - "Entra ID": "", + "Entra ID": "Entra ID", "Error": "錯誤", "ERROR": "錯誤", "Error accessing directory": "存取目錄時發生錯誤", @@ -1608,7 +1608,7 @@ "User Webhooks": "使用者 Webhooks", "Username": "使用者名稱", "Users": "使用者", - "Uses DefaultAzureCredential to authenticate": "", + "Uses DefaultAzureCredential to authenticate": "使用 DefaultAzureCredential 進行身份驗證", "Using Entire Document": "使用完整檔案", "Using Focused Retrieval": "使用聚焦檢索", "Using the default arena model with all models. Click the plus button to add custom models.": "正在使用預設競技場模型與所有模型。點選加號按鈕以新增自訂模型。", From da7610f6cb7a95f3ffe0de10e9b988e90d248d40 Mon Sep 17 00:00:00 2001 From: _00_ <131402327+rgaricano@users.noreply.github.com> Date: Thu, 18 Sep 2025 13:18:07 +0200 Subject: [PATCH 009/154] FIX: Inconsistency in the description of BM25 - Update Documents.svelte FIX: Inconsistency in the description of BM25 Fix issue: https://github.com/open-webui/open-webui/discussions/17553 --- src/lib/components/admin/Settings/Documents.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/admin/Settings/Documents.svelte b/src/lib/components/admin/Settings/Documents.svelte index 7e4f8735a3..78235648d6 100644 --- a/src/lib/components/admin/Settings/Documents.svelte +++ b/src/lib/components/admin/Settings/Documents.svelte @@ -1143,7 +1143,7 @@
Date: Thu, 18 Sep 2025 09:39:40 -0500 Subject: [PATCH 010/154] fix: isdangerous dep --- backend/requirements.txt | 1 + pyproject.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/requirements.txt b/backend/requirements.txt index 5871015075..1ea3128cb8 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -2,6 +2,7 @@ fastapi==0.115.7 uvicorn[standard]==0.35.0 pydantic==2.11.7 python-multipart==0.0.20 +isdangerous==2.2.0 python-socketio==5.13.0 python-jose==3.4.0 diff --git a/pyproject.toml b/pyproject.toml index 4bbaf85b6b..267d8a7c60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ dependencies = [ "uvicorn[standard]==0.35.0", "pydantic==2.11.7", "python-multipart==0.0.20", + "isdangerous==2.2.0", "python-socketio==5.13.0", "python-jose==3.4.0", From d4f21c7e84d35986fc809168cc4194da584fbdd1 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 10:43:59 -0500 Subject: [PATCH 011/154] refac --- backend/requirements.txt | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 1ea3128cb8..81fc0beb45 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -2,7 +2,7 @@ fastapi==0.115.7 uvicorn[standard]==0.35.0 pydantic==2.11.7 python-multipart==0.0.20 -isdangerous==2.2.0 +itsdangerous==2.2.0 python-socketio==5.13.0 python-jose==3.4.0 diff --git a/pyproject.toml b/pyproject.toml index 267d8a7c60..bed62ee4e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "uvicorn[standard]==0.35.0", "pydantic==2.11.7", "python-multipart==0.0.20", - "isdangerous==2.2.0", + "itsdangerous==2.2.0", "python-socketio==5.13.0", "python-jose==3.4.0", From bfc8f744774c1a0ee74fc78245f23fc1cee37f9c Mon Sep 17 00:00:00 2001 From: joaoback <156559121+joaoback@users.noreply.github.com> Date: Thu, 18 Sep 2025 13:53:41 -0300 Subject: [PATCH 012/154] Update translation.json (pt-BR) translation of newly added items. --- src/lib/i18n/locales/pt-BR/translation.json | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index 63105c090e..c4c893f0df 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -212,7 +212,7 @@ "Capture Audio": "Capturar Audio", "Certificate Path": "Caminho do Certificado", "Change Password": "Alterar Senha", - "Channel": "", + "Channel": "Canal", "Channel deleted successfully": "Canal apagado com sucesso", "Channel Name": "Nome do canal", "Channel updated successfully": "Canal atualizado com sucesso", @@ -358,7 +358,7 @@ "Custom Parameter Value": "Valor do parâmetro personalizado", "Danger Zone": "Zona de perigo", "Dark": "Escuro", - "Data Controls": "", + "Data Controls": "Controle de Dados", "Database": "Banco de Dados", "Datalab Marker API": "API do Marcador do Datalab", "Datalab Marker API Key required.": "Chave de API do Datalab Marker necessária.", @@ -370,8 +370,8 @@ "Default (SentenceTransformers)": "Padrão (SentenceTransformers)", "Default action buttons will be used.": "Botões de ação padrão serão usados.", "Default description enabled": "Descrição padrão habilitada", - "Default Features": "", - "Default Filters": "", + "Default Features": "Recursos padrão", + "Default Filters": "Filtros padrão", "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "O modo padrão funciona com uma gama mais ampla de modelos, chamando as ferramentas uma vez antes da execução. O modo nativo aproveita os recursos integrados de chamada de ferramentas do modelo, mas exige que o modelo suporte esse recurso inerentemente.", "Default Model": "Modelo Padrão", "Default model updated": "Modelo padrão atualizado", @@ -487,7 +487,7 @@ "Edit Memory": "Editar Memória", "Edit User": "Editar Usuário", "Edit User Group": "Editar Grupo de Usuários", - "edited": "", + "edited": "editado", "Edited": "Editado", "Editing": "Editando", "Eject": "Ejetar", @@ -630,7 +630,7 @@ "Enter Your Role": "Digite Sua Função", "Enter Your Username": "Digite seu usuário", "Enter your webhook URL": "Insira a URL do seu webhook", - "Entra ID": "", + "Entra ID": "ID Entra", "Error": "Erro", "ERROR": "ERRO", "Error accessing directory": "Erro ao acessar o diretório", @@ -726,13 +726,13 @@ "Firecrawl API Key": "Chave de API do Firecrawl", "Floating Quick Actions": "Ações rápidas flutuantes", "Focus chat input": "Focar entrada de chat", - "Folder Background Image": "", + "Folder Background Image": "Imagem de fundo da pasta", "Folder deleted successfully": "Pasta excluída com sucesso", "Folder Name": "Nome da Pasta", "Folder name cannot be empty.": "Nome da pasta não pode estar vazio.", "Folder name updated successfully": "Nome da pasta atualizado com sucesso", "Folder updated successfully": "Pasta atualizada com sucesso", - "Folders": "", + "Folders": "Pastas", "Follow up": "Acompanhamento", "Follow Up Generation": "Geração de Acompanhamento", "Follow Up Generation Prompt": "Prompt para Geração dos Acompanhamentos", @@ -744,7 +744,7 @@ "Form": "Formulário", "Format Lines": "Formatar linhas", "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "Formata as linhas na saída. O padrão é Falso. Se definido como Verdadeiro, as linhas serão formatadas para detectar matemática e estilos embutidos.", - "Format your variables using brackets like this:": "Formate suas variáveis usando colchetes como este:", + "Format your variables using brackets like this:": "Formate suas variáveis usando duplas chaves como este:", "Formatting may be inconsistent from source.": "A formatação pode ser inconsistente em relação à fonte.", "Forwards system user OAuth access token to authenticate": "Encaminha o token de acesso OAuth do usuário do sistema para autenticação", "Forwards system user session credentials to authenticate": "Encaminha as credenciais da sessão do usuário do sistema para autenticação", @@ -1048,7 +1048,7 @@ "No models found": "Nenhum modelo encontrado", "No models selected": "Nenhum modelo selecionado", "No Notes": "Sem Notas", - "No notes found": "", + "No notes found": "Notas não encontradas", "No results": "Nenhum resultado encontrado", "No results found": "Nenhum resultado encontrado", "No search query generated": "Nenhuma consulta de pesquisa gerada", @@ -1062,7 +1062,7 @@ "None": "Nenhum", "Not factually correct": "Não está factualmente correto", "Not helpful": "Não é útil", - "Note": "", + "Note": "Nota", "Note deleted successfully": "Nota excluída com sucesso", "Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Nota: Se você definir uma pontuação mínima, a pesquisa retornará apenas documentos com pontuação igual ou superior à pontuação mínima.", "Notes": "Notas", @@ -1095,10 +1095,10 @@ "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ops! Você está usando um método não suportado (somente frontend). Por favor, sirva a WebUI a partir do backend.", "Open file": "Abrir arquivo", "Open in full screen": "Abrir em tela cheia", - "Open link": "", + "Open link": "Abrir link", "Open modal to configure connection": "Abra o modal para configurar a conexão", "Open Modal To Manage Floating Quick Actions": "Abra o Modal para gerenciar ações rápidas flutuantes", - "Open Modal To Manage Image Compression": "", + "Open Modal To Manage Image Compression": "Abrir o Modal para gerenciar a compressão de imagens", "Open new chat": "Abrir novo chat", "Open Sidebar": "Abrir barra lateral", "Open User Profile Menu": "Abrir menu de perfil do usuário", @@ -1218,7 +1218,7 @@ "Redirecting you to Open WebUI Community": "Redirecionando você para a Comunidade OpenWebUI", "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "Reduz a probabilidade de gerar respostas sem sentido. Um valor mais alto (por exemplo, 100) resultará em respostas mais diversas, enquanto um valor mais baixo (por exemplo, 10) será mais conservador.", "Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Refira-se como \"Usuário\" (por exemplo, \"Usuário está aprendendo espanhol\")", - "Reference Chats": "", + "Reference Chats": "Chats Anteriores", "Refused when it shouldn't have": "Recusado quando não deveria", "Regenerate": "Gerar novamente", "Regenerate Menu": "Regenerar Menu", @@ -1568,7 +1568,7 @@ "Unarchive All Archived Chats": "Desarquivar Todos os Chats Arquivados", "Unarchive Chat": "Desarquivar Chat", "Underline": "Sublinhado", - "Unknown": "", + "Unknown": "Desconhecido", "Unloads {{FROM_NOW}}": "Descarrega {{FROM_NOW}}", "Unlock mysteries": "Desvendar mistérios", "Unpin": "Desfixar", From c07086401eaf13efbb2eebd02ffe19af49df1044 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 17:47:32 -0500 Subject: [PATCH 013/154] refac --- src/lib/components/admin/Users/UserList/UserChatsModal.svelte | 4 ++++ src/lib/components/layout/ArchivedChatsModal.svelte | 4 ++++ src/lib/components/layout/SearchModal.svelte | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/lib/components/admin/Users/UserList/UserChatsModal.svelte b/src/lib/components/admin/Users/UserList/UserChatsModal.svelte index fa95088933..1e17dfa3ad 100644 --- a/src/lib/components/admin/Users/UserList/UserChatsModal.svelte +++ b/src/lib/components/admin/Users/UserList/UserChatsModal.svelte @@ -43,6 +43,10 @@ let searchDebounceTimeout; const searchHandler = async () => { + if (!show) { + return; + } + if (searchDebounceTimeout) { clearTimeout(searchDebounceTimeout); } diff --git a/src/lib/components/layout/ArchivedChatsModal.svelte b/src/lib/components/layout/ArchivedChatsModal.svelte index 3251e9531f..93a73b394b 100644 --- a/src/lib/components/layout/ArchivedChatsModal.svelte +++ b/src/lib/components/layout/ArchivedChatsModal.svelte @@ -39,6 +39,10 @@ } const searchHandler = async () => { + if (!show) { + return; + } + if (searchDebounceTimeout) { clearTimeout(searchDebounceTimeout); } diff --git a/src/lib/components/layout/SearchModal.svelte b/src/lib/components/layout/SearchModal.svelte index f68e9aa731..3eb6687e41 100644 --- a/src/lib/components/layout/SearchModal.svelte +++ b/src/lib/components/layout/SearchModal.svelte @@ -91,6 +91,10 @@ }; const searchHandler = async () => { + if (!show) { + return; + } + if (searchDebounceTimeout) { clearTimeout(searchDebounceTimeout); } From 04251b7bfffa617591458c9b4ea37bb59aedfd19 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 17:50:39 -0500 Subject: [PATCH 014/154] refac --- src/lib/components/ChangelogModal.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/components/ChangelogModal.svelte b/src/lib/components/ChangelogModal.svelte index c8270b0241..dec152b21b 100644 --- a/src/lib/components/ChangelogModal.svelte +++ b/src/lib/components/ChangelogModal.svelte @@ -23,7 +23,9 @@ changelog = await getChangelog(); }; - $: show && init(); + $: if (show) { + init(); + } From 48cd72fab02a63c51a7e542044af73547bf503a9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 17:51:00 -0500 Subject: [PATCH 015/154] refac --- src/lib/components/layout/Sidebar/RecursiveFolder.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/components/layout/Sidebar/RecursiveFolder.svelte b/src/lib/components/layout/Sidebar/RecursiveFolder.svelte index 8e64fc71aa..8a168cb845 100644 --- a/src/lib/components/layout/Sidebar/RecursiveFolder.svelte +++ b/src/lib/components/layout/Sidebar/RecursiveFolder.svelte @@ -332,14 +332,16 @@ let isExpandedUpdateTimeout; - const isExpandedUpdateDebounceHandler = (open) => { + const isExpandedUpdateDebounceHandler = () => { clearTimeout(isExpandedUpdateTimeout); isExpandedUpdateTimeout = setTimeout(() => { isExpandedUpdateHandler(); }, 500); }; - $: isExpandedUpdateDebounceHandler(open); + $: if (open) { + isExpandedUpdateDebounceHandler(); + } const renameHandler = async () => { console.log('Edit'); From 1c7859437916bf6589ad49b4ea651f892c64fec0 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 17:53:11 -0500 Subject: [PATCH 016/154] refac --- src/lib/components/chat/ModelSelector/Selector.svelte | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 1e98a81a5a..29eb85eb40 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -286,9 +286,11 @@ } }; - onMount(async () => { + const setOllamaVersion = async () => { ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false); + }; + onMount(async () => { if (items) { tags = items .filter((item) => !(item.model?.info?.meta?.hidden ?? false)) @@ -300,6 +302,10 @@ } }); + $: if (show) { + setOllamaVersion(); + } + const cancelModelPullHandler = async (model: string) => { const { reader, abortController } = $MODEL_DOWNLOAD_POOL[model]; if (abortController) { From 700894a13d243b129632190316d1cabf713be033 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 18:02:35 -0500 Subject: [PATCH 017/154] refac: channel modal --- .../components/layout/Sidebar/ChannelModal.svelte | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lib/components/layout/Sidebar/ChannelModal.svelte b/src/lib/components/layout/Sidebar/ChannelModal.svelte index e59b3e42cc..ff54511214 100644 --- a/src/lib/components/layout/Sidebar/ChannelModal.svelte +++ b/src/lib/components/layout/Sidebar/ChannelModal.svelte @@ -44,8 +44,12 @@ accessControl = channel.access_control; }; - $: if (channel) { - init(); + $: if (show) { + if (channel) { + init(); + } + } else { + resetHandler(); } let showDeleteConfirmDialog = false; @@ -68,6 +72,12 @@ show = false; }; + + const resetHandler = () => { + name = ''; + accessControl = {}; + loading = false; + }; From 07c5b25bc8b63173f406feb3ba183d375fedee6a Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 18 Sep 2025 20:55:23 -0500 Subject: [PATCH 018/154] feat: tool ui element support --- backend/open_webui/utils/middleware.py | 40 ++++- backend/open_webui/utils/tools.py | 14 +- src/lib/components/common/Collapsible.svelte | 17 +++ .../components/common/FullHeightIframe.svelte | 144 ++++++++++++++++++ 4 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 src/lib/components/common/FullHeightIframe.svelte diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 97f19dcded..0cd593de11 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1581,7 +1581,8 @@ async def process_chat_response( break if tool_result is not None: - tool_calls_display_content = f'{tool_calls_display_content}
\nTool Executed\n
\n' + tool_result_embeds = result.get("embeds", "") + tool_calls_display_content = f'{tool_calls_display_content}
\nTool Executed\n
\n' else: tool_calls_display_content = f'{tool_calls_display_content}
\nExecuting...\n
\n' @@ -2402,6 +2403,38 @@ async def process_chat_response( except Exception as e: tool_result = str(e) + tool_result_embeds = [] + if tool.get("type") == "external" and isinstance( + tool_result, tuple + ): + + tool_result, tool_response_headers = tool_result + + if tool_response_headers: + content_disposition = tool_response_headers.get( + "Content-Disposition", "" + ) + + if "inline" in content_disposition: + content_type = tool_response_headers.get( + "Content-Type", "" + ) + location = tool_response_headers.get("Location", "") + + if "text/html" in content_type: + # Display as iframe embed + tool_result_embeds.append(tool_result) + tool_result = { + "status": "success", + "message": "Displayed as embed", + } + elif location: + tool_result_embeds.append(location) + tool_result = { + "status": "success", + "message": "Displayed as embed", + } + tool_result_files = [] if isinstance(tool_result, list): for item in tool_result: @@ -2426,6 +2459,11 @@ async def process_chat_response( if tool_result_files else {} ), + **( + {"embeds": tool_result_embeds} + if tool_result_embeds + else {} + ), } ) diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index bc90dd9d74..63df47700f 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -171,6 +171,8 @@ async def get_tools( "tool_id": tool_id, "callable": callable, "spec": spec, + # Misc info + "type": "external", } # Handle function name collisions @@ -646,7 +648,7 @@ async def execute_tool_server( name: str, params: Dict[str, Any], server_data: Dict[str, Any], -) -> Any: +) -> Tuple[Dict[str, Any], Optional[Dict[str, Any]]]: error = None try: openapi = server_data.get("openapi", {}) @@ -718,6 +720,7 @@ async def execute_tool_server( headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, + allow_redirects=False, ) as response: if response.status >= 400: text = await response.text() @@ -728,13 +731,15 @@ async def execute_tool_server( except Exception: response_data = await response.text() - return response_data + response_headers = response.headers + return (response_data, response_headers) else: async with request_method( final_url, headers=headers, cookies=cookies, ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, + allow_redirects=False, ) as response: if response.status >= 400: text = await response.text() @@ -745,12 +750,13 @@ async def execute_tool_server( except Exception: response_data = await response.text() - return response_data + response_headers = response.headers + return (response_data, response_headers) except Exception as err: error = str(err) log.exception(f"API Request Error: {error}") - return {"error": error} + return ({"error": error}, None) def get_tool_server_url(url: Optional[str], path: str) -> str: diff --git a/src/lib/components/common/Collapsible.svelte b/src/lib/components/common/Collapsible.svelte index b092a49826..83522d7006 100644 --- a/src/lib/components/common/Collapsible.svelte +++ b/src/lib/components/common/Collapsible.svelte @@ -38,6 +38,8 @@ import CodeBlock from '../chat/Messages/CodeBlock.svelte'; import Markdown from '../chat/Messages/Markdown.svelte'; import Image from './Image.svelte'; + import FullHeightIframe from './FullHeightIframe.svelte'; + import { settings } from '$lib/stores'; export let open = false; @@ -213,6 +215,21 @@ {@const args = decode(attributes?.arguments)} {@const result = decode(attributes?.result ?? '')} {@const files = parseJSONString(decode(attributes?.files ?? ''))} + {@const embeds = parseJSONString(decode(attributes?.embeds ?? ''))} + + {#if embeds && Array.isArray(embeds) && embeds.length > 0} + {#each embeds as embed, idx} +
+ +
+ {/each} + {/if} {#if !grow} {#if open && !hide} diff --git a/src/lib/components/common/FullHeightIframe.svelte b/src/lib/components/common/FullHeightIframe.svelte new file mode 100644 index 0000000000..ec9d49c5c3 --- /dev/null +++ b/src/lib/components/common/FullHeightIframe.svelte @@ -0,0 +1,144 @@ + + +{#if iframeDoc} +