Browse Source

Merge branch 'dev' into bug/user-signup/fix-oauth-username-claim-has-no-effect

pseudorm 2 months ago
parent
commit
336d1d95c5
100 changed files with 2741 additions and 1125 deletions
  1. 1 1
      README.md
  2. 50 1
      backend/open_webui/config.py
  3. 1 0
      backend/open_webui/env.py
  4. 30 1
      backend/open_webui/main.py
  5. 1 1
      backend/open_webui/models/chats.py
  6. 28 0
      backend/open_webui/retrieval/vector/dbs/opensearch.py
  7. 13 4
      backend/open_webui/retrieval/web/jina_search.py
  8. 68 0
      backend/open_webui/routers/audio.py
  9. 55 0
      backend/open_webui/routers/configs.py
  10. 73 46
      backend/open_webui/routers/ollama.py
  11. 6 6
      backend/open_webui/routers/openai.py
  12. 6 0
      backend/open_webui/routers/retrieval.py
  13. 21 7
      backend/open_webui/storage/provider.py
  14. 35 109
      backend/open_webui/utils/chat.py
  15. 153 0
      backend/open_webui/utils/code_interpreter.py
  16. 99 0
      backend/open_webui/utils/filter.py
  17. 1 1
      backend/open_webui/utils/images/comfyui.py
  18. 81 108
      backend/open_webui/utils/middleware.py
  19. 5 4
      backend/open_webui/utils/misc.py
  20. 44 10
      backend/open_webui/utils/oauth.py
  21. 7 5
      backend/open_webui/utils/pdf_generator.py
  22. 4 2
      backend/requirements.txt
  23. 186 120
      package-lock.json
  24. 4 2
      package.json
  25. 4 1
      pyproject.toml
  26. 57 0
      src/lib/apis/configs/index.ts
  27. 2 2
      src/lib/components/admin/Evaluations/Feedbacks.svelte
  28. 3 1
      src/lib/components/admin/Evaluations/Leaderboard.svelte
  29. 2 2
      src/lib/components/admin/Functions.svelte
  30. 36 0
      src/lib/components/admin/Settings.svelte
  31. 36 1
      src/lib/components/admin/Settings/Audio.svelte
  32. 145 0
      src/lib/components/admin/Settings/CodeInterpreter.svelte
  33. 16 4
      src/lib/components/admin/Settings/Connections.svelte
  34. 28 0
      src/lib/components/admin/Settings/WebSearch.svelte
  35. 2 1
      src/lib/components/chat/Chat.svelte
  36. 19 7
      src/lib/components/chat/MessageInput.svelte
  37. 17 2
      src/lib/components/chat/MessageInput/CallOverlay.svelte
  38. 19 11
      src/lib/components/chat/Messages/Citations.svelte
  39. 17 2
      src/lib/components/chat/Messages/CodeBlock.svelte
  40. 98 61
      src/lib/components/chat/Messages/ResponseMessage.svelte
  41. 162 16
      src/lib/components/chat/Settings/Audio.svelte
  42. 5 0
      src/lib/components/chat/Settings/General.svelte
  43. 2 2
      src/lib/components/chat/ShareChatModal.svelte
  44. 9 3
      src/lib/components/common/Collapsible.svelte
  45. 1 0
      src/lib/components/common/SensitiveInput.svelte
  46. 2 2
      src/lib/components/workspace/Models.svelte
  47. 2 2
      src/lib/components/workspace/Prompts.svelte
  48. 2 2
      src/lib/components/workspace/Tools.svelte
  49. 10 3
      src/lib/i18n/locales/ar-BH/translation.json
  50. 10 3
      src/lib/i18n/locales/bg-BG/translation.json
  51. 10 3
      src/lib/i18n/locales/bn-BD/translation.json
  52. 10 3
      src/lib/i18n/locales/ca-ES/translation.json
  53. 10 3
      src/lib/i18n/locales/ceb-PH/translation.json
  54. 10 3
      src/lib/i18n/locales/cs-CZ/translation.json
  55. 10 3
      src/lib/i18n/locales/da-DK/translation.json
  56. 111 104
      src/lib/i18n/locales/de-DE/translation.json
  57. 10 3
      src/lib/i18n/locales/dg-DG/translation.json
  58. 10 3
      src/lib/i18n/locales/el-GR/translation.json
  59. 10 3
      src/lib/i18n/locales/en-GB/translation.json
  60. 10 3
      src/lib/i18n/locales/en-US/translation.json
  61. 307 301
      src/lib/i18n/locales/es-ES/translation.json
  62. 10 3
      src/lib/i18n/locales/eu-ES/translation.json
  63. 10 3
      src/lib/i18n/locales/fa-IR/translation.json
  64. 10 3
      src/lib/i18n/locales/fi-FI/translation.json
  65. 10 3
      src/lib/i18n/locales/fr-CA/translation.json
  66. 10 3
      src/lib/i18n/locales/fr-FR/translation.json
  67. 10 3
      src/lib/i18n/locales/he-IL/translation.json
  68. 10 3
      src/lib/i18n/locales/hi-IN/translation.json
  69. 10 3
      src/lib/i18n/locales/hr-HR/translation.json
  70. 10 3
      src/lib/i18n/locales/hu-HU/translation.json
  71. 10 3
      src/lib/i18n/locales/id-ID/translation.json
  72. 10 3
      src/lib/i18n/locales/ie-GA/translation.json
  73. 10 3
      src/lib/i18n/locales/it-IT/translation.json
  74. 10 3
      src/lib/i18n/locales/ja-JP/translation.json
  75. 10 3
      src/lib/i18n/locales/ka-GE/translation.json
  76. 10 3
      src/lib/i18n/locales/ko-KR/translation.json
  77. 10 3
      src/lib/i18n/locales/lt-LT/translation.json
  78. 10 3
      src/lib/i18n/locales/ms-MY/translation.json
  79. 10 3
      src/lib/i18n/locales/nb-NO/translation.json
  80. 10 3
      src/lib/i18n/locales/nl-NL/translation.json
  81. 10 3
      src/lib/i18n/locales/pa-IN/translation.json
  82. 10 3
      src/lib/i18n/locales/pl-PL/translation.json
  83. 10 3
      src/lib/i18n/locales/pt-BR/translation.json
  84. 10 3
      src/lib/i18n/locales/pt-PT/translation.json
  85. 10 3
      src/lib/i18n/locales/ro-RO/translation.json
  86. 10 3
      src/lib/i18n/locales/ru-RU/translation.json
  87. 10 3
      src/lib/i18n/locales/sk-SK/translation.json
  88. 10 3
      src/lib/i18n/locales/sr-RS/translation.json
  89. 10 3
      src/lib/i18n/locales/sv-SE/translation.json
  90. 10 3
      src/lib/i18n/locales/th-TH/translation.json
  91. 10 3
      src/lib/i18n/locales/tk-TW/translation.json
  92. 10 3
      src/lib/i18n/locales/tr-TR/translation.json
  93. 10 3
      src/lib/i18n/locales/uk-UA/translation.json
  94. 10 3
      src/lib/i18n/locales/ur-PK/translation.json
  95. 10 3
      src/lib/i18n/locales/vi-VN/translation.json
  96. 20 13
      src/lib/i18n/locales/zh-CN/translation.json
  97. 29 22
      src/lib/i18n/locales/zh-TW/translation.json
  98. 3 0
      src/lib/stores/index.ts
  99. 106 0
      src/lib/workers/KokoroWorker.ts
  100. 57 0
      src/lib/workers/kokoro.worker.ts

+ 1 - 1
README.md

@@ -174,7 +174,7 @@ docker run --rm --volume /var/run/docker.sock:/var/run/docker.sock containrrr/wa
 
 In the last part of the command, replace `open-webui` with your container name if it is different.
 
-Check our Migration Guide available in our [Open WebUI Documentation](https://docs.openwebui.com/tutorials/migration/).
+Check our Updating Guide available in our [Open WebUI Documentation](https://docs.openwebui.com/getting-started/updating).
 
 ### Using the Dev Branch 🌙
 

+ 50 - 1
backend/open_webui/config.py

@@ -660,6 +660,7 @@ S3_ACCESS_KEY_ID = os.environ.get("S3_ACCESS_KEY_ID", None)
 S3_SECRET_ACCESS_KEY = os.environ.get("S3_SECRET_ACCESS_KEY", None)
 S3_REGION_NAME = os.environ.get("S3_REGION_NAME", None)
 S3_BUCKET_NAME = os.environ.get("S3_BUCKET_NAME", None)
+S3_KEY_PREFIX = os.environ.get("S3_KEY_PREFIX", None)
 S3_ENDPOINT_URL = os.environ.get("S3_ENDPOINT_URL", None)
 
 GCS_BUCKET_NAME = os.environ.get("GCS_BUCKET_NAME", None)
@@ -1325,6 +1326,48 @@ Your task is to synthesize these responses into a single, high-quality response.
 Responses from models: {{responses}}"""
 
 
+####################################
+# Code Interpreter
+####################################
+
+ENABLE_CODE_INTERPRETER = PersistentConfig(
+    "ENABLE_CODE_INTERPRETER",
+    "code_interpreter.enable",
+    os.environ.get("ENABLE_CODE_INTERPRETER", "True").lower() == "true",
+)
+
+CODE_INTERPRETER_ENGINE = PersistentConfig(
+    "CODE_INTERPRETER_ENGINE",
+    "code_interpreter.engine",
+    os.environ.get("CODE_INTERPRETER_ENGINE", "pyodide"),
+)
+
+CODE_INTERPRETER_JUPYTER_URL = PersistentConfig(
+    "CODE_INTERPRETER_JUPYTER_URL",
+    "code_interpreter.jupyter.url",
+    os.environ.get("CODE_INTERPRETER_JUPYTER_URL", ""),
+)
+
+CODE_INTERPRETER_JUPYTER_AUTH = PersistentConfig(
+    "CODE_INTERPRETER_JUPYTER_AUTH",
+    "code_interpreter.jupyter.auth",
+    os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH", ""),
+)
+
+CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = PersistentConfig(
+    "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN",
+    "code_interpreter.jupyter.auth_token",
+    os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH_TOKEN", ""),
+)
+
+
+CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = PersistentConfig(
+    "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD",
+    "code_interpreter.jupyter.auth_password",
+    os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD", ""),
+)
+
+
 DEFAULT_CODE_INTERPRETER_PROMPT = """
 #### Tools Available
 
@@ -1645,7 +1688,7 @@ RAG_WEB_SEARCH_ENGINE = PersistentConfig(
 # This ensures the highest level of safety and reliability of the information sources.
 RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = PersistentConfig(
     "RAG_WEB_SEARCH_DOMAIN_FILTER_LIST",
-    "rag.rag.web.search.domain.filter_list",
+    "rag.web.search.domain.filter_list",
     [
         # "wikipedia.com",
         # "wikimedia.org",
@@ -2012,6 +2055,12 @@ WHISPER_MODEL_AUTO_UPDATE = (
     and os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true"
 )
 
+# Add Deepgram configuration
+DEEPGRAM_API_KEY = PersistentConfig(
+    "DEEPGRAM_API_KEY",
+    "audio.stt.deepgram.api_key",
+    os.getenv("DEEPGRAM_API_KEY", ""),
+)
 
 AUDIO_STT_OPENAI_API_BASE_URL = PersistentConfig(
     "AUDIO_STT_OPENAI_API_BASE_URL",

+ 1 - 0
backend/open_webui/env.py

@@ -92,6 +92,7 @@ log_sources = [
     "RAG",
     "WEBHOOK",
     "SOCKET",
+    "OAUTH",
 ]
 
 SRC_LOG_LEVELS = {}

+ 30 - 1
backend/open_webui/main.py

@@ -97,6 +97,13 @@ from open_webui.config import (
     OPENAI_API_BASE_URLS,
     OPENAI_API_KEYS,
     OPENAI_API_CONFIGS,
+    # Code Interpreter
+    ENABLE_CODE_INTERPRETER,
+    CODE_INTERPRETER_ENGINE,
+    CODE_INTERPRETER_JUPYTER_URL,
+    CODE_INTERPRETER_JUPYTER_AUTH,
+    CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
+    CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
     # Image
     AUTOMATIC1111_API_AUTH,
     AUTOMATIC1111_BASE_URL,
@@ -130,6 +137,7 @@ from open_webui.config import (
     AUDIO_TTS_AZURE_SPEECH_REGION,
     AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT,
     WHISPER_MODEL,
+    DEEPGRAM_API_KEY,
     WHISPER_MODEL_AUTO_UPDATE,
     WHISPER_MODEL_DIR,
     # Retrieval
@@ -569,6 +577,23 @@ app.state.EMBEDDING_FUNCTION = get_embedding_function(
     app.state.config.RAG_EMBEDDING_BATCH_SIZE,
 )
 
+########################################
+#
+# CODE INTERPRETER
+#
+########################################
+
+app.state.config.ENABLE_CODE_INTERPRETER = ENABLE_CODE_INTERPRETER
+app.state.config.CODE_INTERPRETER_ENGINE = CODE_INTERPRETER_ENGINE
+
+app.state.config.CODE_INTERPRETER_JUPYTER_URL = CODE_INTERPRETER_JUPYTER_URL
+app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = CODE_INTERPRETER_JUPYTER_AUTH
+app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = (
+    CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
+)
+app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = (
+    CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
+)
 
 ########################################
 #
@@ -611,6 +636,7 @@ app.state.config.STT_ENGINE = AUDIO_STT_ENGINE
 app.state.config.STT_MODEL = AUDIO_STT_MODEL
 
 app.state.config.WHISPER_MODEL = WHISPER_MODEL
+app.state.config.DEEPGRAM_API_KEY = DEEPGRAM_API_KEY
 
 app.state.config.TTS_OPENAI_API_BASE_URL = AUDIO_TTS_OPENAI_API_BASE_URL
 app.state.config.TTS_OPENAI_API_KEY = AUDIO_TTS_OPENAI_API_KEY
@@ -753,6 +779,7 @@ app.include_router(openai.router, prefix="/openai", tags=["openai"])
 app.include_router(pipelines.router, prefix="/api/v1/pipelines", tags=["pipelines"])
 app.include_router(tasks.router, prefix="/api/v1/tasks", tags=["tasks"])
 app.include_router(images.router, prefix="/api/v1/images", tags=["images"])
+
 app.include_router(audio.router, prefix="/api/v1/audio", tags=["audio"])
 app.include_router(retrieval.router, prefix="/api/v1/retrieval", tags=["retrieval"])
 
@@ -1013,12 +1040,14 @@ async def get_app_config(request: Request):
                 {
                     "enable_channels": app.state.config.ENABLE_CHANNELS,
                     "enable_web_search": app.state.config.ENABLE_RAG_WEB_SEARCH,
-                    "enable_google_drive_integration": app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
+                    "enable_code_interpreter": app.state.config.ENABLE_CODE_INTERPRETER,
                     "enable_image_generation": app.state.config.ENABLE_IMAGE_GENERATION,
+                    "enable_autocomplete_generation": app.state.config.ENABLE_AUTOCOMPLETE_GENERATION,
                     "enable_community_sharing": app.state.config.ENABLE_COMMUNITY_SHARING,
                     "enable_message_rating": app.state.config.ENABLE_MESSAGE_RATING,
                     "enable_admin_export": ENABLE_ADMIN_EXPORT,
                     "enable_admin_chat_access": ENABLE_ADMIN_CHAT_ACCESS,
+                    "enable_google_drive_integration": app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
                 }
                 if user is not None
                 else {}

+ 1 - 1
backend/open_webui/models/chats.py

@@ -470,7 +470,7 @@ class ChatTable:
         try:
             with get_db() as db:
                 # it is possible that the shared link was deleted. hence,
-                # we check if the chat is still shared by checkng if a chat with the share_id exists
+                # we check if the chat is still shared by checking if a chat with the share_id exists
                 chat = db.query(Chat).filter_by(share_id=id).first()
 
                 if chat:

+ 28 - 0
backend/open_webui/retrieval/vector/dbs/opensearch.py

@@ -113,6 +113,34 @@ class OpenSearchClient:
 
         return self._result_to_search_result(result)
 
+    def query(
+        self, collection_name: str, filter: dict, limit: Optional[int] = None
+    ) -> Optional[GetResult]:
+        if not self.has_collection(collection_name):
+            return None
+
+        query_body = {
+            "query": {"bool": {"filter": []}},
+            "_source": ["text", "metadata"],
+        }
+
+        for field, value in filter.items():
+            query_body["query"]["bool"]["filter"].append({"term": {field: value}})
+
+        size = limit if limit else 10
+
+        try:
+            result = self.client.search(
+                index=f"{self.index_prefix}_{collection_name}",
+                body=query_body,
+                size=size,
+            )
+
+            return self._result_to_get_result(result)
+
+        except Exception as e:
+            return None
+
     def get_or_create_index(self, index_name: str, dimension: int):
         if not self.has_index(index_name):
             self._create_index(index_name, dimension)

+ 13 - 4
backend/open_webui/retrieval/web/jina_search.py

@@ -20,14 +20,23 @@ def search_jina(api_key: str, query: str, count: int) -> list[SearchResult]:
         list[SearchResult]: A list of search results
     """
     jina_search_endpoint = "https://s.jina.ai/"
-    headers = {"Accept": "application/json", "Authorization": f"Bearer {api_key}"}
-    url = str(URL(jina_search_endpoint + query))
-    response = requests.get(url, headers=headers)
+
+    headers = {
+        "Accept": "application/json",
+        "Content-Type": "application/json",
+        "Authorization": api_key,
+        "X-Retain-Images": "none",
+    }
+
+    payload = {"q": query, "count": count if count <= 10 else 10}
+
+    url = str(URL(jina_search_endpoint))
+    response = requests.post(url, headers=headers, json=payload)
     response.raise_for_status()
     data = response.json()
 
     results = []
-    for result in data["data"][:count]:
+    for result in data["data"]:
         results.append(
             SearchResult(
                 link=result["url"],

+ 68 - 0
backend/open_webui/routers/audio.py

@@ -11,6 +11,7 @@ from pydub.silence import split_on_silence
 import aiohttp
 import aiofiles
 import requests
+import mimetypes
 
 from fastapi import (
     Depends,
@@ -138,6 +139,7 @@ class STTConfigForm(BaseModel):
     ENGINE: str
     MODEL: str
     WHISPER_MODEL: str
+    DEEPGRAM_API_KEY: str
 
 
 class AudioConfigUpdateForm(BaseModel):
@@ -165,6 +167,7 @@ async def get_audio_config(request: Request, user=Depends(get_admin_user)):
             "ENGINE": request.app.state.config.STT_ENGINE,
             "MODEL": request.app.state.config.STT_MODEL,
             "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL,
+            "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY,
         },
     }
 
@@ -190,6 +193,7 @@ async def update_audio_config(
     request.app.state.config.STT_ENGINE = form_data.stt.ENGINE
     request.app.state.config.STT_MODEL = form_data.stt.MODEL
     request.app.state.config.WHISPER_MODEL = form_data.stt.WHISPER_MODEL
+    request.app.state.config.DEEPGRAM_API_KEY = form_data.stt.DEEPGRAM_API_KEY
 
     if request.app.state.config.STT_ENGINE == "":
         request.app.state.faster_whisper_model = set_faster_whisper_model(
@@ -214,6 +218,7 @@ async def update_audio_config(
             "ENGINE": request.app.state.config.STT_ENGINE,
             "MODEL": request.app.state.config.STT_MODEL,
             "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL,
+            "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY,
         },
     }
 
@@ -521,6 +526,69 @@ def transcribe(request: Request, file_path):
 
             raise Exception(detail if detail else "Open WebUI: Server Connection Error")
 
+    elif request.app.state.config.STT_ENGINE == "deepgram":
+        try:
+            # Determine the MIME type of the file
+            mime, _ = mimetypes.guess_type(file_path)
+            if not mime:
+                mime = "audio/wav"  # fallback to wav if undetectable
+
+            # Read the audio file
+            with open(file_path, "rb") as f:
+                file_data = f.read()
+
+            # Build headers and parameters
+            headers = {
+                "Authorization": f"Token {request.app.state.config.DEEPGRAM_API_KEY}",
+                "Content-Type": mime,
+            }
+
+            # Add model if specified
+            params = {}
+            if request.app.state.config.STT_MODEL:
+                params["model"] = request.app.state.config.STT_MODEL
+
+            # Make request to Deepgram API
+            r = requests.post(
+                "https://api.deepgram.com/v1/listen",
+                headers=headers,
+                params=params,
+                data=file_data,
+            )
+            r.raise_for_status()
+            response_data = r.json()
+
+            # Extract transcript from Deepgram response
+            try:
+                transcript = response_data["results"]["channels"][0]["alternatives"][
+                    0
+                ].get("transcript", "")
+            except (KeyError, IndexError) as e:
+                log.error(f"Malformed response from Deepgram: {str(e)}")
+                raise Exception(
+                    "Failed to parse Deepgram response - unexpected response format"
+                )
+            data = {"text": transcript.strip()}
+
+            # Save transcript
+            transcript_file = f"{file_dir}/{id}.json"
+            with open(transcript_file, "w") as f:
+                json.dump(data, f)
+
+            return data
+
+        except Exception as e:
+            log.exception(e)
+            detail = None
+            if r is not None:
+                try:
+                    res = r.json()
+                    if "error" in res:
+                        detail = f"External: {res['error'].get('message', '')}"
+                except Exception:
+                    detail = f"External: {e}"
+            raise Exception(detail if detail else "Open WebUI: Server Connection Error")
+
 
 def compress_audio(file_path):
     if os.path.getsize(file_path) > MAX_FILE_SIZE:

+ 55 - 0
backend/open_webui/routers/configs.py

@@ -36,6 +36,61 @@ async def export_config(user=Depends(get_admin_user)):
     return get_config()
 
 
+############################
+# CodeInterpreterConfig
+############################
+class CodeInterpreterConfigForm(BaseModel):
+    ENABLE_CODE_INTERPRETER: bool
+    CODE_INTERPRETER_ENGINE: str
+    CODE_INTERPRETER_JUPYTER_URL: Optional[str]
+    CODE_INTERPRETER_JUPYTER_AUTH: Optional[str]
+    CODE_INTERPRETER_JUPYTER_AUTH_TOKEN: Optional[str]
+    CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD: Optional[str]
+
+
+@router.get("/code_interpreter", response_model=CodeInterpreterConfigForm)
+async def get_code_interpreter_config(request: Request, user=Depends(get_admin_user)):
+    return {
+        "ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER,
+        "CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE,
+        "CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
+        "CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH,
+        "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
+        "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
+    }
+
+
+@router.post("/code_interpreter", response_model=CodeInterpreterConfigForm)
+async def set_code_interpreter_config(
+    request: Request, form_data: CodeInterpreterConfigForm, user=Depends(get_admin_user)
+):
+    request.app.state.config.ENABLE_CODE_INTERPRETER = form_data.ENABLE_CODE_INTERPRETER
+    request.app.state.config.CODE_INTERPRETER_ENGINE = form_data.CODE_INTERPRETER_ENGINE
+    request.app.state.config.CODE_INTERPRETER_JUPYTER_URL = (
+        form_data.CODE_INTERPRETER_JUPYTER_URL
+    )
+
+    request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = (
+        form_data.CODE_INTERPRETER_JUPYTER_AUTH
+    )
+
+    request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = (
+        form_data.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
+    )
+    request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = (
+        form_data.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
+    )
+
+    return {
+        "ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER,
+        "CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE,
+        "CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
+        "CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH,
+        "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
+        "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
+    }
+
+
 ############################
 # SetDefaultModels
 ############################

+ 73 - 46
backend/open_webui/routers/ollama.py

@@ -11,10 +11,8 @@ import re
 import time
 from typing import Optional, Union
 from urllib.parse import urlparse
-
 import aiohttp
 from aiocache import cached
-
 import requests
 
 from fastapi import (
@@ -990,6 +988,8 @@ async def generate_chat_completion(
         )
 
     payload = {**form_data.model_dump(exclude_none=True)}
+    if "metadata" in payload:
+        del payload["metadata"]
 
     model_id = payload["model"]
     model_info = Models.get_model_by_id(model_id)
@@ -1408,9 +1408,10 @@ async def download_model(
         return None
 
 
+# TODO: Progress bar does not reflect size & duration of upload.
 @router.post("/models/upload")
 @router.post("/models/upload/{url_idx}")
-def upload_model(
+async def upload_model(
     request: Request,
     file: UploadFile = File(...),
     url_idx: Optional[int] = None,
@@ -1419,59 +1420,85 @@ def upload_model(
     if url_idx is None:
         url_idx = 0
     ollama_url = request.app.state.config.OLLAMA_BASE_URLS[url_idx]
-
-    file_path = f"{UPLOAD_DIR}/{file.filename}"
-
-    # Save file in chunks
-    with open(file_path, "wb+") as f:
-        for chunk in file.file:
-            f.write(chunk)
-
-    def file_process_stream():
+    file_path = os.path.join(UPLOAD_DIR, file.filename)
+    os.makedirs(UPLOAD_DIR, exist_ok=True)
+
+    # --- P1: save file locally ---
+    chunk_size = 1024 * 1024 * 2  # 2 MB chunks
+    with open(file_path, "wb") as out_f:
+        while True:
+            chunk = file.file.read(chunk_size)
+            # log.info(f"Chunk: {str(chunk)}") # DEBUG
+            if not chunk:
+                break
+            out_f.write(chunk)
+
+    async def file_process_stream():
         nonlocal ollama_url
         total_size = os.path.getsize(file_path)
-        chunk_size = 1024 * 1024
+        log.info(f"Total Model Size: {str(total_size)}")  # DEBUG
+
+        # --- P2: SSE progress + calculate sha256 hash ---
+        file_hash = calculate_sha256(file_path, chunk_size)
+        log.info(f"Model Hash: {str(file_hash)}")  # DEBUG
         try:
             with open(file_path, "rb") as f:
-                total = 0
-                done = False
-
-                while not done:
-                    chunk = f.read(chunk_size)
-                    if not chunk:
-                        done = True
-                        continue
-
-                    total += len(chunk)
-                    progress = round((total / total_size) * 100, 2)
-
-                    res = {
+                bytes_read = 0
+                while chunk := f.read(chunk_size):
+                    bytes_read += len(chunk)
+                    progress = round(bytes_read / total_size * 100, 2)
+                    data_msg = {
                         "progress": progress,
                         "total": total_size,
-                        "completed": total,
+                        "completed": bytes_read,
                     }
-                    yield f"data: {json.dumps(res)}\n\n"
+                    yield f"data: {json.dumps(data_msg)}\n\n"
 
-                if done:
-                    f.seek(0)
-                    hashed = calculate_sha256(f)
-                    f.seek(0)
+            # --- P3: Upload to ollama /api/blobs ---
+            with open(file_path, "rb") as f:
+                url = f"{ollama_url}/api/blobs/sha256:{file_hash}"
+                response = requests.post(url, data=f)
+
+            if response.ok:
+                log.info(f"Uploaded to /api/blobs")  # DEBUG
+                # Remove local file
+                os.remove(file_path)
+
+                # Create model in ollama
+                model_name, ext = os.path.splitext(file.filename)
+                log.info(f"Created Model: {model_name}")  # DEBUG
+
+                create_payload = {
+                    "model": model_name,
+                    # Reference the file by its original name => the uploaded blob's digest
+                    "files": {file.filename: f"sha256:{file_hash}"},
+                }
+                log.info(f"Model Payload: {create_payload}")  # DEBUG
+
+                # Call ollama /api/create
+                # https://github.com/ollama/ollama/blob/main/docs/api.md#create-a-model
+                create_resp = requests.post(
+                    url=f"{ollama_url}/api/create",
+                    headers={"Content-Type": "application/json"},
+                    data=json.dumps(create_payload),
+                )
 
-                    url = f"{ollama_url}/api/blobs/sha256:{hashed}"
-                    response = requests.post(url, data=f)
+                if create_resp.ok:
+                    log.info(f"API SUCCESS!")  # DEBUG
+                    done_msg = {
+                        "done": True,
+                        "blob": f"sha256:{file_hash}",
+                        "name": file.filename,
+                        "model_created": model_name,
+                    }
+                    yield f"data: {json.dumps(done_msg)}\n\n"
+                else:
+                    raise Exception(
+                        f"Failed to create model in Ollama. {create_resp.text}"
+                    )
 
-                    if response.ok:
-                        res = {
-                            "done": done,
-                            "blob": f"sha256:{hashed}",
-                            "name": file.filename,
-                        }
-                        os.remove(file_path)
-                        yield f"data: {json.dumps(res)}\n\n"
-                    else:
-                        raise Exception(
-                            "Ollama: Could not create blob, Please try again."
-                        )
+            else:
+                raise Exception("Ollama: Could not create blob, Please try again.")
 
         except Exception as e:
             res = {"error": str(e)}

+ 6 - 6
backend/open_webui/routers/openai.py

@@ -75,9 +75,9 @@ async def cleanup_response(
         await session.close()
 
 
-def openai_o1_handler(payload):
+def openai_o1_o3_handler(payload):
     """
-    Handle O1 specific parameters
+    Handle o1, o3 specific parameters
     """
     if "max_tokens" in payload:
         # Remove "max_tokens" from the payload
@@ -621,10 +621,10 @@ async def generate_chat_completion(
     url = request.app.state.config.OPENAI_API_BASE_URLS[idx]
     key = request.app.state.config.OPENAI_API_KEYS[idx]
 
-    # Fix: O1 does not support the "max_tokens" parameter, Modify "max_tokens" to "max_completion_tokens"
-    is_o1 = payload["model"].lower().startswith("o1-")
-    if is_o1:
-        payload = openai_o1_handler(payload)
+    # Fix: o1,o3 does not support the "max_tokens" parameter, Modify "max_tokens" to "max_completion_tokens"
+    is_o1_o3 = payload["model"].lower().startswith(("o1", "o3-"))
+    if is_o1_o3:
+        payload = openai_o1_o3_handler(payload)
     elif "api.openai.com" not in url:
         # Remove "max_completion_tokens" from the payload for backward compatibility
         if "max_completion_tokens" in payload:

+ 6 - 0
backend/open_webui/routers/retrieval.py

@@ -392,6 +392,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
                 "exa_api_key": request.app.state.config.EXA_API_KEY,
                 "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
                 "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
+                "domain_filter_list": request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
             },
         },
     }
@@ -441,6 +442,7 @@ class WebSearchConfig(BaseModel):
     exa_api_key: Optional[str] = None
     result_count: Optional[int] = None
     concurrent_requests: Optional[int] = None
+    domain_filter_list: Optional[List[str]] = []
 
 
 class WebConfig(BaseModel):
@@ -553,6 +555,9 @@ async def update_rag_config(
         request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS = (
             form_data.web.search.concurrent_requests
         )
+        request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = (
+            form_data.web.search.domain_filter_list
+        )
 
     return {
         "status": True,
@@ -599,6 +604,7 @@ async def update_rag_config(
                 "exa_api_key": request.app.state.config.EXA_API_KEY,
                 "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
                 "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
+                "domain_filter_list": request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
             },
         },
     }

+ 21 - 7
backend/open_webui/storage/provider.py

@@ -10,6 +10,7 @@ from open_webui.config import (
     S3_ACCESS_KEY_ID,
     S3_BUCKET_NAME,
     S3_ENDPOINT_URL,
+    S3_KEY_PREFIX,
     S3_REGION_NAME,
     S3_SECRET_ACCESS_KEY,
     GCS_BUCKET_NAME,
@@ -93,15 +94,17 @@ class S3StorageProvider(StorageProvider):
             aws_secret_access_key=S3_SECRET_ACCESS_KEY,
         )
         self.bucket_name = S3_BUCKET_NAME
+        self.key_prefix = S3_KEY_PREFIX if S3_KEY_PREFIX else ""
 
     def upload_file(self, file: BinaryIO, filename: str) -> Tuple[bytes, str]:
         """Handles uploading of the file to S3 storage."""
         _, file_path = LocalStorageProvider.upload_file(file, filename)
         try:
-            self.s3_client.upload_file(file_path, self.bucket_name, filename)
+            s3_key = os.path.join(self.key_prefix, filename)
+            self.s3_client.upload_file(file_path, self.bucket_name, s3_key)
             return (
                 open(file_path, "rb").read(),
-                "s3://" + self.bucket_name + "/" + filename,
+                "s3://" + self.bucket_name + "/" + s3_key,
             )
         except ClientError as e:
             raise RuntimeError(f"Error uploading file to S3: {e}")
@@ -109,18 +112,18 @@ class S3StorageProvider(StorageProvider):
     def get_file(self, file_path: str) -> str:
         """Handles downloading of the file from S3 storage."""
         try:
-            bucket_name, key = file_path.split("//")[1].split("/")
-            local_file_path = f"{UPLOAD_DIR}/{key}"
-            self.s3_client.download_file(bucket_name, key, local_file_path)
+            s3_key = self._extract_s3_key(file_path)
+            local_file_path = self._get_local_file_path(s3_key)
+            self.s3_client.download_file(self.bucket_name, s3_key, local_file_path)
             return local_file_path
         except ClientError as e:
             raise RuntimeError(f"Error downloading file from S3: {e}")
 
     def delete_file(self, file_path: str) -> None:
         """Handles deletion of the file from S3 storage."""
-        filename = file_path.split("/")[-1]
         try:
-            self.s3_client.delete_object(Bucket=self.bucket_name, Key=filename)
+            s3_key = self._extract_s3_key(file_path)
+            self.s3_client.delete_object(Bucket=self.bucket_name, Key=s3_key)
         except ClientError as e:
             raise RuntimeError(f"Error deleting file from S3: {e}")
 
@@ -133,6 +136,10 @@ class S3StorageProvider(StorageProvider):
             response = self.s3_client.list_objects_v2(Bucket=self.bucket_name)
             if "Contents" in response:
                 for content in response["Contents"]:
+                    # Skip objects that were not uploaded from open-webui in the first place
+                    if not content["Key"].startswith(self.key_prefix):
+                        continue
+
                     self.s3_client.delete_object(
                         Bucket=self.bucket_name, Key=content["Key"]
                     )
@@ -142,6 +149,13 @@ class S3StorageProvider(StorageProvider):
         # Always delete from local storage
         LocalStorageProvider.delete_all_files()
 
+    # The s3 key is the name assigned to an object. It excludes the bucket name, but includes the internal path and the file name.
+    def _extract_s3_key(self, full_file_path: str) -> str:
+        return "/".join(full_file_path.split("//")[1].split("/")[1:])
+
+    def _get_local_file_path(self, s3_key: str) -> str:
+        return f"{UPLOAD_DIR}/{s3_key.split('/')[-1]}"
+
 
 class GCSStorageProvider(StorageProvider):
     def __init__(self):

+ 35 - 109
backend/open_webui/utils/chat.py

@@ -44,6 +44,10 @@ from open_webui.utils.response import (
     convert_response_ollama_to_openai,
     convert_streaming_response_ollama_to_openai,
 )
+from open_webui.utils.filter import (
+    get_sorted_filter_ids,
+    process_filter_functions,
+)
 
 from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL
 
@@ -177,116 +181,38 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
     except Exception as e:
         return Exception(f"Error: {e}")
 
-    __event_emitter__ = get_event_emitter(
-        {
-            "chat_id": data["chat_id"],
-            "message_id": data["id"],
-            "session_id": data["session_id"],
-            "user_id": user.id,
-        }
-    )
-
-    __event_call__ = get_event_call(
-        {
-            "chat_id": data["chat_id"],
-            "message_id": data["id"],
-            "session_id": data["session_id"],
-            "user_id": user.id,
-        }
-    )
-
-    def get_priority(function_id):
-        function = Functions.get_function_by_id(function_id)
-        if function is not None and hasattr(function, "valves"):
-            # TODO: Fix FunctionModel to include vavles
-            return (function.valves if function.valves else {}).get("priority", 0)
-        return 0
-
-    filter_ids = [function.id for function in Functions.get_global_filter_functions()]
-    if "info" in model and "meta" in model["info"]:
-        filter_ids.extend(model["info"]["meta"].get("filterIds", []))
-        filter_ids = list(set(filter_ids))
-
-    enabled_filter_ids = [
-        function.id
-        for function in Functions.get_functions_by_type("filter", active_only=True)
-    ]
-    filter_ids = [
-        filter_id for filter_id in filter_ids if filter_id in enabled_filter_ids
-    ]
-
-    # Sort filter_ids by priority, using the get_priority function
-    filter_ids.sort(key=get_priority)
-
-    for filter_id in filter_ids:
-        filter = Functions.get_function_by_id(filter_id)
-        if not filter:
-            continue
-
-        if filter_id in request.app.state.FUNCTIONS:
-            function_module = request.app.state.FUNCTIONS[filter_id]
-        else:
-            function_module, _, _ = load_function_module_by_id(filter_id)
-            request.app.state.FUNCTIONS[filter_id] = function_module
-
-        if hasattr(function_module, "valves") and hasattr(function_module, "Valves"):
-            valves = Functions.get_function_valves_by_id(filter_id)
-            function_module.valves = function_module.Valves(
-                **(valves if valves else {})
-            )
-
-        if not hasattr(function_module, "outlet"):
-            continue
-        try:
-            outlet = function_module.outlet
-
-            # Get the signature of the function
-            sig = inspect.signature(outlet)
-            params = {"body": data}
-
-            # Extra parameters to be passed to the function
-            extra_params = {
-                "__model__": model,
-                "__id__": filter_id,
-                "__event_emitter__": __event_emitter__,
-                "__event_call__": __event_call__,
-                "__request__": request,
-            }
+    metadata = {
+        "chat_id": data["chat_id"],
+        "message_id": data["id"],
+        "session_id": data["session_id"],
+        "user_id": user.id,
+    }
+
+    extra_params = {
+        "__event_emitter__": get_event_emitter(metadata),
+        "__event_call__": get_event_call(metadata),
+        "__user__": {
+            "id": user.id,
+            "email": user.email,
+            "name": user.name,
+            "role": user.role,
+        },
+        "__metadata__": metadata,
+        "__request__": request,
+        "__model__": model,
+    }
 
-            # Add extra params in contained in function signature
-            for key, value in extra_params.items():
-                if key in sig.parameters:
-                    params[key] = value
-
-            if "__user__" in sig.parameters:
-                __user__ = {
-                    "id": user.id,
-                    "email": user.email,
-                    "name": user.name,
-                    "role": user.role,
-                }
-
-                try:
-                    if hasattr(function_module, "UserValves"):
-                        __user__["valves"] = function_module.UserValves(
-                            **Functions.get_user_valves_by_id_and_user_id(
-                                filter_id, user.id
-                            )
-                        )
-                except Exception as e:
-                    print(e)
-
-                params = {**params, "__user__": __user__}
-
-            if inspect.iscoroutinefunction(outlet):
-                data = await outlet(**params)
-            else:
-                data = outlet(**params)
-
-        except Exception as e:
-            return Exception(f"Error: {e}")
-
-    return data
+    try:
+        result, _ = await process_filter_functions(
+            request=request,
+            filter_ids=get_sorted_filter_ids(model),
+            filter_type="outlet",
+            form_data=data,
+            extra_params=extra_params,
+        )
+        return result
+    except Exception as e:
+        return Exception(f"Error: {e}")
 
 
 async def chat_action(request: Request, action_id: str, form_data: dict, user: Any):

+ 153 - 0
backend/open_webui/utils/code_interpreter.py

@@ -0,0 +1,153 @@
+import asyncio
+import json
+import uuid
+import websockets
+import requests
+from urllib.parse import urljoin
+
+
+async def execute_code_jupyter(
+    jupyter_url, code, token=None, password=None, timeout=10
+):
+    """
+    Executes Python code in a Jupyter kernel.
+    Supports authentication with a token or password.
+    :param jupyter_url: Jupyter server URL (e.g., "http://localhost:8888")
+    :param code: Code to execute
+    :param token: Jupyter authentication token (optional)
+    :param password: Jupyter password (optional)
+    :param timeout: WebSocket timeout in seconds (default: 10s)
+    :return: Dictionary with stdout, stderr, and result
+    """
+    session = requests.Session()  # Maintain cookies
+    headers = {}  # Headers for requests
+
+    # Authenticate using password
+    if password and not token:
+        try:
+            login_url = urljoin(jupyter_url, "/login")
+            response = session.get(login_url)
+            response.raise_for_status()
+
+            # Retrieve `_xsrf` token
+            xsrf_token = session.cookies.get("_xsrf")
+            if not xsrf_token:
+                raise ValueError("Failed to fetch _xsrf token")
+
+            # Send login request
+            login_data = {"_xsrf": xsrf_token, "password": password}
+            login_response = session.post(
+                login_url, data=login_data, cookies=session.cookies
+            )
+            login_response.raise_for_status()
+
+            # Update headers with `_xsrf`
+            headers["X-XSRFToken"] = xsrf_token
+        except Exception as e:
+            return {
+                "stdout": "",
+                "stderr": f"Authentication Error: {str(e)}",
+                "result": "",
+            }
+
+    # Construct API URLs with authentication token if provided
+    params = f"?token={token}" if token else ""
+    kernel_url = urljoin(jupyter_url, f"/api/kernels{params}")
+
+    try:
+        # Include cookies if authenticating with password
+        response = session.post(kernel_url, headers=headers, cookies=session.cookies)
+        response.raise_for_status()
+        kernel_id = response.json()["id"]
+
+        # Construct WebSocket URL
+        websocket_url = urljoin(
+            jupyter_url.replace("http", "ws"),
+            f"/api/kernels/{kernel_id}/channels{params}",
+        )
+
+        # **IMPORTANT:** Include authentication cookies for WebSockets
+        ws_headers = {}
+        if password and not token:
+            ws_headers["X-XSRFToken"] = session.cookies.get("_xsrf")
+            cookies = {name: value for name, value in session.cookies.items()}
+            ws_headers["Cookie"] = "; ".join(
+                [f"{name}={value}" for name, value in cookies.items()]
+            )
+
+        # Connect to the WebSocket
+        async with websockets.connect(
+            websocket_url, additional_headers=ws_headers
+        ) as ws:
+            msg_id = str(uuid.uuid4())
+
+            # Send execution request
+            execute_request = {
+                "header": {
+                    "msg_id": msg_id,
+                    "msg_type": "execute_request",
+                    "username": "user",
+                    "session": str(uuid.uuid4()),
+                    "date": "",
+                    "version": "5.3",
+                },
+                "parent_header": {},
+                "metadata": {},
+                "content": {
+                    "code": code,
+                    "silent": False,
+                    "store_history": True,
+                    "user_expressions": {},
+                    "allow_stdin": False,
+                    "stop_on_error": True,
+                },
+                "channel": "shell",
+            }
+            await ws.send(json.dumps(execute_request))
+
+            # Collect execution results
+            stdout, stderr, result = "", "", None
+            while True:
+                try:
+                    message = await asyncio.wait_for(ws.recv(), timeout)
+                    message_data = json.loads(message)
+                    if message_data.get("parent_header", {}).get("msg_id") == msg_id:
+                        msg_type = message_data.get("msg_type")
+                        if msg_type == "stream":
+                            if message_data["content"]["name"] == "stdout":
+                                stdout += message_data["content"]["text"]
+                            elif message_data["content"]["name"] == "stderr":
+                                stderr += message_data["content"]["text"]
+                        elif msg_type in ("execute_result", "display_data"):
+                            result = message_data["content"]["data"].get(
+                                "text/plain", ""
+                            )
+                        elif msg_type == "error":
+                            stderr += "\n".join(message_data["content"]["traceback"])
+                        elif (
+                            msg_type == "status"
+                            and message_data["content"]["execution_state"] == "idle"
+                        ):
+                            break
+                except asyncio.TimeoutError:
+                    stderr += "\nExecution timed out."
+                    break
+    except Exception as e:
+        return {"stdout": "", "stderr": f"Error: {str(e)}", "result": ""}
+    finally:
+        # Shutdown the kernel
+        if kernel_id:
+            requests.delete(
+                f"{kernel_url}/{kernel_id}", headers=headers, cookies=session.cookies
+            )
+
+    return {
+        "stdout": stdout.strip(),
+        "stderr": stderr.strip(),
+        "result": result.strip() if result else "",
+    }
+
+
+# Example Usage
+# asyncio.run(execute_code_jupyter("http://localhost:8888", "print('Hello, world!')", token="your-token"))
+# asyncio.run(execute_code_jupyter("http://localhost:8888", "print('Hello, world!')", password="your-password"))

+ 99 - 0
backend/open_webui/utils/filter.py

@@ -0,0 +1,99 @@
+import inspect
+from open_webui.utils.plugin import load_function_module_by_id
+from open_webui.models.functions import Functions
+
+
+def get_sorted_filter_ids(model):
+    def get_priority(function_id):
+        function = Functions.get_function_by_id(function_id)
+        if function is not None and hasattr(function, "valves"):
+            # TODO: Fix FunctionModel to include vavles
+            return (function.valves if function.valves else {}).get("priority", 0)
+        return 0
+
+    filter_ids = [function.id for function in Functions.get_global_filter_functions()]
+    if "info" in model and "meta" in model["info"]:
+        filter_ids.extend(model["info"]["meta"].get("filterIds", []))
+        filter_ids = list(set(filter_ids))
+
+    enabled_filter_ids = [
+        function.id
+        for function in Functions.get_functions_by_type("filter", active_only=True)
+    ]
+
+    filter_ids = [fid for fid in filter_ids if fid in enabled_filter_ids]
+    filter_ids.sort(key=get_priority)
+    return filter_ids
+
+
+async def process_filter_functions(
+    request, filter_ids, filter_type, form_data, extra_params
+):
+    skip_files = None
+
+    for filter_id in filter_ids:
+        filter = Functions.get_function_by_id(filter_id)
+        if not filter:
+            continue
+
+        if filter_id in request.app.state.FUNCTIONS:
+            function_module = request.app.state.FUNCTIONS[filter_id]
+        else:
+            function_module, _, _ = load_function_module_by_id(filter_id)
+            request.app.state.FUNCTIONS[filter_id] = function_module
+
+        # Check if the function has a file_handler variable
+        if filter_type == "inlet" and hasattr(function_module, "file_handler"):
+            skip_files = function_module.file_handler
+
+        # Apply valves to the function
+        if hasattr(function_module, "valves") and hasattr(function_module, "Valves"):
+            valves = Functions.get_function_valves_by_id(filter_id)
+            function_module.valves = function_module.Valves(
+                **(valves if valves else {})
+            )
+
+        # Prepare handler function
+        handler = getattr(function_module, filter_type, None)
+        if not handler:
+            continue
+
+        try:
+            # Prepare parameters
+            sig = inspect.signature(handler)
+            params = {"body": form_data} | {
+                k: v
+                for k, v in {
+                    **extra_params,
+                    "__id__": filter_id,
+                }.items()
+                if k in sig.parameters
+            }
+
+            # Handle user parameters
+            if "__user__" in sig.parameters:
+                if hasattr(function_module, "UserValves"):
+                    try:
+                        params["__user__"]["valves"] = function_module.UserValves(
+                            **Functions.get_user_valves_by_id_and_user_id(
+                                filter_id, params["__user__"]["id"]
+                            )
+                        )
+                    except Exception as e:
+                        print(e)
+
+            # Execute handler
+            if inspect.iscoroutinefunction(handler):
+                form_data = await handler(**params)
+            else:
+                form_data = handler(**params)
+
+        except Exception as e:
+            print(f"Error in {filter_type} handler {filter_id}: {e}")
+            raise e
+
+    # Handle file cleanup for inlet
+    if skip_files and "files" in form_data.get("metadata", {}):
+        del form_data["metadata"]["files"]
+
+    return form_data, {}

+ 1 - 1
backend/open_webui/utils/images/comfyui.py

@@ -161,7 +161,7 @@ async def comfyui_generate_image(
                 seed = (
                     payload.seed
                     if payload.seed
-                    else random.randint(0, 18446744073709551614)
+                    else random.randint(0, 1125899906842624)
                 )
                 for node_id in node.node_ids:
                     workflow[node_id]["inputs"][node.key] = seed

+ 81 - 108
backend/open_webui/utils/middleware.py

@@ -68,7 +68,11 @@ from open_webui.utils.misc import (
 )
 from open_webui.utils.tools import get_tools
 from open_webui.utils.plugin import load_function_module_by_id
-
+from open_webui.utils.filter import (
+    get_sorted_filter_ids,
+    process_filter_functions,
+)
+from open_webui.utils.code_interpreter import execute_code_jupyter
 
 from open_webui.tasks import create_task
 
@@ -91,99 +95,6 @@ log = logging.getLogger(__name__)
 log.setLevel(SRC_LOG_LEVELS["MAIN"])
 
 
-async def chat_completion_filter_functions_handler(request, body, model, extra_params):
-    skip_files = None
-
-    def get_filter_function_ids(model):
-        def get_priority(function_id):
-            function = Functions.get_function_by_id(function_id)
-            if function is not None and hasattr(function, "valves"):
-                # TODO: Fix FunctionModel
-                return (function.valves if function.valves else {}).get("priority", 0)
-            return 0
-
-        filter_ids = [
-            function.id for function in Functions.get_global_filter_functions()
-        ]
-        if "info" in model and "meta" in model["info"]:
-            filter_ids.extend(model["info"]["meta"].get("filterIds", []))
-            filter_ids = list(set(filter_ids))
-
-        enabled_filter_ids = [
-            function.id
-            for function in Functions.get_functions_by_type("filter", active_only=True)
-        ]
-
-        filter_ids = [
-            filter_id for filter_id in filter_ids if filter_id in enabled_filter_ids
-        ]
-
-        filter_ids.sort(key=get_priority)
-        return filter_ids
-
-    filter_ids = get_filter_function_ids(model)
-    for filter_id in filter_ids:
-        filter = Functions.get_function_by_id(filter_id)
-        if not filter:
-            continue
-
-        if filter_id in request.app.state.FUNCTIONS:
-            function_module = request.app.state.FUNCTIONS[filter_id]
-        else:
-            function_module, _, _ = load_function_module_by_id(filter_id)
-            request.app.state.FUNCTIONS[filter_id] = function_module
-
-        # Check if the function has a file_handler variable
-        if hasattr(function_module, "file_handler"):
-            skip_files = function_module.file_handler
-
-        # Apply valves to the function
-        if hasattr(function_module, "valves") and hasattr(function_module, "Valves"):
-            valves = Functions.get_function_valves_by_id(filter_id)
-            function_module.valves = function_module.Valves(
-                **(valves if valves else {})
-            )
-
-        if hasattr(function_module, "inlet"):
-            try:
-                inlet = function_module.inlet
-
-                # Create a dictionary of parameters to be passed to the function
-                params = {"body": body} | {
-                    k: v
-                    for k, v in {
-                        **extra_params,
-                        "__model__": model,
-                        "__id__": filter_id,
-                    }.items()
-                    if k in inspect.signature(inlet).parameters
-                }
-
-                if "__user__" in params and hasattr(function_module, "UserValves"):
-                    try:
-                        params["__user__"]["valves"] = function_module.UserValves(
-                            **Functions.get_user_valves_by_id_and_user_id(
-                                filter_id, params["__user__"]["id"]
-                            )
-                        )
-                    except Exception as e:
-                        print(e)
-
-                if inspect.iscoroutinefunction(inlet):
-                    body = await inlet(**params)
-                else:
-                    body = inlet(**params)
-
-            except Exception as e:
-                print(f"Error: {e}")
-                raise e
-
-    if skip_files and "files" in body.get("metadata", {}):
-        del body["metadata"]["files"]
-
-    return body, {}
-
-
 async def chat_completion_tools_handler(
     request: Request, body: dict, user: UserModel, models, tools
 ) -> tuple[dict, dict]:
@@ -572,13 +483,13 @@ async def chat_image_generation_handler(
             {
                 "type": "status",
                 "data": {
-                    "description": f"An error occured while generating an image",
+                    "description": f"An error occurred while generating an image",
                     "done": True,
                 },
             }
         )
 
-        system_message_content = "<context>Unable to generate an image, tell the user that an error occured</context>"
+        system_message_content = "<context>Unable to generate an image, tell the user that an error occurred</context>"
 
     if system_message_content:
         form_data["messages"] = add_or_update_system_message(
@@ -706,6 +617,7 @@ async def process_chat_payload(request, form_data, metadata, user, model):
         },
         "__metadata__": metadata,
         "__request__": request,
+        "__model__": model,
     }
 
     # Initialize events to store additional event to be sent to the client
@@ -782,8 +694,12 @@ async def process_chat_payload(request, form_data, metadata, user, model):
             )
 
     try:
-        form_data, flags = await chat_completion_filter_functions_handler(
-            request, form_data, model, extra_params
+        form_data, flags = await process_filter_functions(
+            request=request,
+            filter_ids=get_sorted_filter_ids(model),
+            filter_type="inlet",
+            form_data=form_data,
+            extra_params=extra_params,
         )
     except Exception as e:
         raise Exception(f"Error: {e}")
@@ -1122,6 +1038,20 @@ async def process_chat_response(
             },
         )
 
+        def split_content_and_whitespace(content):
+            content_stripped = content.rstrip()
+            original_whitespace = (
+                content[len(content_stripped) :]
+                if len(content) > len(content_stripped)
+                else ""
+            )
+            return content_stripped, original_whitespace
+
+        def is_opening_code_block(content):
+            backtick_segments = content.split("```")
+            # Even number of segments means the last backticks are opening a new block
+            return len(backtick_segments) > 1 and len(backtick_segments) % 2 == 0
+
         # Handle as a background task
         async def post_response_handler(response, events):
             def serialize_content_blocks(content_blocks, raw=False):
@@ -1188,6 +1118,19 @@ async def process_chat_response(
                         output = block.get("output", None)
                         lang = attributes.get("lang", "")
 
+                        content_stripped, original_whitespace = (
+                            split_content_and_whitespace(content)
+                        )
+                        if is_opening_code_block(content_stripped):
+                            # Remove trailing backticks that would open a new block
+                            content = (
+                                content_stripped.rstrip("`").rstrip()
+                                + original_whitespace
+                            )
+                        else:
+                            # Keep content as is - either closing backticks or no backticks
+                            content = content_stripped + original_whitespace
+
                         if output:
                             output = html.escape(json.dumps(output))
 
@@ -1242,10 +1185,10 @@ async def process_chat_response(
                                 match.end() :
                             ]  # Content after opening tag
 
-                            # Remove the start tag from the currently handling text block
+                            # Remove the start tag and after from the currently handling text block
                             content_blocks[-1]["content"] = content_blocks[-1][
                                 "content"
-                            ].replace(match.group(0), "")
+                            ].replace(match.group(0) + after_tag, "")
 
                             if before_tag:
                                 content_blocks[-1]["content"] = before_tag
@@ -1708,15 +1651,45 @@ async def process_chat_response(
                         output = ""
                         try:
                             if content_blocks[-1]["attributes"].get("type") == "code":
-                                output = await event_caller(
-                                    {
-                                        "type": "execute:python",
-                                        "data": {
-                                            "id": str(uuid4()),
-                                            "code": content_blocks[-1]["content"],
-                                        },
+                                code = content_blocks[-1]["content"]
+
+                                if (
+                                    request.app.state.config.CODE_INTERPRETER_ENGINE
+                                    == "pyodide"
+                                ):
+                                    output = await event_caller(
+                                        {
+                                            "type": "execute:python",
+                                            "data": {
+                                                "id": str(uuid4()),
+                                                "code": code,
+                                            },
+                                        }
+                                    )
+                                elif (
+                                    request.app.state.config.CODE_INTERPRETER_ENGINE
+                                    == "jupyter"
+                                ):
+                                    output = await execute_code_jupyter(
+                                        request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
+                                        code,
+                                        (
+                                            request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
+                                            if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH
+                                            == "token"
+                                            else None
+                                        ),
+                                        (
+                                            request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
+                                            if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH
+                                            == "password"
+                                            else None
+                                        ),
+                                    )
+                                else:
+                                    output = {
+                                        "stdout": "Code interpreter engine not configured."
                                     }
-                                )
 
                                 if isinstance(output, dict):
                                     stdout = output.get("stdout", "")

+ 5 - 4
backend/open_webui/utils/misc.py

@@ -244,11 +244,12 @@ def get_gravatar_url(email):
     return f"https://www.gravatar.com/avatar/{hash_hex}?d=mp"
 
 
-def calculate_sha256(file):
+def calculate_sha256(file_path, chunk_size):
+    # Compute SHA-256 hash of a file efficiently in chunks
     sha256 = hashlib.sha256()
-    # Read the file in chunks to efficiently handle large files
-    for chunk in iter(lambda: file.read(8192), b""):
-        sha256.update(chunk)
+    with open(file_path, "rb") as f:
+        while chunk := f.read(chunk_size):
+            sha256.update(chunk)
     return sha256.hexdigest()
 
 

+ 44 - 10
backend/open_webui/utils/oauth.py

@@ -1,6 +1,7 @@
 import base64
 import logging
 import mimetypes
+import sys
 import uuid
 
 import aiohttp
@@ -40,7 +41,11 @@ from open_webui.utils.misc import parse_duration
 from open_webui.utils.auth import get_password_hash, create_token
 from open_webui.utils.webhook import post_webhook
 
+from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL
+
+logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
 log = logging.getLogger(__name__)
+log.setLevel(SRC_LOG_LEVELS["OAUTH"])
 
 auth_manager_config = AppConfig()
 auth_manager_config.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE
@@ -72,12 +77,15 @@ class OAuthManager:
     def get_user_role(self, user, user_data):
         if user and Users.get_num_users() == 1:
             # If the user is the only user, assign the role "admin" - actually repairs role for single user on login
+            log.debug("Assigning the only user the admin role")
             return "admin"
         if not user and Users.get_num_users() == 0:
             # If there are no users, assign the role "admin", as the first user will be an admin
+            log.debug("Assigning the first user the admin role")
             return "admin"
 
         if auth_manager_config.ENABLE_OAUTH_ROLE_MANAGEMENT:
+            log.debug("Running OAUTH Role management")
             oauth_claim = auth_manager_config.OAUTH_ROLES_CLAIM
             oauth_allowed_roles = auth_manager_config.OAUTH_ALLOWED_ROLES
             oauth_admin_roles = auth_manager_config.OAUTH_ADMIN_ROLES
@@ -93,17 +101,24 @@ class OAuthManager:
                     claim_data = claim_data.get(nested_claim, {})
                 oauth_roles = claim_data if isinstance(claim_data, list) else None
 
+            log.debug(f"Oauth Roles claim: {oauth_claim}")
+            log.debug(f"User roles from oauth: {oauth_roles}")
+            log.debug(f"Accepted user roles: {oauth_allowed_roles}")
+            log.debug(f"Accepted admin roles: {oauth_admin_roles}")
+
             # If any roles are found, check if they match the allowed or admin roles
             if oauth_roles:
                 # If role management is enabled, and matching roles are provided, use the roles
                 for allowed_role in oauth_allowed_roles:
                     # If the user has any of the allowed roles, assign the role "user"
                     if allowed_role in oauth_roles:
+                        log.debug("Assigned user the user role")
                         role = "user"
                         break
                 for admin_role in oauth_admin_roles:
                     # If the user has any of the admin roles, assign the role "admin"
                     if admin_role in oauth_roles:
+                        log.debug("Assigned user the admin role")
                         role = "admin"
                         break
         else:
@@ -117,16 +132,27 @@ class OAuthManager:
         return role
 
     def update_user_groups(self, user, user_data, default_permissions):
+        log.debug("Running OAUTH Group management")
         oauth_claim = auth_manager_config.OAUTH_GROUPS_CLAIM
 
         user_oauth_groups: list[str] = user_data.get(oauth_claim, list())
         user_current_groups: list[GroupModel] = Groups.get_groups_by_member_id(user.id)
         all_available_groups: list[GroupModel] = Groups.get_groups()
 
+        log.debug(f"Oauth Groups claim: {oauth_claim}")
+        log.debug(f"User oauth groups: {user_oauth_groups}")
+        log.debug(f"User's current groups: {[g.name for g in user_current_groups]}")
+        log.debug(
+            f"All groups available in OpenWebUI: {[g.name for g in all_available_groups]}"
+        )
+
         # Remove groups that user is no longer a part of
         for group_model in user_current_groups:
             if group_model.name not in user_oauth_groups:
                 # Remove group from user
+                log.debug(
+                    f"Removing user from group {group_model.name} as it is no longer in their oauth groups"
+                )
 
                 user_ids = group_model.user_ids
                 user_ids = [i for i in user_ids if i != user.id]
@@ -152,6 +178,9 @@ class OAuthManager:
                 gm.name == group_model.name for gm in user_current_groups
             ):
                 # Add user to group
+                log.debug(
+                    f"Adding user to group {group_model.name} as it was found in their oauth groups"
+                )
 
                 user_ids = group_model.user_ids
                 user_ids.append(user.id)
@@ -193,7 +222,7 @@ class OAuthManager:
             log.warning(f"OAuth callback error: {e}")
             raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
         user_data: UserInfo = token.get("userinfo")
-        if not user_data:
+        if not user_data or "email" not in user_data:
             user_data: UserInfo = await client.userinfo(token=token)
         if not user_data:
             log.warning(f"OAuth callback failed, user data is missing: {token}")
@@ -261,15 +290,20 @@ class OAuthManager:
                             }
                         async with aiohttp.ClientSession() as session:
                             async with session.get(picture_url, **get_kwargs) as resp:
-                                picture = await resp.read()
-                                base64_encoded_picture = base64.b64encode(
-                                    picture
-                                ).decode("utf-8")
-                                guessed_mime_type = mimetypes.guess_type(picture_url)[0]
-                                if guessed_mime_type is None:
-                                    # assume JPG, browsers are tolerant enough of image formats
-                                    guessed_mime_type = "image/jpeg"
-                                picture_url = f"data:{guessed_mime_type};base64,{base64_encoded_picture}"
+                                if resp.ok:
+                                    picture = await resp.read()
+                                    base64_encoded_picture = base64.b64encode(
+                                        picture
+                                    ).decode("utf-8")
+                                    guessed_mime_type = mimetypes.guess_type(
+                                        picture_url
+                                    )[0]
+                                    if guessed_mime_type is None:
+                                        # assume JPG, browsers are tolerant enough of image formats
+                                        guessed_mime_type = "image/jpeg"
+                                    picture_url = f"data:{guessed_mime_type};base64,{base64_encoded_picture}"
+                                else:
+                                    picture_url = "/user.png"
                     except Exception as e:
                         log.error(
                             f"Error downloading profile image '{picture_url}': {e}"

+ 7 - 5
backend/open_webui/utils/pdf_generator.py

@@ -2,6 +2,7 @@ from datetime import datetime
 from io import BytesIO
 from pathlib import Path
 from typing import Dict, Any, List
+from html import escape
 
 from markdown import markdown
 
@@ -41,13 +42,13 @@ class PDFGenerator:
 
     def _build_html_message(self, message: Dict[str, Any]) -> str:
         """Build HTML for a single message."""
-        role = message.get("role", "user")
-        content = message.get("content", "")
+        role = escape(message.get("role", "user"))
+        content = escape(message.get("content", ""))
         timestamp = message.get("timestamp")
 
-        model = message.get("model") if role == "assistant" else ""
+        model = escape(message.get("model") if role == "assistant" else "")
 
-        date_str = self.format_timestamp(timestamp) if timestamp else ""
+        date_str = escape(self.format_timestamp(timestamp) if timestamp else "")
 
         # extends pymdownx extension to convert markdown to html.
         # - https://facelessuser.github.io/pymdown-extensions/usage_notes/
@@ -76,6 +77,7 @@ class PDFGenerator:
 
     def _generate_html_body(self) -> str:
         """Generate the full HTML body for the PDF."""
+        escaped_title = escape(self.form_data.title)
         return f"""
         <html>
             <head>
@@ -84,7 +86,7 @@ class PDFGenerator:
             <body>
             <div>
                 <div>
-                    <h2>{self.form_data.title}</h2>
+                    <h2>{escaped_title}</h2>
                     {self.messages_html}
                 </div>
             </div>

+ 4 - 2
backend/requirements.txt

@@ -32,6 +32,8 @@ boto3==1.35.53
 argon2-cffi==23.1.0
 APScheduler==3.10.4
 
+RestrictedPython==8.0
+
 # AI libraries
 openai
 anthropic
@@ -45,7 +47,7 @@ fake-useragent==1.5.1
 chromadb==0.6.2
 pymilvus==2.5.0
 qdrant-client~=1.12.0
-opensearch-py==2.7.1
+opensearch-py==2.8.0
 
 
 transformers
@@ -77,7 +79,7 @@ opencv-python-headless==4.11.0.86
 rapidocr-onnxruntime==1.3.24
 rank-bm25==0.2.2
 
-faster-whisper==1.0.3
+faster-whisper==1.1.1
 
 PyJWT[crypto]==2.10.1
 authlib==1.4.1

+ 186 - 120
package-lock.json

@@ -42,6 +42,7 @@
 				"idb": "^7.1.1",
 				"js-sha256": "^0.10.1",
 				"katex": "^0.16.21",
+				"kokoro-js": "^1.1.1",
 				"marked": "^9.1.0",
 				"mermaid": "^10.9.3",
 				"paneforge": "^0.0.6",
@@ -62,7 +63,8 @@
 				"svelte-sonner": "^0.3.19",
 				"tippy.js": "^6.3.7",
 				"turndown": "^7.2.0",
-				"uuid": "^9.0.1"
+				"uuid": "^9.0.1",
+				"vite-plugin-static-copy": "^2.2.0"
 			},
 			"devDependencies": {
 				"@sveltejs/adapter-auto": "3.2.2",
@@ -91,7 +93,7 @@
 				"tslib": "^2.4.1",
 				"typescript": "^5.5.4",
 				"vite": "^5.4.14",
-				"vitest": "^1.6.0"
+				"vitest": "^1.6.1"
 			},
 			"engines": {
 				"node": ">=18.13.0 <=22.x.x",
@@ -1078,21 +1080,23 @@
 			}
 		},
 		"node_modules/@huggingface/jinja": {
-			"version": "0.3.1",
-			"resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.3.1.tgz",
-			"integrity": "sha512-SbcBWUKDQ76lzlVYOloscUk0SJjuL1LcbZsfQv/Bxxc7dwJMYuS+DAQ+HhVw6ZkTFXArejaX5HQRuCuleYwYdA==",
+			"version": "0.3.3",
+			"resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.3.3.tgz",
+			"integrity": "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw==",
+			"license": "MIT",
 			"engines": {
 				"node": ">=18"
 			}
 		},
 		"node_modules/@huggingface/transformers": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-3.0.0.tgz",
-			"integrity": "sha512-OWIPnTijAw4DQ+IFHBOrej2SDdYyykYlTtpTLCEt5MZq/e9Cb65RS2YVhdGcgbaW/6JAL3i8ZA5UhDeWGm4iRQ==",
+			"version": "3.3.3",
+			"resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-3.3.3.tgz",
+			"integrity": "sha512-OcMubhBjW6u1xnp0zSt5SvCxdGHuhP2k+w2Vlm3i0vNcTJhJTZWxxYQmPBfcb7PX+Q6c43lGSzWD6tsJFwka4Q==",
+			"license": "Apache-2.0",
 			"dependencies": {
-				"@huggingface/jinja": "^0.3.0",
-				"onnxruntime-node": "1.19.2",
-				"onnxruntime-web": "1.20.0-dev.20241016-2b8fc5529b",
+				"@huggingface/jinja": "^0.3.3",
+				"onnxruntime-node": "1.20.1",
+				"onnxruntime-web": "1.21.0-dev.20250206-d981b153d3",
 				"sharp": "^0.33.5"
 			}
 		},
@@ -1546,6 +1550,7 @@
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
 			"integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+			"license": "ISC",
 			"dependencies": {
 				"minipass": "^7.0.4"
 			},
@@ -1558,6 +1563,7 @@
 			"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
 			"integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"@sinclair/typebox": "^0.27.8"
 			},
@@ -1798,7 +1804,6 @@
 			"version": "2.1.5",
 			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
 			"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-			"dev": true,
 			"dependencies": {
 				"@nodelib/fs.stat": "2.0.5",
 				"run-parallel": "^1.1.9"
@@ -1811,7 +1816,6 @@
 			"version": "2.0.5",
 			"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
 			"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-			"dev": true,
 			"engines": {
 				"node": ">= 8"
 			}
@@ -1820,7 +1824,6 @@
 			"version": "1.2.8",
 			"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
 			"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-			"dev": true,
 			"dependencies": {
 				"@nodelib/fs.scandir": "2.1.5",
 				"fastq": "^1.6.0"
@@ -1856,27 +1859,32 @@
 		"node_modules/@protobufjs/aspromise": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
-			"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+			"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/base64": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
-			"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+			"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/codegen": {
 			"version": "2.0.4",
 			"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
-			"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+			"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/eventemitter": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
-			"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+			"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/fetch": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
 			"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+			"license": "BSD-3-Clause",
 			"dependencies": {
 				"@protobufjs/aspromise": "^1.1.1",
 				"@protobufjs/inquire": "^1.1.0"
@@ -1885,27 +1893,32 @@
 		"node_modules/@protobufjs/float": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
-			"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+			"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/inquire": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
-			"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+			"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/path": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
-			"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+			"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/pool": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
-			"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+			"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@protobufjs/utf8": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
-			"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+			"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+			"license": "BSD-3-Clause"
 		},
 		"node_modules/@pyscript/core": {
 			"version": "0.4.32",
@@ -2210,7 +2223,8 @@
 			"version": "0.27.8",
 			"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
 			"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
-			"dev": true
+			"dev": true,
+			"license": "MIT"
 		},
 		"node_modules/@socket.io/component-emitter": {
 			"version": "3.1.2",
@@ -3146,13 +3160,14 @@
 			"integrity": "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw=="
 		},
 		"node_modules/@vitest/expect": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz",
-			"integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
+			"integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
-				"@vitest/spy": "1.6.0",
-				"@vitest/utils": "1.6.0",
+				"@vitest/spy": "1.6.1",
+				"@vitest/utils": "1.6.1",
 				"chai": "^4.3.10"
 			},
 			"funding": {
@@ -3160,12 +3175,13 @@
 			}
 		},
 		"node_modules/@vitest/runner": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz",
-			"integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz",
+			"integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
-				"@vitest/utils": "1.6.0",
+				"@vitest/utils": "1.6.1",
 				"p-limit": "^5.0.0",
 				"pathe": "^1.1.1"
 			},
@@ -3178,6 +3194,7 @@
 			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
 			"integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"yocto-queue": "^1.0.0"
 			},
@@ -3189,10 +3206,11 @@
 			}
 		},
 		"node_modules/@vitest/runner/node_modules/yocto-queue": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
-			"integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
+			"integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": ">=12.20"
 			},
@@ -3201,10 +3219,11 @@
 			}
 		},
 		"node_modules/@vitest/snapshot": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz",
-			"integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz",
+			"integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"magic-string": "^0.30.5",
 				"pathe": "^1.1.1",
@@ -3215,10 +3234,11 @@
 			}
 		},
 		"node_modules/@vitest/spy": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz",
-			"integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz",
+			"integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"tinyspy": "^2.2.0"
 			},
@@ -3227,10 +3247,11 @@
 			}
 		},
 		"node_modules/@vitest/utils": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz",
-			"integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz",
+			"integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"diff-sequences": "^29.6.3",
 				"estree-walker": "^3.0.3",
@@ -3246,6 +3267,7 @@
 			"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
 			"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"@types/estree": "^1.0.0"
 			}
@@ -3416,7 +3438,6 @@
 			"version": "3.1.3",
 			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
 			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
-			"dev": true,
 			"dependencies": {
 				"normalize-path": "^3.0.0",
 				"picomatch": "^2.0.4"
@@ -3496,6 +3517,7 @@
 			"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
 			"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": "*"
 			}
@@ -3644,7 +3666,6 @@
 			"version": "2.3.0",
 			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
 			"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
-			"dev": true,
 			"engines": {
 				"node": ">=8"
 			},
@@ -3720,7 +3741,6 @@
 			"version": "3.0.3",
 			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
 			"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-			"dev": true,
 			"dependencies": {
 				"fill-range": "^7.1.1"
 			},
@@ -3895,6 +3915,7 @@
 			"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
 			"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": ">=8"
 			}
@@ -3972,10 +3993,11 @@
 			"dev": true
 		},
 		"node_modules/chai": {
-			"version": "4.4.1",
-			"resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz",
-			"integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==",
+			"version": "4.5.0",
+			"resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
+			"integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"assertion-error": "^1.1.0",
 				"check-error": "^1.0.3",
@@ -3983,7 +4005,7 @@
 				"get-func-name": "^2.0.2",
 				"loupe": "^2.3.6",
 				"pathval": "^1.1.1",
-				"type-detect": "^4.0.8"
+				"type-detect": "^4.1.0"
 			},
 			"engines": {
 				"node": ">=4"
@@ -4019,6 +4041,7 @@
 			"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
 			"integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"get-func-name": "^2.0.2"
 			},
@@ -4077,7 +4100,6 @@
 			"version": "3.6.0",
 			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
 			"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-			"dev": true,
 			"dependencies": {
 				"anymatch": "~3.1.2",
 				"braces": "~3.0.2",
@@ -4101,7 +4123,6 @@
 			"version": "5.1.2",
 			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 			"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-			"dev": true,
 			"dependencies": {
 				"is-glob": "^4.0.1"
 			},
@@ -4113,6 +4134,7 @@
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
 			"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+			"license": "BlueOak-1.0.0",
 			"engines": {
 				"node": ">=18"
 			}
@@ -5135,10 +5157,11 @@
 			}
 		},
 		"node_modules/deep-eql": {
-			"version": "4.1.3",
-			"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
-			"integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
+			"version": "4.1.4",
+			"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
+			"integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"type-detect": "^4.0.0"
 			},
@@ -5257,6 +5280,7 @@
 			"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
 			"integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
 			}
@@ -5899,7 +5923,6 @@
 			"version": "3.3.2",
 			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
 			"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-			"dev": true,
 			"dependencies": {
 				"@nodelib/fs.stat": "^2.0.2",
 				"@nodelib/fs.walk": "^1.2.3",
@@ -5915,7 +5938,6 @@
 			"version": "5.1.2",
 			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 			"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-			"dev": true,
 			"dependencies": {
 				"is-glob": "^4.0.1"
 			},
@@ -5939,7 +5961,6 @@
 			"version": "1.17.1",
 			"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
 			"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-			"dev": true,
 			"dependencies": {
 				"reusify": "^1.0.4"
 			}
@@ -5998,7 +6019,6 @@
 			"version": "7.1.1",
 			"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
 			"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-			"dev": true,
 			"dependencies": {
 				"to-regex-range": "^5.0.1"
 			},
@@ -6037,9 +6057,10 @@
 			}
 		},
 		"node_modules/flatbuffers": {
-			"version": "1.12.0",
-			"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz",
-			"integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ=="
+			"version": "25.1.24",
+			"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.1.24.tgz",
+			"integrity": "sha512-Ni+KCqYquU30UEgGkrrwpbYtUcUmNuLFcQ5Xdy9DK7WUaji+AAov+Bf12FEYmu0eI15y31oD38utnBexe0cAYA==",
+			"license": "Apache-2.0"
 		},
 		"node_modules/flatted": {
 			"version": "3.3.1",
@@ -6110,7 +6131,6 @@
 			"version": "11.2.0",
 			"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
 			"integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
-			"dev": true,
 			"dependencies": {
 				"graceful-fs": "^4.2.0",
 				"jsonfile": "^6.0.1",
@@ -6238,6 +6258,7 @@
 			"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
 			"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": "*"
 			}
@@ -6429,8 +6450,7 @@
 		"node_modules/graceful-fs": {
 			"version": "4.2.11",
 			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-			"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-			"dev": true
+			"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
 		},
 		"node_modules/graphemer": {
 			"version": "1.4.0",
@@ -6441,7 +6461,8 @@
 		"node_modules/guid-typescript": {
 			"version": "1.0.9",
 			"resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
-			"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="
+			"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==",
+			"license": "ISC"
 		},
 		"node_modules/gulp-sort": {
 			"version": "2.0.0",
@@ -6809,7 +6830,6 @@
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
 			"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-			"dev": true,
 			"dependencies": {
 				"binary-extensions": "^2.0.0"
 			},
@@ -6858,7 +6878,6 @@
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 			"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-			"dev": true,
 			"engines": {
 				"node": ">=0.10.0"
 			}
@@ -6875,7 +6894,6 @@
 			"version": "4.0.3",
 			"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
 			"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-			"dev": true,
 			"dependencies": {
 				"is-extglob": "^2.1.1"
 			},
@@ -6917,7 +6935,6 @@
 			"version": "7.0.0",
 			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-			"dev": true,
 			"engines": {
 				"node": ">=0.12.0"
 			}
@@ -7097,7 +7114,6 @@
 			"version": "6.1.0",
 			"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
 			"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-			"dev": true,
 			"dependencies": {
 				"universalify": "^2.0.0"
 			},
@@ -7172,6 +7188,16 @@
 			"integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==",
 			"dev": true
 		},
+		"node_modules/kokoro-js": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/kokoro-js/-/kokoro-js-1.1.1.tgz",
+			"integrity": "sha512-cyLO34iI8nBJXPnd3fI4fGeQGS+a6Uatg7eXNL6QS8TLSxaa30WD6Fj7/XoIZYaHg8q6d+TCrui/f74MTY2g1g==",
+			"license": "Apache-2.0",
+			"dependencies": {
+				"@huggingface/transformers": "^3.3.3",
+				"phonemizer": "^1.2.1"
+			}
+		},
 		"node_modules/layout-base": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz",
@@ -7455,15 +7481,17 @@
 			}
 		},
 		"node_modules/long": {
-			"version": "5.2.3",
-			"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
-			"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+			"version": "5.2.4",
+			"resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz",
+			"integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==",
+			"license": "Apache-2.0"
 		},
 		"node_modules/loupe": {
 			"version": "2.3.7",
 			"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
 			"integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"get-func-name": "^2.0.1"
 			}
@@ -7609,7 +7637,6 @@
 			"version": "1.4.1",
 			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-			"dev": true,
 			"engines": {
 				"node": ">= 8"
 			}
@@ -8066,7 +8093,6 @@
 			"version": "4.0.8",
 			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
 			"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-			"dev": true,
 			"dependencies": {
 				"braces": "^3.0.3",
 				"picomatch": "^2.3.1"
@@ -8150,6 +8176,7 @@
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz",
 			"integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==",
+			"license": "MIT",
 			"dependencies": {
 				"minipass": "^7.0.4",
 				"rimraf": "^5.0.5"
@@ -8162,6 +8189,7 @@
 			"version": "10.4.5",
 			"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
 			"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+			"license": "ISC",
 			"dependencies": {
 				"foreground-child": "^3.1.0",
 				"jackspeak": "^3.1.2",
@@ -8181,6 +8209,7 @@
 			"version": "3.4.3",
 			"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
 			"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+			"license": "BlueOak-1.0.0",
 			"dependencies": {
 				"@isaacs/cliui": "^8.0.2"
 			},
@@ -8195,6 +8224,7 @@
 			"version": "9.0.5",
 			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
 			"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+			"license": "ISC",
 			"dependencies": {
 				"brace-expansion": "^2.0.1"
 			},
@@ -8209,6 +8239,7 @@
 			"version": "5.0.10",
 			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
 			"integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
+			"license": "ISC",
 			"dependencies": {
 				"glob": "^10.3.7"
 			},
@@ -8329,7 +8360,6 @@
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 			"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-			"dev": true,
 			"engines": {
 				"node": ">=0.10.0"
 			}
@@ -8433,42 +8463,46 @@
 			}
 		},
 		"node_modules/onnxruntime-common": {
-			"version": "1.19.2",
-			"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.19.2.tgz",
-			"integrity": "sha512-a4R7wYEVFbZBlp0BfhpbFWqe4opCor3KM+5Wm22Az3NGDcQMiU2hfG/0MfnBs+1ZrlSGmlgWeMcXQkDk1UFb8Q=="
+			"version": "1.20.1",
+			"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.20.1.tgz",
+			"integrity": "sha512-YiU0s0IzYYC+gWvqD1HzLc46Du1sXpSiwzKb63PACIJr6LfL27VsXSXQvt68EzD3V0D5Bc0vyJTjmMxp0ylQiw==",
+			"license": "MIT"
 		},
 		"node_modules/onnxruntime-node": {
-			"version": "1.19.2",
-			"resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.19.2.tgz",
-			"integrity": "sha512-9eHMP/HKbbeUcqte1JYzaaRC8JPn7ojWeCeoyShO86TOR97OCyIyAIOGX3V95ErjslVhJRXY8Em/caIUc0hm1Q==",
+			"version": "1.20.1",
+			"resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.20.1.tgz",
+			"integrity": "sha512-di/I4HDXRw+FLgq+TyHmQEDd3cEp9iFFZm0r4uJ1Wd7b/WE1VXtKWo8yemex347c6GNF/3Pv86ZfPhIWxORr0w==",
 			"hasInstallScript": true,
+			"license": "MIT",
 			"os": [
 				"win32",
 				"darwin",
 				"linux"
 			],
 			"dependencies": {
-				"onnxruntime-common": "1.19.2",
+				"onnxruntime-common": "1.20.1",
 				"tar": "^7.0.1"
 			}
 		},
 		"node_modules/onnxruntime-web": {
-			"version": "1.20.0-dev.20241016-2b8fc5529b",
-			"resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.20.0-dev.20241016-2b8fc5529b.tgz",
-			"integrity": "sha512-1XovqtgqeEFtupuyzdDQo7Tqj4GRyNHzOoXjapCEo4rfH3JrXok5VtqucWfRXHPsOI5qoNxMQ9VE+drDIp6woQ==",
+			"version": "1.21.0-dev.20250206-d981b153d3",
+			"resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.21.0-dev.20250206-d981b153d3.tgz",
+			"integrity": "sha512-esDVQdRic6J44VBMFLumYvcGfioMh80ceLmzF1yheJyuLKq/Th8VT2aj42XWQst+2bcWnAhw4IKmRQaqzU8ugg==",
+			"license": "MIT",
 			"dependencies": {
-				"flatbuffers": "^1.12.0",
+				"flatbuffers": "^25.1.24",
 				"guid-typescript": "^1.0.9",
 				"long": "^5.2.3",
-				"onnxruntime-common": "1.20.0-dev.20241016-2b8fc5529b",
+				"onnxruntime-common": "1.21.0-dev.20250206-d981b153d3",
 				"platform": "^1.3.6",
 				"protobufjs": "^7.2.4"
 			}
 		},
 		"node_modules/onnxruntime-web/node_modules/onnxruntime-common": {
-			"version": "1.20.0-dev.20241016-2b8fc5529b",
-			"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.20.0-dev.20241016-2b8fc5529b.tgz",
-			"integrity": "sha512-KZK8b6zCYGZFjd4ANze0pqBnqnFTS3GIVeclQpa2qseDpXrCQJfkWBixRcrZShNhm3LpFOZ8qJYFC5/qsJK9WQ=="
+			"version": "1.21.0-dev.20250206-d981b153d3",
+			"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.21.0-dev.20250206-d981b153d3.tgz",
+			"integrity": "sha512-TwaE51xV9q2y8pM61q73rbywJnusw9ivTEHAJ39GVWNZqxCoDBpe/tQkh/w9S+o/g+zS7YeeL0I/2mEWd+dgyA==",
+			"license": "MIT"
 		},
 		"node_modules/optionator": {
 			"version": "0.9.3",
@@ -8546,7 +8580,8 @@
 		"node_modules/package-json-from-dist": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
-			"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
+			"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+			"license": "BlueOak-1.0.0"
 		},
 		"node_modules/paneforge": {
 			"version": "0.0.6",
@@ -8686,6 +8721,7 @@
 			"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
 			"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": "*"
 			}
@@ -8728,6 +8764,12 @@
 				"@types/estree": "*"
 			}
 		},
+		"node_modules/phonemizer": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/phonemizer/-/phonemizer-1.2.1.tgz",
+			"integrity": "sha512-v0KJ4mi2T4Q7eJQ0W15Xd4G9k4kICSXE8bpDeJ8jisL4RyJhNWsweKTOi88QXFc4r4LZlz5jVL5lCHhkpdT71A==",
+			"license": "Apache-2.0"
+		},
 		"node_modules/picocolors": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
@@ -8781,7 +8823,8 @@
 		"node_modules/platform": {
 			"version": "1.3.6",
 			"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
-			"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
+			"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
+			"license": "MIT"
 		},
 		"node_modules/polyscript": {
 			"version": "0.12.8",
@@ -9064,6 +9107,7 @@
 			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
 			"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"@jest/schemas": "^29.6.3",
 				"ansi-styles": "^5.0.0",
@@ -9078,6 +9122,7 @@
 			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
 			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": ">=10"
 			},
@@ -9314,6 +9359,7 @@
 			"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
 			"integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
 			"hasInstallScript": true,
+			"license": "BSD-3-Clause",
 			"dependencies": {
 				"@protobufjs/aspromise": "^1.1.2",
 				"@protobufjs/base64": "^1.1.2",
@@ -9413,7 +9459,6 @@
 			"version": "1.2.3",
 			"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
 			"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-			"dev": true,
 			"funding": [
 				{
 					"type": "github",
@@ -9504,7 +9549,8 @@
 			"version": "18.3.1",
 			"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
 			"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
-			"dev": true
+			"dev": true,
+			"license": "MIT"
 		},
 		"node_modules/read-cache": {
 			"version": "1.0.0",
@@ -9534,7 +9580,6 @@
 			"version": "3.6.0",
 			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
 			"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-			"dev": true,
 			"dependencies": {
 				"picomatch": "^2.2.1"
 			},
@@ -9637,7 +9682,6 @@
 			"version": "1.0.4",
 			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
 			"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-			"dev": true,
 			"engines": {
 				"iojs": ">=1.0.0",
 				"node": ">=0.10.0"
@@ -9763,7 +9807,6 @@
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
 			"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-			"dev": true,
 			"funding": [
 				{
 					"type": "github",
@@ -11131,6 +11174,7 @@
 			"version": "7.4.3",
 			"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
 			"integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+			"license": "ISC",
 			"dependencies": {
 				"@isaacs/fs-minipass": "^4.0.0",
 				"chownr": "^3.0.0",
@@ -11147,6 +11191,7 @@
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
 			"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+			"license": "MIT",
 			"bin": {
 				"mkdirp": "dist/cjs/src/bin.js"
 			},
@@ -11247,6 +11292,7 @@
 			"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
 			"integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": ">=14.0.0"
 			}
@@ -11277,7 +11323,6 @@
 			"version": "5.0.1",
 			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
 			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-			"dev": true,
 			"dependencies": {
 				"is-number": "^7.0.0"
 			},
@@ -11406,10 +11451,11 @@
 			"integrity": "sha512-fLIydlJy7IG9XL4wjRwEcKhxx/ekLXiWiMvcGo01cOMF+TN+5ZqajM1mRNRz2bNNi1bzou2yofhjZEQi7kgl9A=="
 		},
 		"node_modules/type-detect": {
-			"version": "4.0.8",
-			"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-			"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+			"integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
 			"dev": true,
+			"license": "MIT",
 			"engines": {
 				"node": ">=4"
 			}
@@ -11484,7 +11530,6 @@
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
 			"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-			"dev": true,
 			"engines": {
 				"node": ">= 10.0.0"
 			}
@@ -11749,10 +11794,11 @@
 			}
 		},
 		"node_modules/vite-node": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz",
-			"integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz",
+			"integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
 				"cac": "^6.7.14",
 				"debug": "^4.3.4",
@@ -11770,6 +11816,24 @@
 				"url": "https://opencollective.com/vitest"
 			}
 		},
+		"node_modules/vite-plugin-static-copy": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz",
+			"integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==",
+			"license": "MIT",
+			"dependencies": {
+				"chokidar": "^3.5.3",
+				"fast-glob": "^3.2.11",
+				"fs-extra": "^11.1.0",
+				"picocolors": "^1.0.0"
+			},
+			"engines": {
+				"node": "^18.0.0 || >=20.0.0"
+			},
+			"peerDependencies": {
+				"vite": "^5.0.0 || ^6.0.0"
+			}
+		},
 		"node_modules/vite/node_modules/@esbuild/aix-ppc64": {
 			"version": "0.21.5",
 			"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
@@ -12166,16 +12230,17 @@
 			}
 		},
 		"node_modules/vitest": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz",
-			"integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==",
+			"version": "1.6.1",
+			"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz",
+			"integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==",
 			"dev": true,
+			"license": "MIT",
 			"dependencies": {
-				"@vitest/expect": "1.6.0",
-				"@vitest/runner": "1.6.0",
-				"@vitest/snapshot": "1.6.0",
-				"@vitest/spy": "1.6.0",
-				"@vitest/utils": "1.6.0",
+				"@vitest/expect": "1.6.1",
+				"@vitest/runner": "1.6.1",
+				"@vitest/snapshot": "1.6.1",
+				"@vitest/spy": "1.6.1",
+				"@vitest/utils": "1.6.1",
 				"acorn-walk": "^8.3.2",
 				"chai": "^4.3.10",
 				"debug": "^4.3.4",
@@ -12189,7 +12254,7 @@
 				"tinybench": "^2.5.1",
 				"tinypool": "^0.8.3",
 				"vite": "^5.0.0",
-				"vite-node": "1.6.0",
+				"vite-node": "1.6.1",
 				"why-is-node-running": "^2.2.2"
 			},
 			"bin": {
@@ -12204,8 +12269,8 @@
 			"peerDependencies": {
 				"@edge-runtime/vm": "*",
 				"@types/node": "^18.0.0 || >=20.0.0",
-				"@vitest/browser": "1.6.0",
-				"@vitest/ui": "1.6.0",
+				"@vitest/browser": "1.6.1",
+				"@vitest/ui": "1.6.1",
 				"happy-dom": "*",
 				"jsdom": "*"
 			},
@@ -12567,6 +12632,7 @@
 			"version": "5.0.0",
 			"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
 			"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+			"license": "BlueOak-1.0.0",
 			"engines": {
 				"node": ">=18"
 			}

+ 4 - 2
package.json

@@ -47,7 +47,7 @@
 		"tslib": "^2.4.1",
 		"typescript": "^5.5.4",
 		"vite": "^5.4.14",
-		"vitest": "^1.6.0"
+		"vitest": "^1.6.1"
 	},
 	"type": "module",
 	"dependencies": {
@@ -85,6 +85,7 @@
 		"idb": "^7.1.1",
 		"js-sha256": "^0.10.1",
 		"katex": "^0.16.21",
+		"kokoro-js": "^1.1.1",
 		"marked": "^9.1.0",
 		"mermaid": "^10.9.3",
 		"paneforge": "^0.0.6",
@@ -105,7 +106,8 @@
 		"svelte-sonner": "^0.3.19",
 		"tippy.js": "^6.3.7",
 		"turndown": "^7.2.0",
-		"uuid": "^9.0.1"
+		"uuid": "^9.0.1",
+		"vite-plugin-static-copy": "^2.2.0"
 	},
 	"engines": {
 		"node": ">=18.13.0 <=22.x.x",

+ 4 - 1
pyproject.toml

@@ -40,6 +40,9 @@ dependencies = [
     "argon2-cffi==23.1.0",
     "APScheduler==3.10.4",
 
+
+    "RestrictedPython==8.0",
+
     "openai",
     "anthropic",
     "google-generativeai==0.7.2",
@@ -82,7 +85,7 @@ dependencies = [
     "rapidocr-onnxruntime==1.3.24",
     "rank-bm25==0.2.2",
 
-    "faster-whisper==1.0.3",
+    "faster-whisper==1.1.1",
 
     "PyJWT[crypto]==2.10.1",
     "authlib==1.4.1",

+ 57 - 0
src/lib/apis/configs/index.ts

@@ -58,6 +58,63 @@ export const exportConfig = async (token: string) => {
 	return res;
 };
 
+export const getCodeInterpreterConfig = async (token: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/configs/code_interpreter`, {
+		method: 'GET',
+		headers: {
+			'Content-Type': 'application/json',
+			Authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = err.detail;
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const setCodeInterpreterConfig = async (token: string, config: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/configs/code_interpreter`, {
+		method: 'POST',
+		headers: {
+			'Content-Type': 'application/json',
+			Authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			...config
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = err.detail;
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
 export const getModelsConfig = async (token: string) => {
 	let error = null;
 

+ 2 - 2
src/lib/components/admin/Evaluations/Feedbacks.svelte

@@ -65,7 +65,7 @@
 	};
 
 	const shareHandler = async () => {
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 
 		// remove snapshot from feedbacks
 		const feedbacksToShare = feedbacks.map((f) => {
@@ -266,7 +266,7 @@
 					}}
 				>
 					<div class=" self-center mr-2 font-medium line-clamp-1">
-						{$i18n.t('Share to OpenWebUI Community')}
+						{$i18n.t('Share to Open WebUI Community')}
 					</div>
 
 					<div class=" self-center">

+ 3 - 1
src/lib/components/admin/Evaluations/Leaderboard.svelte

@@ -1,6 +1,8 @@
 <script lang="ts">
 	import * as ort from 'onnxruntime-web';
-	import { AutoModel, AutoTokenizer } from '@huggingface/transformers';
+	import { env, AutoModel, AutoTokenizer } from '@huggingface/transformers';
+
+	env.backends.onnx.wasm.wasmPaths = '/wasm/';
 
 	import { onMount, getContext } from 'svelte';
 	import { models } from '$lib/stores';

+ 2 - 2
src/lib/components/admin/Functions.svelte

@@ -65,7 +65,7 @@
 			return null;
 		});
 
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 
 		const url = 'https://openwebui.com';
 
@@ -453,7 +453,7 @@
 {#if $config?.features.enable_community_sharing}
 	<div class=" my-16">
 		<div class=" text-xl font-medium mb-1 line-clamp-1">
-			{$i18n.t('Made by OpenWebUI Community')}
+			{$i18n.t('Made by Open WebUI Community')}
 		</div>
 
 		<a

+ 36 - 0
src/lib/components/admin/Settings.svelte

@@ -19,6 +19,7 @@
 	import ChartBar from '../icons/ChartBar.svelte';
 	import DocumentChartBar from '../icons/DocumentChartBar.svelte';
 	import Evaluations from './Settings/Evaluations.svelte';
+	import CodeInterpreter from './Settings/CodeInterpreter.svelte';
 
 	const i18n = getContext('i18n');
 
@@ -188,6 +189,32 @@
 			<div class=" self-center">{$i18n.t('Web Search')}</div>
 		</button>
 
+		<button
+			class="px-0.5 py-1 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'code-interpreter'
+				? ''
+				: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
+			on:click={() => {
+				selectedTab = 'code-interpreter';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="size-4"
+				>
+					<path
+						fill-rule="evenodd"
+						d="M2 4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4Zm2.22 1.97a.75.75 0 0 0 0 1.06l.97.97-.97.97a.75.75 0 1 0 1.06 1.06l1.5-1.5a.75.75 0 0 0 0-1.06l-1.5-1.5a.75.75 0 0 0-1.06 0ZM8.75 8.5a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5h-2.5Z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Code Interpreter')}</div>
+		</button>
+
 		<button
 			class="px-0.5 py-1 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 			'interface'
@@ -364,6 +391,15 @@
 					await config.set(await getBackendConfig());
 				}}
 			/>
+		{:else if selectedTab === 'code-interpreter'}
+			<CodeInterpreter
+				saveHandler={async () => {
+					toast.success($i18n.t('Settings saved successfully!'));
+
+					await tick();
+					await config.set(await getBackendConfig());
+				}}
+			/>
 		{:else if selectedTab === 'interface'}
 			<Interface
 				on:save={() => {

+ 36 - 1
src/lib/components/admin/Settings/Audio.svelte

@@ -39,6 +39,7 @@
 	let STT_ENGINE = '';
 	let STT_MODEL = '';
 	let STT_WHISPER_MODEL = '';
+	let STT_DEEPGRAM_API_KEY = '';
 
 	let STT_WHISPER_MODEL_LOADING = false;
 
@@ -103,7 +104,8 @@
 				OPENAI_API_KEY: STT_OPENAI_API_KEY,
 				ENGINE: STT_ENGINE,
 				MODEL: STT_MODEL,
-				WHISPER_MODEL: STT_WHISPER_MODEL
+				WHISPER_MODEL: STT_WHISPER_MODEL,
+				DEEPGRAM_API_KEY: STT_DEEPGRAM_API_KEY
 			}
 		});
 
@@ -143,6 +145,7 @@
 			STT_ENGINE = res.stt.ENGINE;
 			STT_MODEL = res.stt.MODEL;
 			STT_WHISPER_MODEL = res.stt.WHISPER_MODEL;
+			STT_DEEPGRAM_API_KEY = res.stt.DEEPGRAM_API_KEY;
 		}
 
 		await getVoices();
@@ -173,6 +176,7 @@
 							<option value="">{$i18n.t('Whisper (Local)')}</option>
 							<option value="openai">OpenAI</option>
 							<option value="web">{$i18n.t('Web API')}</option>
+							<option value="deepgram">Deepgram</option>
 						</select>
 					</div>
 				</div>
@@ -210,6 +214,37 @@
 							</div>
 						</div>
 					</div>
+				{:else if STT_ENGINE === 'deepgram'}
+					<div>
+						<div class="mt-1 flex gap-2 mb-1">
+							<SensitiveInput placeholder={$i18n.t('API Key')} bind:value={STT_DEEPGRAM_API_KEY} />
+						</div>
+					</div>
+
+					<hr class=" dark:border-gray-850 my-2" />
+
+					<div>
+						<div class=" mb-1.5 text-sm font-medium">{$i18n.t('STT Model')}</div>
+						<div class="flex w-full">
+							<div class="flex-1">
+								<input
+									class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+									bind:value={STT_MODEL}
+									placeholder="Select a model (optional)"
+								/>
+							</div>
+						</div>
+						<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
+							{$i18n.t('Leave model field empty to use the default model.')}
+							<a
+								class=" hover:underline dark:text-gray-200 text-gray-800"
+								href="https://developers.deepgram.com/docs/models"
+								target="_blank"
+							>
+								{$i18n.t('Click here to see available models.')}
+							</a>
+						</div>
+					</div>
 				{:else if STT_ENGINE === ''}
 					<div>
 						<div class=" mb-1.5 text-sm font-medium">{$i18n.t('STT Model')}</div>

+ 145 - 0
src/lib/components/admin/Settings/CodeInterpreter.svelte

@@ -0,0 +1,145 @@
+<script lang="ts">
+	import { getRAGConfig, updateRAGConfig } from '$lib/apis/retrieval';
+	import Switch from '$lib/components/common/Switch.svelte';
+
+	import { models } from '$lib/stores';
+	import { onMount, getContext } from 'svelte';
+	import { toast } from 'svelte-sonner';
+	import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
+	import { getCodeInterpreterConfig, setCodeInterpreterConfig } from '$lib/apis/configs';
+
+	const i18n = getContext('i18n');
+
+	export let saveHandler: Function;
+
+	let config = null;
+
+	let engines = ['pyodide', 'jupyter'];
+
+	const submitHandler = async () => {
+		const res = await setCodeInterpreterConfig(localStorage.token, config);
+	};
+
+	onMount(async () => {
+		const res = await getCodeInterpreterConfig(localStorage.token);
+
+		if (res) {
+			config = res;
+		}
+	});
+</script>
+
+<form
+	class="flex flex-col h-full justify-between space-y-3 text-sm"
+	on:submit|preventDefault={async () => {
+		await submitHandler();
+		saveHandler();
+	}}
+>
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
+		{#if config}
+			<div>
+				<div class=" mb-1 text-sm font-medium">
+					{$i18n.t('Code Interpreter')}
+				</div>
+
+				<div>
+					<div class=" py-0.5 flex w-full justify-between">
+						<div class=" self-center text-xs font-medium">
+							{$i18n.t('Enable Code Interpreter')}
+						</div>
+
+						<Switch bind:state={config.ENABLE_CODE_INTERPRETER} />
+					</div>
+				</div>
+
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs font-medium">{$i18n.t('Code Interpreter Engine')}</div>
+					<div class="flex items-center relative">
+						<select
+							class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
+							bind:value={config.CODE_INTERPRETER_ENGINE}
+							placeholder={$i18n.t('Select a engine')}
+							required
+						>
+							<option disabled selected value="">{$i18n.t('Select a engine')}</option>
+							{#each engines as engine}
+								<option value={engine}>{engine}</option>
+							{/each}
+						</select>
+					</div>
+				</div>
+
+				{#if config.CODE_INTERPRETER_ENGINE === 'jupyter'}
+					<div class="mt-1 flex flex-col gap-1.5 mb-1 w-full">
+						<div class="text-xs font-medium">
+							{$i18n.t('Jupyter Kernel Gateway URL')}
+						</div>
+
+						<div class="flex w-full">
+							<div class="flex-1">
+								<input
+									class="w-full text-sm py-0.5 placeholder:text-gray-300 dark:placeholder:text-gray-700 bg-transparent outline-none"
+									type="text"
+									placeholder={$i18n.t('Enter Jupyter Kernel Gateway URL')}
+									bind:value={config.CODE_INTERPRETER_JUPYTER_URL}
+									autocomplete="off"
+								/>
+							</div>
+						</div>
+					</div>
+
+					<div class="mt-1 flex gap-2 mb-1 w-full items-center justify-between">
+						<div class="text-xs font-medium">
+							{$i18n.t('Jupyter Kernel Gateway Auth')}
+						</div>
+
+						<div>
+							<select
+								class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-left"
+								bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH}
+								placeholder={$i18n.t('Select an auth method')}
+							>
+								<option selected value="">{$i18n.t('None')}</option>
+								<option value="token">{$i18n.t('Token')}</option>
+								<option value="password">{$i18n.t('Password')}</option>
+							</select>
+						</div>
+					</div>
+
+					{#if config.CODE_INTERPRETER_JUPYTER_AUTH}
+						<div class="flex w-full gap-2">
+							<div class="flex-1">
+								{#if config.CODE_INTERPRETER_JUPYTER_AUTH === 'password'}
+									<SensitiveInput
+										type="text"
+										placeholder={$i18n.t('Enter Jupyter Kernel Gateway Password')}
+										bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD}
+										autocomplete="off"
+									/>
+								{:else}
+									<SensitiveInput
+										type="text"
+										placeholder={$i18n.t('Enter Jupyter Kernel Gateway Token')}
+										bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN}
+										autocomplete="off"
+									/>
+								{/if}
+							</div>
+						</div>
+					{/if}
+				{/if}
+			</div>
+
+			<!-- <hr class=" dark:border-gray-850 my-2" /> -->
+		{/if}
+	</div>
+	<div class="flex justify-end pt-3 text-sm font-medium">
+		<button
+			class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
+			type="submit"
+		>
+			{$i18n.t('Save')}
+		</button>
+	</div>
+</form>

+ 16 - 4
src/lib/components/admin/Settings/Connections.svelte

@@ -101,14 +101,17 @@
 	const addOpenAIConnectionHandler = async (connection) => {
 		OPENAI_API_BASE_URLS = [...OPENAI_API_BASE_URLS, connection.url];
 		OPENAI_API_KEYS = [...OPENAI_API_KEYS, connection.key];
-		OPENAI_API_CONFIGS[OPENAI_API_BASE_URLS.length] = connection.config;
+		OPENAI_API_CONFIGS[OPENAI_API_BASE_URLS.length - 1] = connection.config;
 
 		await updateOpenAIHandler();
 	};
 
 	const addOllamaConnectionHandler = async (connection) => {
 		OLLAMA_BASE_URLS = [...OLLAMA_BASE_URLS, connection.url];
-		OLLAMA_API_CONFIGS[OLLAMA_BASE_URLS.length] = connection.config;
+		OLLAMA_API_CONFIGS[OLLAMA_BASE_URLS.length - 1] = {
+			...connection.config,
+			key: connection.key
+		};
 
 		await updateOllamaHandler();
 	};
@@ -244,7 +247,11 @@
 											);
 											OPENAI_API_KEYS = OPENAI_API_KEYS.filter((key, keyIdx) => idx !== keyIdx);
 
-											delete OPENAI_API_CONFIGS[idx];
+											let newConfig = {};
+											OPENAI_API_BASE_URLS.forEach((url, newIdx) => {
+												newConfig[newIdx] = OPENAI_API_CONFIGS[newIdx < idx ? newIdx : newIdx + 1];
+											});
+											OPENAI_API_CONFIGS = newConfig;
 										}}
 									/>
 								{/each}
@@ -302,7 +309,12 @@
 										}}
 										onDelete={() => {
 											OLLAMA_BASE_URLS = OLLAMA_BASE_URLS.filter((url, urlIdx) => idx !== urlIdx);
-											delete OLLAMA_API_CONFIGS[idx];
+
+											let newConfig = {};
+											OLLAMA_BASE_URLS.forEach((url, newIdx) => {
+												newConfig[newIdx] = OLLAMA_API_CONFIGS[newIdx < idx ? newIdx : newIdx + 1];
+											});
+											OLLAMA_API_CONFIGS = newConfig;
 										}}
 									/>
 								{/each}

+ 28 - 0
src/lib/components/admin/Settings/WebSearch.svelte

@@ -34,6 +34,16 @@
 	let youtubeProxyUrl = '';
 
 	const submitHandler = async () => {
+		// Convert domain filter string to array before sending
+		if (webConfig.search.domain_filter_list) {
+			webConfig.search.domain_filter_list = webConfig.search.domain_filter_list
+				.split(',')
+				.map((domain) => domain.trim())
+				.filter((domain) => domain.length > 0);
+		} else {
+			webConfig.search.domain_filter_list = [];
+		}
+
 		const res = await updateRAGConfig(localStorage.token, {
 			web: webConfig,
 			youtube: {
@@ -49,6 +59,10 @@
 
 		if (res) {
 			webConfig = res.web;
+			// Convert array back to comma-separated string for display
+			if (webConfig?.search?.domain_filter_list) {
+				webConfig.search.domain_filter_list = webConfig.search.domain_filter_list.join(', ');
+			}
 
 			youtubeLanguage = res.youtube.language.join(',');
 			youtubeTranslation = res.youtube.translation;
@@ -334,6 +348,20 @@
 							/>
 						</div>
 					</div>
+
+					<div class="mt-2">
+						<div class=" self-center text-xs font-medium mb-1">
+							{$i18n.t('Domain Filter List')}
+						</div>
+
+						<input
+							class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
+							placeholder={$i18n.t(
+								'Enter domains separated by commas (e.g., example.com,site.org)'
+							)}
+							bind:value={webConfig.search.domain_filter_list}
+						/>
+					</div>
 				{/if}
 			</div>
 

+ 2 - 1
src/lib/components/chat/Chat.svelte

@@ -1556,7 +1556,8 @@
 							? imageGenerationEnabled
 							: false,
 					code_interpreter:
-						$user.role === 'admin' || $user?.permissions?.features?.code_interpreter
+						$config?.features?.enable_code_interpreter &&
+						($user.role === 'admin' || $user?.permissions?.features?.code_interpreter)
 							? codeInterpreterEnabled
 							: false,
 					web_search:

+ 19 - 7
src/lib/components/chat/MessageInput.svelte

@@ -16,7 +16,8 @@
 		showCallOverlay,
 		tools,
 		user as _user,
-		showControls
+		showControls,
+		TTSWorker
 	} from '$lib/stores';
 
 	import { blobToFile, compressImage, createMessagesList, findWordIndices } from '$lib/utils';
@@ -43,6 +44,7 @@
 	import PhotoSolid from '../icons/PhotoSolid.svelte';
 	import Photo from '../icons/Photo.svelte';
 	import CommandLine from '../icons/CommandLine.svelte';
+	import { KokoroWorker } from '$lib/workers/KokoroWorker';
 
 	const i18n = getContext('i18n');
 
@@ -638,7 +640,7 @@
 																xmlns="http://www.w3.org/2000/svg"
 																viewBox="0 0 20 20"
 																fill="currentColor"
-																class="w-4 h-4"
+																class="size-4"
 															>
 																<path
 																	d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
@@ -695,7 +697,7 @@
 													)}
 												placeholder={placeholder ? placeholder : $i18n.t('Send a Message')}
 												largeTextAsFile={$settings?.largeTextAsFile ?? false}
-												autocomplete={true}
+												autocomplete={$config?.features.enable_autocomplete_generation}
 												generateAutoCompletion={async (text) => {
 													if (selectedModelIds.length === 0 || !selectedModelIds.at(0)) {
 														toast.error($i18n.t('Please select a model first.'));
@@ -1169,7 +1171,7 @@
 													</Tooltip>
 												{/if}
 
-												{#if $_user.role === 'admin' || $_user?.permissions?.features?.code_interpreter}
+												{#if $config?.features?.enable_code_interpreter && ($_user.role === 'admin' || $_user?.permissions?.features?.code_interpreter)}
 													<Tooltip content={$i18n.t('Execute code for analysis')} placement="top">
 														<button
 															on:click|preventDefault={() =>
@@ -1242,7 +1244,7 @@
 										{/if}
 
 										{#if !history.currentId || history.messages[history.currentId]?.done == true}
-											{#if prompt === ''}
+											{#if prompt === '' && files.length === 0}
 												<div class=" flex items-center">
 													<Tooltip content={$i18n.t('Call')}>
 														<button
@@ -1281,6 +1283,16 @@
 
 																	stream = null;
 
+																	if (!$TTSWorker) {
+																		await TTSWorker.set(
+																			new KokoroWorker({
+																				dtype: $settings.audio?.tts?.engineConfig?.dtype ?? 'fp32'
+																			})
+																		);
+
+																		await $TTSWorker.init();
+																	}
+
 																	showCallOverlay.set(true);
 																	showControls.set(true);
 																} catch (err) {
@@ -1301,13 +1313,13 @@
 													<Tooltip content={$i18n.t('Send message')}>
 														<button
 															id="send-message-button"
-															class="{prompt !== ''
+															class="{!(prompt === '' && files.length === 0)
 																? webSearchEnabled || ($settings?.webSearch ?? false) === 'always'
 																	? 'bg-blue-500 text-white hover:bg-blue-400 '
 																	: 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
 																: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center"
 															type="submit"
-															disabled={prompt === ''}
+															disabled={prompt === '' && files.length === 0}
 														>
 															<svg
 																xmlns="http://www.w3.org/2000/svg"

+ 17 - 2
src/lib/components/chat/MessageInput/CallOverlay.svelte

@@ -1,5 +1,5 @@
 <script lang="ts">
-	import { config, models, settings, showCallOverlay } from '$lib/stores';
+	import { config, models, settings, showCallOverlay, TTSWorker } from '$lib/stores';
 	import { onMount, tick, getContext, onDestroy, createEventDispatcher } from 'svelte';
 
 	const dispatch = createEventDispatcher();
@@ -12,6 +12,7 @@
 
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
 	import VideoInputMenu from './CallOverlay/VideoInputMenu.svelte';
+	import { KokoroWorker } from '$lib/workers/KokoroWorker';
 
 	const i18n = getContext('i18n');
 
@@ -459,7 +460,21 @@
 					}
 				}
 
-				if ($config.audio.tts.engine !== '') {
+				if ($settings.audio?.tts?.engine === 'browser-kokoro') {
+					const blob = await $TTSWorker
+						.generate({
+							text: content,
+							voice: $settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice
+						})
+						.catch((error) => {
+							console.error(error);
+							toast.error(`${error}`);
+						});
+
+					if (blob) {
+						audioCache.set(content, new Audio(blob));
+					}
+				} else if ($config.audio.tts.engine !== '') {
 					const res = await synthesizeOpenAISpeech(
 						localStorage.token,
 						$settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice

+ 19 - 11
src/lib/components/chat/Messages/Citations.svelte

@@ -97,7 +97,7 @@
 {#if citations.length > 0}
 	<div class=" py-0.5 -mx-0.5 w-full flex gap-1 items-center flex-wrap">
 		{#if citations.length <= 3}
-			<div class="flex text-xs font-medium">
+			<div class="flex text-xs font-medium flex-wrap">
 				{#each citations as citation, idx}
 					<button
 						id={`source-${citation.source.name}`}
@@ -113,7 +113,7 @@
 							</div>
 						{/if}
 						<div
-							class="flex-1 mx-1 line-clamp-1 text-black/60 hover:text-black dark:text-white/60 dark:hover:text-white transition"
+							class="flex-1 mx-1 truncate text-black/60 hover:text-black dark:text-white/60 dark:hover:text-white transition"
 						>
 							{citation.source.name}
 						</div>
@@ -121,13 +121,21 @@
 				{/each}
 			</div>
 		{:else}
-			<Collapsible bind:open={isCollapsibleOpen} className="w-full">
+			<Collapsible
+				bind:open={isCollapsibleOpen}
+				className="w-full max-w-full "
+				buttonClassName="w-fit max-w-full"
+			>
 				<div
-					class="flex items-center gap-2 text-gray-500 hover:text-gray-600 dark:hover:text-gray-400 transition cursor-pointer"
+					class="flex w-full overflow-auto items-center gap-2 text-gray-500 hover:text-gray-600 dark:hover:text-gray-400 transition cursor-pointer"
 				>
-					<div class="flex-grow flex items-center gap-1 overflow-hidden">
-						<span class="whitespace-nowrap hidden sm:inline">{$i18n.t('References from')}</span>
-						<div class="flex items-center">
+					<div
+						class="flex-1 flex items-center gap-1 overflow-auto scrollbar-none w-full max-w-full"
+					>
+						<span class="whitespace-nowrap hidden sm:inline flex-shrink-0"
+							>{$i18n.t('References from')}</span
+						>
+						<div class="flex items-center overflow-auto scrollbar-none w-full max-w-full flex-1">
 							<div class="flex text-xs font-medium items-center">
 								{#each citations.slice(0, 2) as citation, idx}
 									<button
@@ -145,14 +153,14 @@
 												{idx + 1}
 											</div>
 										{/if}
-										<div class="flex-1 mx-1 line-clamp-1 truncate">
+										<div class="flex-1 mx-1 truncate">
 											{citation.source.name}
 										</div>
 									</button>
 								{/each}
 							</div>
 						</div>
-						<div class="flex items-center gap-1 whitespace-nowrap">
+						<div class="flex items-center gap-1 whitespace-nowrap flex-shrink-0">
 							<span class="hidden sm:inline">{$i18n.t('and')}</span>
 							{citations.length - 2}
 							<span>{$i18n.t('more')}</span>
@@ -167,7 +175,7 @@
 					</div>
 				</div>
 				<div slot="content">
-					<div class="flex text-xs font-medium">
+					<div class="flex text-xs font-medium flex-wrap">
 						{#each citations as citation, idx}
 							<button
 								class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96"
@@ -181,7 +189,7 @@
 										{idx + 1}
 									</div>
 								{/if}
-								<div class="flex-1 mx-1 line-clamp-1 truncate">
+								<div class="flex-1 mx-1 truncate">
 									{citation.source.name}
 								</div>
 							</button>

+ 17 - 2
src/lib/components/chat/Messages/CodeBlock.svelte

@@ -5,7 +5,14 @@
 
 	import { v4 as uuidv4 } from 'uuid';
 
-	import { getContext, getAllContexts, onMount, tick, createEventDispatcher } from 'svelte';
+	import {
+		getContext,
+		getAllContexts,
+		onMount,
+		tick,
+		createEventDispatcher,
+		onDestroy
+	} from 'svelte';
 	import { copyToClipboard } from '$lib/utils';
 
 	import 'highlight.js/styles/github-dark.min.css';
@@ -31,6 +38,8 @@
 	export let editorClassName = '';
 	export let stickyButtonsClassName = 'top-8';
 
+	let pyodideWorker = null;
+
 	let _code = '';
 	$: if (code) {
 		updateCode();
@@ -138,7 +147,7 @@
 
 		console.log(packages);
 
-		const pyodideWorker = new PyodideWorker();
+		pyodideWorker = new PyodideWorker();
 
 		pyodideWorker.postMessage({
 			id: id,
@@ -280,6 +289,12 @@
 			});
 		}
 	});
+
+	onDestroy(() => {
+		if (pyodideWorker) {
+			pyodideWorker.terminate();
+		}
+	});
 </script>
 
 <div>

+ 98 - 61
src/lib/components/chat/Messages/ResponseMessage.svelte

@@ -4,12 +4,18 @@
 
 	import { createEventDispatcher } from 'svelte';
 	import { onMount, tick, getContext } from 'svelte';
+	import type { Writable } from 'svelte/store';
+	import type { i18n as i18nType } from 'i18next';
 
 	const i18n = getContext<Writable<i18nType>>('i18n');
 
 	const dispatch = createEventDispatcher();
 
-	import { config, models, settings, user } from '$lib/stores';
+	import { createNewFeedback, getFeedbackById, updateFeedbackById } from '$lib/apis/evaluations';
+	import { getChatById } from '$lib/apis/chats';
+	import { generateTags } from '$lib/apis';
+
+	import { config, models, settings, TTSWorker, user } from '$lib/stores';
 	import { synthesizeOpenAISpeech } from '$lib/apis/audio';
 	import { imageGenerations } from '$lib/apis/images';
 	import {
@@ -34,13 +40,8 @@
 	import Error from './Error.svelte';
 	import Citations from './Citations.svelte';
 	import CodeExecutions from './CodeExecutions.svelte';
-
-	import type { Writable } from 'svelte/store';
-	import type { i18n as i18nType } from 'i18next';
 	import ContentRenderer from './ContentRenderer.svelte';
-	import { createNewFeedback, getFeedbackById, updateFeedbackById } from '$lib/apis/evaluations';
-	import { getChatById } from '$lib/apis/chats';
-	import { generateTags } from '$lib/apis';
+	import { KokoroWorker } from '$lib/workers/KokoroWorker';
 
 	interface MessageType {
 		id: string;
@@ -193,7 +194,42 @@
 
 		speaking = true;
 
-		if ($config.audio.tts.engine !== '') {
+		if ($config.audio.tts.engine === '') {
+			let voices = [];
+			const getVoicesLoop = setInterval(() => {
+				voices = speechSynthesis.getVoices();
+				if (voices.length > 0) {
+					clearInterval(getVoicesLoop);
+
+					const voice =
+						voices
+							?.filter(
+								(v) => v.voiceURI === ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
+							)
+							?.at(0) ?? undefined;
+
+					console.log(voice);
+
+					const speak = new SpeechSynthesisUtterance(message.content);
+					speak.rate = $settings.audio?.tts?.playbackRate ?? 1;
+
+					console.log(speak);
+
+					speak.onend = () => {
+						speaking = false;
+						if ($settings.conversationMode) {
+							document.getElementById('voice-input-button')?.click();
+						}
+					};
+
+					if (voice) {
+						speak.voice = voice;
+					}
+
+					speechSynthesis.speak(speak);
+				}
+			}, 100);
+		} else {
 			loadingSpeech = true;
 
 			const messageContentParts: string[] = getMessageContentParts(
@@ -222,67 +258,68 @@
 
 			let lastPlayedAudioPromise = Promise.resolve(); // Initialize a promise that resolves immediately
 
-			for (const [idx, sentence] of messageContentParts.entries()) {
-				const res = await synthesizeOpenAISpeech(
-					localStorage.token,
-					$settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice
-						? ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
-						: $config?.audio?.tts?.voice,
-					sentence
-				).catch((error) => {
-					console.error(error);
-					toast.error(`${error}`);
+			if ($settings.audio?.tts?.engine === 'browser-kokoro') {
+				if (!$TTSWorker) {
+					await TTSWorker.set(
+						new KokoroWorker({
+							dtype: $settings.audio?.tts?.engineConfig?.dtype ?? 'fp32'
+						})
+					);
 
-					speaking = false;
-					loadingSpeech = false;
-				});
-
-				if (res) {
-					const blob = await res.blob();
-					const blobUrl = URL.createObjectURL(blob);
-					const audio = new Audio(blobUrl);
-					audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
-
-					audioParts[idx] = audio;
-					loadingSpeech = false;
-					lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
+					await $TTSWorker.init();
 				}
-			}
-		} else {
-			let voices = [];
-			const getVoicesLoop = setInterval(() => {
-				voices = speechSynthesis.getVoices();
-				if (voices.length > 0) {
-					clearInterval(getVoicesLoop);
-
-					const voice =
-						voices
-							?.filter(
-								(v) => v.voiceURI === ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
-							)
-							?.at(0) ?? undefined;
-
-					console.log(voice);
-
-					const speak = new SpeechSynthesisUtterance(message.content);
-					speak.rate = $settings.audio?.tts?.playbackRate ?? 1;
 
-					console.log(speak);
+				for (const [idx, sentence] of messageContentParts.entries()) {
+					const blob = await $TTSWorker
+						.generate({
+							text: sentence,
+							voice: $settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice
+						})
+						.catch((error) => {
+							console.error(error);
+							toast.error(`${error}`);
+
+							speaking = false;
+							loadingSpeech = false;
+						});
+
+					if (blob) {
+						const audio = new Audio(blob);
+						audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
+
+						audioParts[idx] = audio;
+						loadingSpeech = false;
+						lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
+					}
+				}
+			} else {
+				for (const [idx, sentence] of messageContentParts.entries()) {
+					const res = await synthesizeOpenAISpeech(
+						localStorage.token,
+						$settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice
+							? ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
+							: $config?.audio?.tts?.voice,
+						sentence
+					).catch((error) => {
+						console.error(error);
+						toast.error(`${error}`);
 
-					speak.onend = () => {
 						speaking = false;
-						if ($settings.conversationMode) {
-							document.getElementById('voice-input-button')?.click();
-						}
-					};
+						loadingSpeech = false;
+					});
 
-					if (voice) {
-						speak.voice = voice;
-					}
+					if (res) {
+						const blob = await res.blob();
+						const blobUrl = URL.createObjectURL(blob);
+						const audio = new Audio(blobUrl);
+						audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
 
-					speechSynthesis.speak(speak);
+						audioParts[idx] = audio;
+						loadingSpeech = false;
+						lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
+					}
 				}
-			}, 100);
+			}
 		}
 	};
 

+ 162 - 16
src/lib/components/chat/Settings/Audio.svelte

@@ -1,11 +1,14 @@
 <script lang="ts">
 	import { toast } from 'svelte-sonner';
 	import { createEventDispatcher, onMount, getContext } from 'svelte';
+	import { KokoroTTS } from 'kokoro-js';
 
 	import { user, settings, config } from '$lib/stores';
 	import { getVoices as _getVoices } from '$lib/apis/audio';
 
 	import Switch from '$lib/components/common/Switch.svelte';
+	import { round } from '@huggingface/transformers';
+	import Spinner from '$lib/components/common/Spinner.svelte';
 	const dispatch = createEventDispatcher();
 
 	const i18n = getContext('i18n');
@@ -20,6 +23,13 @@
 
 	let STTEngine = '';
 
+	let TTSEngine = '';
+	let TTSEngineConfig = {};
+
+	let TTSModel = null;
+	let TTSModelProgress = null;
+	let TTSModelLoading = false;
+
 	let voices = [];
 	let voice = '';
 
@@ -28,23 +38,37 @@
 	const speedOptions = [2, 1.75, 1.5, 1.25, 1, 0.75, 0.5];
 
 	const getVoices = async () => {
-		if ($config.audio.tts.engine === '') {
-			const getVoicesLoop = setInterval(async () => {
-				voices = await speechSynthesis.getVoices();
+		if (TTSEngine === 'browser-kokoro') {
+			if (!TTSModel) {
+				await loadKokoro();
+			}
 
-				// do your loop
-				if (voices.length > 0) {
-					clearInterval(getVoicesLoop);
-				}
-			}, 100);
-		} else {
-			const res = await _getVoices(localStorage.token).catch((e) => {
-				toast.error(`${e}`);
+			voices = Object.entries(TTSModel.voices).map(([key, value]) => {
+				return {
+					id: key,
+					name: value.name,
+					localService: false
+				};
 			});
-
-			if (res) {
-				console.log(res);
-				voices = res.voices;
+		} else {
+			if ($config.audio.tts.engine === '') {
+				const getVoicesLoop = setInterval(async () => {
+					voices = await speechSynthesis.getVoices();
+
+					// do your loop
+					if (voices.length > 0) {
+						clearInterval(getVoicesLoop);
+					}
+				}, 100);
+			} else {
+				const res = await _getVoices(localStorage.token).catch((e) => {
+					toast.error(`${e}`);
+				});
+
+				if (res) {
+					console.log(res);
+					voices = res.voices;
+				}
 			}
 		}
 	};
@@ -67,6 +91,9 @@
 
 		STTEngine = $settings?.audio?.stt?.engine ?? '';
 
+		TTSEngine = $settings?.audio?.tts?.engine ?? '';
+		TTSEngineConfig = $settings?.audio?.tts?.engineConfig ?? {};
+
 		if ($settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice) {
 			voice = $settings?.audio?.tts?.voice ?? $config.audio.tts.voice ?? '';
 		} else {
@@ -77,6 +104,51 @@
 
 		await getVoices();
 	});
+
+	$: if (TTSEngine && TTSEngineConfig) {
+		onTTSEngineChange();
+	}
+
+	const onTTSEngineChange = async () => {
+		if (TTSEngine === 'browser-kokoro') {
+			await loadKokoro();
+		}
+	};
+
+	const loadKokoro = async () => {
+		if (TTSEngine === 'browser-kokoro') {
+			voices = [];
+
+			if (TTSEngineConfig?.dtype) {
+				TTSModel = null;
+				TTSModelProgress = null;
+				TTSModelLoading = true;
+
+				const model_id = 'onnx-community/Kokoro-82M-v1.0-ONNX';
+
+				TTSModel = await KokoroTTS.from_pretrained(model_id, {
+					dtype: TTSEngineConfig.dtype, // Options: "fp32", "fp16", "q8", "q4", "q4f16"
+					device: !!navigator?.gpu ? 'webgpu' : 'wasm', // Detect WebGPU
+					progress_callback: (e) => {
+						TTSModelProgress = e;
+						console.log(e);
+					}
+				});
+
+				await getVoices();
+
+				// const rawAudio = await tts.generate(inputText, {
+				// 	// Use `tts.list_voices()` to list all available voices
+				// 	voice: voice
+				// });
+
+				// const blobUrl = URL.createObjectURL(await rawAudio.toBlob());
+				// const audio = new Audio(blobUrl);
+
+				// audio.play();
+			}
+		}
+	};
 </script>
 
 <form
@@ -88,6 +160,8 @@
 					engine: STTEngine !== '' ? STTEngine : undefined
 				},
 				tts: {
+					engine: TTSEngine !== '' ? TTSEngine : undefined,
+					engineConfig: TTSEngineConfig,
 					playbackRate: playbackRate,
 					voice: voice !== '' ? voice : undefined,
 					defaultVoice: $config?.audio?.tts?.voice ?? '',
@@ -142,6 +216,39 @@
 		<div>
 			<div class=" mb-1 text-sm font-medium">{$i18n.t('TTS Settings')}</div>
 
+			<div class=" py-0.5 flex w-full justify-between">
+				<div class=" self-center text-xs font-medium">{$i18n.t('Text-to-Speech Engine')}</div>
+				<div class="flex items-center relative">
+					<select
+						class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
+						bind:value={TTSEngine}
+						placeholder="Select an engine"
+					>
+						<option value="">{$i18n.t('Default')}</option>
+						<option value="browser-kokoro">{$i18n.t('Kokoro.js (Browser)')}</option>
+					</select>
+				</div>
+			</div>
+
+			{#if TTSEngine === 'browser-kokoro'}
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs font-medium">{$i18n.t('Kokoro.js Dtype')}</div>
+					<div class="flex items-center relative">
+						<select
+							class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
+							bind:value={TTSEngineConfig.dtype}
+							placeholder="Select dtype"
+						>
+							<option value="" disabled selected>Select dtype</option>
+							<option value="fp32">fp32</option>
+							<option value="fp16">fp16</option>
+							<option value="q8">q8</option>
+							<option value="q4">q4</option>
+						</select>
+					</div>
+				</div>
+			{/if}
+
 			<div class=" py-0.5 flex w-full justify-between">
 				<div class=" self-center text-xs font-medium">{$i18n.t('Auto-playback response')}</div>
 
@@ -178,7 +285,46 @@
 
 		<hr class=" dark:border-gray-850" />
 
-		{#if $config.audio.tts.engine === ''}
+		{#if TTSEngine === 'browser-kokoro'}
+			{#if TTSModel}
+				<div>
+					<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Voice')}</div>
+					<div class="flex w-full">
+						<div class="flex-1">
+							<input
+								list="voice-list"
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								bind:value={voice}
+								placeholder="Select a voice"
+							/>
+
+							<datalist id="voice-list">
+								{#each voices as voice}
+									<option value={voice.id}>{voice.name}</option>
+								{/each}
+							</datalist>
+						</div>
+					</div>
+				</div>
+			{:else}
+				<div>
+					<div class=" mb-2.5 text-sm font-medium flex gap-2 items-center">
+						<Spinner className="size-4" />
+
+						<div class=" text-sm font-medium shimmer">
+							{$i18n.t('Loading Kokoro.js...')}
+							{TTSModelProgress && TTSModelProgress.status === 'progress'
+								? `(${Math.round(TTSModelProgress.progress * 10) / 10}%)`
+								: ''}
+						</div>
+					</div>
+
+					<div class="text-xs text-gray-500">
+						{$i18n.t('Please do not close the settings page while loading the model.')}
+					</div>
+				</div>
+			{/if}
+		{:else if $config.audio.tts.engine === ''}
 			<div>
 				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Voice')}</div>
 				<div class="flex w-full">

+ 5 - 0
src/lib/components/chat/Settings/General.svelte

@@ -49,6 +49,7 @@
 		function_calling: null,
 		seed: null,
 		temperature: null,
+		reasoning_effort: null,
 		frequency_penalty: null,
 		repeat_last_n: null,
 		mirostat: null,
@@ -333,9 +334,13 @@
 					system: system !== '' ? system : undefined,
 					params: {
 						stream_response: params.stream_response !== null ? params.stream_response : undefined,
+						function_calling:
+							params.function_calling !== null ? params.function_calling : undefined,
 						seed: (params.seed !== null ? params.seed : undefined) ?? undefined,
 						stop: params.stop ? params.stop.split(',').filter((e) => e) : undefined,
 						temperature: params.temperature !== null ? params.temperature : undefined,
+						reasoning_effort:
+							params.reasoning_effort !== null ? params.reasoning_effort : undefined,
 						frequency_penalty:
 							params.frequency_penalty !== null ? params.frequency_penalty : undefined,
 						repeat_last_n: params.repeat_last_n !== null ? params.repeat_last_n : undefined,

+ 2 - 2
src/lib/components/chat/ShareChatModal.svelte

@@ -30,7 +30,7 @@
 		const _chat = chat.chat;
 		console.log('share', _chat);
 
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 		const url = 'https://openwebui.com';
 		// const url = 'http://localhost:5173';
 
@@ -143,7 +143,7 @@
 										show = false;
 									}}
 								>
-									{$i18n.t('Share to OpenWebUI Community')}
+									{$i18n.t('Share to Open WebUI Community')}
 								</button>
 							{/if}
 

+ 9 - 3
src/lib/components/common/Collapsible.svelte

@@ -74,9 +74,15 @@
 				<div class="">
 					{#if attributes?.type === 'reasoning'}
 						{#if attributes?.done === 'true' && attributes?.duration}
-							{$i18n.t('Thought for {{DURATION}}', {
-								DURATION: dayjs.duration(attributes.duration, 'seconds').humanize()
-							})}
+							{#if attributes.duration < 60}
+								{$i18n.t('Thought for {{DURATION}} seconds', {
+									DURATION: attributes.duration
+								})}
+							{:else}
+								{$i18n.t('Thought for {{DURATION}}', {
+									DURATION: dayjs.duration(attributes.duration, 'seconds').humanize()
+								})}
+							{/if}
 						{:else}
 							{$i18n.t('Thinking...')}
 						{/if}

+ 1 - 0
src/lib/components/common/SensitiveInput.svelte

@@ -23,6 +23,7 @@
 	/>
 	<button
 		class={showButtonClassName}
+		type="button"
 		on:click={(e) => {
 			e.preventDefault();
 			show = !show;

+ 2 - 2
src/lib/components/workspace/Models.svelte

@@ -82,7 +82,7 @@
 	};
 
 	const shareModelHandler = async (model) => {
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 
 		const url = 'https://openwebui.com';
 
@@ -479,7 +479,7 @@
 	{#if $config?.features.enable_community_sharing}
 		<div class=" my-16">
 			<div class=" text-xl font-medium mb-1 line-clamp-1">
-				{$i18n.t('Made by OpenWebUI Community')}
+				{$i18n.t('Made by Open WebUI Community')}
 			</div>
 
 			<a

+ 2 - 2
src/lib/components/workspace/Prompts.svelte

@@ -40,7 +40,7 @@
 	$: filteredItems = prompts.filter((p) => query === '' || p.command.includes(query));
 
 	const shareHandler = async (prompt) => {
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 
 		const url = 'https://openwebui.com';
 
@@ -319,7 +319,7 @@
 	{#if $config?.features.enable_community_sharing}
 		<div class=" my-16">
 			<div class=" text-xl font-medium mb-1 line-clamp-1">
-				{$i18n.t('Made by OpenWebUI Community')}
+				{$i18n.t('Made by Open WebUI Community')}
 			</div>
 
 			<a

+ 2 - 2
src/lib/components/workspace/Tools.svelte

@@ -65,7 +65,7 @@
 			return null;
 		});
 
-		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
+		toast.success($i18n.t('Redirecting you to Open WebUI Community'));
 
 		const url = 'https://openwebui.com';
 
@@ -438,7 +438,7 @@
 	{#if $config?.features.enable_community_sharing}
 		<div class=" my-16">
 			<div class=" text-xl font-medium mb-1 line-clamp-1">
-				{$i18n.t('Made by OpenWebUI Community')}
+				{$i18n.t('Made by Open WebUI Community')}
 			</div>
 
 			<a

+ 10 - 3
src/lib/i18n/locales/ar-BH/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "أضغط هنا الانتقال",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "مستندات",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "لا يجري أي اتصالات خارجية، وتظل بياناتك آمنة على الخادم المستضاف محليًا.",
+	"Domain Filter List": "",
 	"Don't have an account?": "ليس لديك حساب؟",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "أدخل الChunk Overlap",
 	"Enter Chunk Size": "أدخل Chunk الحجم",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "أدخل عنوان URL ل Github Raw",
 	"Enter Google PSE API Key": "أدخل مفتاح واجهة برمجة تطبيقات PSE من Google",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "اللغة",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "فاتح",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "من جهة اليسار إلى اليمين",
-	"Made by OpenWebUI Community": "OpenWebUI تم إنشاؤه بواسطة مجتمع ",
+	"Made by Open WebUI Community": "OpenWebUI تم إنشاؤه بواسطة مجتمع ",
 	"Make sure to enclose them with": "تأكد من إرفاقها",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "أقراء لي",
 	"Reasoning Effort": "",
 	"Record voice": "سجل صوت",
-	"Redirecting you to OpenWebUI Community": "OpenWebUI إعادة توجيهك إلى مجتمع ",
+	"Redirecting you to Open WebUI Community": "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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "تم حفظ الاعدادات بنجاح",
 	"Share": "كشاركة",
 	"Share Chat": "مشاركة الدردشة",
-	"Share to OpenWebUI Community": "OpenWebUI شارك في مجتمع",
+	"Share to Open WebUI Community": "OpenWebUI شارك في مجتمع",
 	"Show": "عرض",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "شرح شامل",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/bg-BG/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Натиснете тук за",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "Документи",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "няма външни връзки, и вашите данни остават сигурни на локално назначен сървър.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Нямате акаунт?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Въведете Chunk Overlap",
 	"Enter Chunk Size": "Въведете Chunk Size",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Въведете URL адреса на Github Raw",
 	"Enter Google PSE API Key": "Въведете Google PSE API ключ",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Език",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Светъл",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Направено от OpenWebUI общността",
+	"Made by Open WebUI Community": "Направено от OpenWebUI общността",
 	"Make sure to enclose them with": "Уверете се, че са заключени с",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Прочети на Голос",
 	"Reasoning Effort": "",
 	"Record voice": "Записване на глас",
-	"Redirecting you to OpenWebUI Community": "Пренасочване към OpenWebUI общността",
+	"Redirecting you to Open WebUI Community": "Пренасочване към 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Настройките са запазени успешно!",
 	"Share": "Подели",
 	"Share Chat": "Подели Чат",
-	"Share to OpenWebUI Community": "Споделите с OpenWebUI Общността",
+	"Share to Open WebUI Community": "Споделите с OpenWebUI Общността",
 	"Show": "Покажи",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Това е подробно описание.",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/bn-BD/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "এখানে ক্লিক করুন",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "ডকুমেন্টসমূহ",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "কোন এক্সটার্নাল কানেকশন তৈরি করে না, এবং আপনার ডেটা আর লোকালি হোস্টেড সার্ভারেই নিরাপদে থাকে।",
+	"Domain Filter List": "",
 	"Don't have an account?": "একাউন্ট নেই?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "চাঙ্ক ওভারল্যাপ লিখুন",
 	"Enter Chunk Size": "চাংক সাইজ লিখুন",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "গিটহাব কাঁচা URL লিখুন",
 	"Enter Google PSE API Key": "গুগল পিএসই এপিআই কী লিখুন",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "ভাষা",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "লাইট",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "OpenWebUI কমিউনিটিকর্তৃক নির্মিত",
+	"Made by Open WebUI Community": "OpenWebUI কমিউনিটিকর্তৃক নির্মিত",
 	"Make sure to enclose them with": "এটা দিয়ে বন্ধনী দিতে ভুলবেন না",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "পড়াশোনা করুন",
 	"Reasoning Effort": "",
 	"Record voice": "ভয়েস রেকর্ড করুন",
-	"Redirecting you to OpenWebUI Community": "আপনাকে OpenWebUI কমিউনিটিতে পাঠানো হচ্ছে",
+	"Redirecting you to Open WebUI Community": "আপনাকে 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "সেটিংগুলো সফলভাবে সংরক্ষিত হয়েছে",
 	"Share": "শেয়ার করুন",
 	"Share Chat": "চ্যাট শেয়ার করুন",
-	"Share to OpenWebUI Community": "OpenWebUI কমিউনিটিতে শেয়ার করুন",
+	"Share to Open WebUI Community": "OpenWebUI কমিউনিটিতে শেয়ার করুন",
 	"Show": "দেখান",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "পুঙ্খানুপুঙ্খ ব্যাখ্যা",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ca-ES/translation.json

@@ -163,6 +163,7 @@
 	"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",
 	"Click here to learn more about faster-whisper and see the available models.": "Clica aquí per obtenir més informació sobre faster-whisper i veure els models disponibles.",
+	"Click here to see available models.": "",
 	"Click here to select": "Clica aquí per seleccionar",
 	"Click here to select a csv file.": "Clica aquí per seleccionar un fitxer csv.",
 	"Click here to select a py file.": "Clica aquí per seleccionar un fitxer py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentació",
 	"Documents": "Documents",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.",
+	"Domain Filter List": "",
 	"Don't have an account?": "No tens un compte?",
 	"don't install random functions from sources you don't trust.": "no instal·lis funcions aleatòries de fonts en què no confiïs.",
 	"don't install random tools from sources you don't trust.": "no instal·lis eines aleatòries de fonts en què no confiïs.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Introdueix la mida de solapament de blocs",
 	"Enter Chunk Size": "Introdueix la mida del bloc",
 	"Enter description": "Introdueix la descripció",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Introdueix l'URL en brut de Github",
 	"Enter Google PSE API Key": "Introdueix la clau API de Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Coneixement eliminat correctament.",
 	"Knowledge reset successfully.": "Coneixement restablert correctament.",
 	"Knowledge updated successfully": "Coneixement actualitzat correctament.",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Etiqueta",
 	"Landing Page Mode": "Mode de la pàgina d'entrada",
 	"Language": "Idioma",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{URL}}/models\"",
 	"Leave empty to include all models or select specific models": "Deixa-ho en blanc per incloure tots els models o selecciona models específics",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Deixa-ho en blanc per utilitzar la indicació predeterminada o introdueix una indicació personalitzada",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Clar",
 	"Listening...": "Escoltant...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "Models locals",
 	"Lost": "Perdut",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Creat per la Comunitat OpenWebUI",
+	"Made by Open WebUI Community": "Creat per la Comunitat OpenWebUI",
 	"Make sure to enclose them with": "Assegura't d'envoltar-los amb",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Assegura't d'exportar un fitxer workflow.json com a format API des de ComfyUI.",
 	"Manage": "Gestionar",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Llegir en veu alta",
 	"Reasoning Effort": "Esforç de raonament",
 	"Record voice": "Enregistrar la veu",
-	"Redirecting you to OpenWebUI Community": "Redirigint-te a la comunitat OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Redirigint-te a la comunitat 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. (Default: 40)": "Redueix la probabilitat de generar ximpleries. Un valor més alt (p. ex. 100) donarà respostes més diverses, mentre que un valor més baix (p. ex. 10) serà més conservador. (Per defecte: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Fes referència a tu mateix com a \"Usuari\" (p. ex., \"L'usuari està aprenent espanyol\")",
 	"References from": "Referències de",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Les preferències s'han desat correctament",
 	"Share": "Compartir",
 	"Share Chat": "Compartir el xat",
-	"Share to OpenWebUI Community": "Compartir amb la comunitat OpenWebUI",
+	"Share to Open WebUI Community": "Compartir amb la comunitat OpenWebUI",
 	"Show": "Mostrar",
 	"Show \"What's New\" modal on login": "Veure 'Què hi ha de nou' a l'entrada",
 	"Show Admin Details in Account Pending Overlay": "Mostrar els detalls de l'administrador a la superposició del compte pendent",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Això restablirà la base de coneixement i sincronitzarà tots els fitxers. Vols continuar?",
 	"Thorough explanation": "Explicació en detall",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "La URL del servidor Tika és obligatòria.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/ceb-PH/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "I-klik dinhi aron makapili",
 	"Click here to select a csv file.": "",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "Mga dokumento",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "wala maghimo ug eksternal nga koneksyon, ug ang imong data nagpabiling luwas sa imong lokal nga host server.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Wala kay account ?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Pagsulod sa block overlap",
 	"Enter Chunk Size": "Isulod ang block size",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "",
 	"Enter Google PSE API Key": "",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Pinulongan",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Kahayag",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "",
-	"Made by OpenWebUI Community": "Gihimo sa komunidad sa OpenWebUI",
+	"Made by Open WebUI Community": "Gihimo sa komunidad sa OpenWebUI",
 	"Make sure to enclose them with": "Siguruha nga palibutan sila",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "",
 	"Reasoning Effort": "",
 	"Record voice": "Irekord ang tingog",
-	"Redirecting you to OpenWebUI Community": "Gi-redirect ka sa komunidad sa OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Gi-redirect ka sa komunidad sa 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Malampuson nga na-save ang mga setting!",
 	"Share": "",
 	"Share Chat": "",
-	"Share to OpenWebUI Community": "Ipakigbahin sa komunidad sa OpenWebUI",
+	"Share to Open WebUI Community": "Ipakigbahin sa komunidad sa OpenWebUI",
 	"Show": "Pagpakita",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/cs-CZ/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klikněte sem pro",
 	"Click here to download user import template file.": "Klikněte zde pro stažení šablony souboru pro import uživatelů.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klikněte sem a zjistěte více o faster-whisper a podívejte se na dostupné modely.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klikněte sem pro výběr",
 	"Click here to select a csv file.": "Klikněte zde pro výběr souboru typu csv.",
 	"Click here to select a py file.": "Klikněte sem pro výběr {{py}} souboru.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentace",
 	"Documents": "Dokumenty",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "nevytváří žádná externí připojení a vaše data zůstávají bezpečně na vašem lokálním serveru.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nemáte účet?",
 	"don't install random functions from sources you don't trust.": "Neinstalujte náhodné funkce ze zdrojů, kterým nedůvěřujete.",
 	"don't install random tools from sources you don't trust.": "Neinstalujte náhodné nástroje ze zdrojů, kterým nedůvěřujete.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Zadejte překryv části",
 	"Enter Chunk Size": "Zadejte velikost bloku",
 	"Enter description": "Zadejte popis",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Zadejte URL adresu Github Raw",
 	"Enter Google PSE API Key": "Zadejte klíč rozhraní API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Znalosti byly úspěšně odstraněny.",
 	"Knowledge reset successfully.": "Úspěšné obnovení znalostí.",
 	"Knowledge updated successfully": "Znalosti úspěšně aktualizovány",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Režim vstupní stránky",
 	"Language": "Jazyk",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "Nechte prázdné pro zahrnutí všech modelů nebo vyberte konkrétní modely.",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Nechte prázdné pro použití výchozího podnětu, nebo zadejte vlastní podnět.",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Světlo",
 	"Listening...": "Poslouchání...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokální modely",
 	"Lost": "Ztracený",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Vytvořeno komunitou OpenWebUI",
+	"Made by Open WebUI Community": "Vytvořeno komunitou OpenWebUI",
 	"Make sure to enclose them with": "Ujistěte se, že jsou uzavřeny pomocí",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Ujistěte se, že exportujete soubor workflow.json ve formátu API z ComfyUI.",
 	"Manage": "Spravovat",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Číst nahlas",
 	"Reasoning Effort": "",
 	"Record voice": "Nahrát hlas",
-	"Redirecting you to OpenWebUI Community": "Přesměrování na komunitu OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Přesměrování na komunitu 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Odkazujte na sebe jako na \"uživatele\" (např. \"Uživatel se učí španělsky\").",
 	"References from": "Reference z",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Nastavení byla úspěšně uložena!",
 	"Share": "Sdílet",
 	"Share Chat": "Sdílet chat",
-	"Share to OpenWebUI Community": "Sdílet s komunitou OpenWebUI",
+	"Share to Open WebUI Community": "Sdílet s komunitou OpenWebUI",
 	"Show": "Zobrazit",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Zobrazit podrobnosti administrátora v překryvném okně s čekajícím účtem",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostní databázi a synchronizuje všechny soubory. Přejete si pokračovat?",
 	"Thorough explanation": "Obsáhlé vysvětlení",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Je vyžadována URL adresa serveru Tika.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/da-DK/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klik her for at",
 	"Click here to download user import template file.": "Klik her for at downloade bruger import template fil.",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Klik her for at vælge",
 	"Click here to select a csv file.": "Klik her for at vælge en csv fil",
 	"Click here to select a py file.": "Klik her for at vælge en py fil",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentation",
 	"Documents": "Dokumenter",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "laver ikke eksterne kald, og din data bliver sikkert på din egen lokalt hostede server.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Har du ikke en profil?",
 	"don't install random functions from sources you don't trust.": "lad være med at installere tilfældige funktioner fra kilder, som du ikke stoler på.",
 	"don't install random tools from sources you don't trust.": "lad være med at installere tilfældige værktøjer fra kilder, som du ikke stoler på.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Indtast overlapning af tekststykker",
 	"Enter Chunk Size": "Indtast størrelse af tekststykker",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Indtast Github Raw URL",
 	"Enter Google PSE API Key": "Indtast Google PSE API-nøgle",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Viden slettet.",
 	"Knowledge reset successfully.": "Viden nulstillet.",
 	"Knowledge updated successfully": "Viden opdateret.",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Landing Page-tilstand",
 	"Language": "Sprog",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Lad stå tomt for at bruge standardprompten, eller indtast en brugerdefineret prompt",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Lys",
 	"Listening...": "Lytter...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokale modeller",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Lavet af OpenWebUI Community",
+	"Made by Open WebUI Community": "Lavet af OpenWebUI Community",
 	"Make sure to enclose them with": "Sørg for at omslutte dem med",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Sørg for at eksportere en workflow.json-fil som API-format fra ComfyUI.",
 	"Manage": "Administrer",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Læs højt",
 	"Reasoning Effort": "",
 	"Record voice": "Optag stemme",
-	"Redirecting you to OpenWebUI Community": "Omdirigerer dig til OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "Omdirigerer dig til OpenWebUI Community",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Referer til dig selv som \"Bruger\" (f.eks. \"Bruger lærer spansk\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Indstillinger gemt!",
 	"Share": "Del",
 	"Share Chat": "Del chat",
-	"Share to OpenWebUI Community": "Del til OpenWebUI Community",
+	"Share to Open WebUI Community": "Del til OpenWebUI Community",
 	"Show": "Vis",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Vis administratordetaljer i overlay for ventende konto",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette vil nulstille vidensbasen og synkronisere alle filer. Vil du fortsætte?",
 	"Thorough explanation": "Grundig forklaring",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika-server-URL påkrævet.",
 	"Tiktoken": "",

+ 111 - 104
src/lib/i18n/locales/de-DE/translation.json

@@ -1,11 +1,11 @@
 {
-	"-1 for no limit, or a positive integer for a specific limit": "",
+	"-1 for no limit, or a positive integer for a specific limit": "-1 für kein Limit oder eine positive Zahl für ein spezifisches Limit",
 	"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' oder '-1' für keine Ablaufzeit.",
 	"(e.g. `sh webui.sh --api --api-auth username_password`)": "(z. B. `sh webui.sh --api --api-auth username_password`)",
 	"(e.g. `sh webui.sh --api`)": "(z. B. `sh webui.sh --api`)",
 	"(latest)": "(neueste)",
 	"{{ models }}": "{{ Modelle }}",
-	"{{COUNT}} Replies": "",
+	"{{COUNT}} Replies": "{{COUNT}} Antworten",
 	"{{user}}'s Chats": "{{user}}s Unterhaltungen",
 	"{{webUIName}} Backend Required": "{{webUIName}}-Backend erforderlich",
 	"*Prompt node ID(s) are required for image generation": "*Prompt-Node-ID(s) sind für die Bildgenerierung erforderlich",
@@ -35,7 +35,7 @@
 	"Add Group": "Gruppe hinzufügen",
 	"Add Memory": "Erinnerung hinzufügen",
 	"Add Model": "Modell hinzufügen",
-	"Add Reaction": "",
+	"Add Reaction": "Reaktion hinzufügen",
 	"Add Tag": "Tag hinzufügen",
 	"Add Tags": "Tags hinzufügen",
 	"Add text content": "Textinhalt hinzufügen",
@@ -51,7 +51,7 @@
 	"Advanced Params": "Erweiterte Parameter",
 	"All Documents": "Alle Dokumente",
 	"All models deleted successfully": "Alle Modelle erfolgreich gelöscht",
-	"Allow Chat Controls": "",
+	"Allow Chat Controls": "Chat-Steuerung erlauben",
 	"Allow Chat Delete": "Löschen von Unterhaltungen erlauben",
 	"Allow Chat Deletion": "Löschen von Unterhaltungen erlauben",
 	"Allow Chat Edit": "Bearbeiten von Unterhaltungen erlauben",
@@ -60,21 +60,21 @@
 	"Allow Temporary Chat": "Temporäre Unterhaltungen erlauben",
 	"Allow User Location": "Standort freigeben",
 	"Allow Voice Interruption in Call": "Unterbrechung durch Stimme im Anruf zulassen",
-	"Allowed Endpoints": "",
+	"Allowed Endpoints": "Erlaubte Endpunkte",
 	"Already have an account?": "Haben Sie bereits einen Account?",
 	"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternative zu top_p und zielt darauf ab, ein Gleichgewicht zwischen Qualität und Vielfalt zu gewährleisten. Der Parameter p repräsentiert die Mindestwahrscheinlichkeit für ein Token, um berücksichtigt zu werden, relativ zur Wahrscheinlichkeit des wahrscheinlichsten Tokens. Zum Beispiel, bei p=0.05 und das wahrscheinlichste Token hat eine Wahrscheinlichkeit von 0.9, werden Logits mit einem Wert von weniger als 0.045 herausgefiltert. (Standard: 0.0)",
-	"Always": "",
+	"Always": "Immer",
 	"Amazing": "Fantastisch",
 	"an assistant": "ein Assistent",
-	"Analyzed": "",
-	"Analyzing...": "",
+	"Analyzed": "Analysiert",
+	"Analyzing...": "Analysiere...",
 	"and": "und",
 	"and {{COUNT}} more": "und {{COUNT}} mehr",
 	"and create a new shared link.": "und erstellen Sie einen neuen freigegebenen Link.",
 	"API Base URL": "API-Basis-URL",
 	"API Key": "API-Schlüssel",
 	"API Key created.": "API-Schlüssel erstellt.",
-	"API Key Endpoint Restrictions": "",
+	"API Key Endpoint Restrictions": "API-Schlüssel Endpunkteinschränkungen",
 	"API keys": "API-Schlüssel",
 	"Application DN": "Anwendungs-DN",
 	"Application DN Password": "Anwendungs-DN-Passwort",
@@ -84,8 +84,8 @@
 	"Archive All Chats": "Alle Unterhaltungen archivieren",
 	"Archived Chats": "Archivierte Unterhaltungen",
 	"archived-chat-export": "archivierter-chat-export",
-	"Are you sure you want to delete this channel?": "",
-	"Are you sure you want to delete this message?": "",
+	"Are you sure you want to delete this channel?": "Sind Sie sicher, dass Sie diesen Kanal löschen möchten?",
+	"Are you sure you want to delete this message?": "Sind Sie sicher, dass Sie diese Nachricht löschen möchten?",
 	"Are you sure you want to unarchive all archived chats?": "Sind Sie sicher, dass Sie alle archivierten Unterhaltungen wiederherstellen möchten?",
 	"Are you sure?": "Sind Sie sicher?",
 	"Arena Models": "Arena-Modelle",
@@ -94,15 +94,15 @@
 	"Assistant": "Assistent",
 	"Attach file": "Datei anhängen",
 	"Attention to detail": "Aufmerksamkeit für Details",
-	"Attribute for Mail": "",
+	"Attribute for Mail": "Attribut für E-Mail",
 	"Attribute for Username": "Attribut für Benutzername",
 	"Audio": "Audio",
 	"August": "August",
 	"Authenticate": "Authentifizieren",
 	"Auto-Copy Response to Clipboard": "Antwort automatisch in die Zwischenablage kopieren",
 	"Auto-playback response": "Antwort automatisch abspielen",
-	"Autocomplete Generation": "",
-	"Autocomplete Generation Input Max Length": "",
+	"Autocomplete Generation": "Automatische Vervollständigung",
+	"Autocomplete Generation Input Max Length": "Maximale Eingabenlände für automatische Vervollständigung",
 	"Automatic1111": "Automatic1111",
 	"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111-API-Authentifizierungszeichenfolge",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111-Basis-URL",
@@ -119,7 +119,7 @@
 	"Batch Size (num_batch)": "Stapelgröße (num_batch)",
 	"before": "bereits geteilt",
 	"Being lazy": "Faulheit",
-	"Beta": "",
+	"Beta": "Beta",
 	"Bing Search V7 Endpoint": "Bing Search V7-Endpunkt",
 	"Bing Search V7 Subscription Key": "Bing Search V7-Abonnement-Schlüssel",
 	"Brave Search API Key": "Brave Search API-Schlüssel",
@@ -130,13 +130,13 @@
 	"Camera": "Kamera",
 	"Cancel": "Abbrechen",
 	"Capabilities": "Fähigkeiten",
-	"Capture": "",
+	"Capture": "Aufnehmen",
 	"Certificate Path": "Zertifikatpfad",
 	"Change Password": "Passwort ändern",
-	"Channel Name": "",
-	"Channels": "",
+	"Channel Name": "Kanalname",
+	"Channels": "Kanäle",
 	"Character": "Zeichen",
-	"Character limit for autocomplete generation input": "",
+	"Character limit for autocomplete generation input": "Zeichenlimit für die Eingabe der automatischen Vervollständigung",
 	"Chart new frontiers": "Neue Wege beschreiten",
 	"Chat": "Gespräch",
 	"Chat Background Image": "Hintergrundbild des Unterhaltungsfensters",
@@ -163,6 +163,7 @@
 	"Click here to": "Klicken Sie hier, um",
 	"Click here to download user import template file.": "Klicken Sie hier, um die Vorlage für den Benutzerimport herunterzuladen.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klicken Sie hier, um mehr über faster-whisper zu erfahren und die verfügbaren Modelle zu sehen.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klicke Sie zum Auswählen hier",
 	"Click here to select a csv file.": "Klicken Sie zum Auswählen einer CSV-Datei hier.",
 	"Click here to select a py file.": "Klicken Sie zum Auswählen einer py-Datei hier.",
@@ -171,16 +172,16 @@
 	"Click on the user role button to change a user's role.": "Klicken Sie auf die Benutzerrolle, um sie zu ändern.",
 	"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Schreibberechtigung für die Zwischenablage verweigert. Bitte überprüfen Sie Ihre Browsereinstellungen, um den erforderlichen Zugriff zu erlauben.",
 	"Clone": "Klonen",
-	"Clone Chat": "",
-	"Clone of {{TITLE}}": "",
+	"Clone Chat": "Konversation klonen",
+	"Clone of {{TITLE}}": "Klon von {{TITLE}}",
 	"Close": "Schließen",
 	"Code execution": "Codeausführung",
 	"Code formatted successfully": "Code erfolgreich formatiert",
-	"Code Interpreter": "",
+	"Code Interpreter": "Code-Interpreter",
 	"Collection": "Kollektion",
 	"Color": "Farbe",
 	"ComfyUI": "ComfyUI",
-	"ComfyUI API Key": "",
+	"ComfyUI API Key": "ComfyUI-API-Schlüssel",
 	"ComfyUI Base URL": "ComfyUI-Basis-URL",
 	"ComfyUI Base URL is required.": "ComfyUI-Basis-URL wird benötigt.",
 	"ComfyUI Workflow": "ComfyUI-Workflow",
@@ -192,9 +193,9 @@
 	"Confirm": "Bestätigen",
 	"Confirm Password": "Passwort bestätigen",
 	"Confirm your action": "Bestätigen Sie Ihre Aktion.",
-	"Confirm your new password": "",
+	"Confirm your new password": "Neues Passwort bestätigen",
 	"Connections": "Verbindungen",
-	"Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort. (Default: medium)": "",
+	"Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort. (Default: medium)": "Beschränkt den Aufwand für das Schlussfolgern bei Schlussfolgerungsmodellen. Nur anwendbar auf Schlussfolgerungsmodelle von spezifischen Anbietern, die den Schlussfolgerungsaufwand unterstützen. (Standard: medium)",
 	"Contact Admin for WebUI Access": "Kontaktieren Sie den Administrator für den Zugriff auf die Weboberfläche",
 	"Content": "Info",
 	"Content Extraction": "Inhaltsextraktion",
@@ -220,7 +221,7 @@
 	"Create a model": "Modell erstellen",
 	"Create Account": "Konto erstellen",
 	"Create Admin Account": "Administrator-Account erstellen",
-	"Create Channel": "",
+	"Create Channel": "Kanal erstellen",
 	"Create Group": "Gruppe erstellen",
 	"Create Knowledge": "Wissen erstellen",
 	"Create new key": "Neuen Schlüssel erstellen",
@@ -238,10 +239,10 @@
 	"Default": "Standard",
 	"Default (Open AI)": "Standard (Open AI)",
 	"Default (SentenceTransformers)": "Standard (SentenceTransformers)",
-	"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.": "",
+	"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.": "Der Standardmodus funktioniert mit einer breiteren Auswahl von Modellen, indem er Werkzeuge einmal vor der Ausführung aufruft. Der native Modus nutzt die integrierten Tool-Aufrufmöglichkeiten des Modells, erfordert jedoch, dass das Modell diese Funktion von Natur aus unterstützt.",
 	"Default Model": "Standardmodell",
 	"Default model updated": "Standardmodell aktualisiert",
-	"Default Models": "",
+	"Default Models": "Standardmodelle",
 	"Default permissions": "Standardberechtigungen",
 	"Default permissions updated successfully": "Standardberechtigungen erfolgreich aktualisiert",
 	"Default Prompt Suggestions": "Prompt-Vorschläge",
@@ -257,7 +258,7 @@
 	"Delete chat?": "Unterhaltung löschen?",
 	"Delete folder?": "Ordner löschen?",
 	"Delete function?": "Funktion löschen?",
-	"Delete Message": "",
+	"Delete Message": "Nachricht löschen",
 	"Delete prompt?": "Prompt löschen?",
 	"delete this link": "diesen Link löschen",
 	"Delete tool?": "Werkzeug löschen?",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentation",
 	"Documents": "Dokumente",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "stellt keine externen Verbindungen her, und Ihre Daten bleiben sicher auf Ihrem lokal gehosteten Server.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Haben Sie noch kein Benutzerkonto?",
 	"don't install random functions from sources you don't trust.": "installieren Sie keine Funktionen aus Quellen, denen Sie nicht vertrauen.",
 	"don't install random tools from sources you don't trust.": "installieren Sie keine Werkzeuge aus Quellen, denen Sie nicht vertrauen.",
@@ -310,7 +312,7 @@
 	"e.g. Tools for performing various operations": "z. B. Werkzeuge für verschiedene Operationen",
 	"Edit": "Bearbeiten",
 	"Edit Arena Model": "Arena-Modell bearbeiten",
-	"Edit Channel": "",
+	"Edit Channel": "Kanal bearbeiten",
 	"Edit Connection": "Verbindung bearbeiten",
 	"Edit Default Permissions": "Standardberechtigungen bearbeiten",
 	"Edit Memory": "Erinnerungen bearbeiten",
@@ -323,10 +325,10 @@
 	"Embedding Model": "Embedding-Modell",
 	"Embedding Model Engine": "Embedding-Modell-Engine",
 	"Embedding model set to \"{{embedding_model}}\"": "Embedding-Modell auf \"{{embedding_model}}\" gesetzt",
-	"Enable API Key": "",
-	"Enable autocomplete generation for chat messages": "",
+	"Enable API Key": "API-Schlüssel aktivieren",
+	"Enable autocomplete generation for chat messages": "Automatische Vervollständigung für Chat-Nachrichten aktivieren",
 	"Enable Community Sharing": "Community-Freigabe aktivieren",
-	"Enable Google Drive": "",
+	"Enable Google Drive": "Google Drive aktivieren",
 	"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Aktiviere Memory Locking (mlock), um zu verhindern, dass Modelldaten aus dem RAM ausgelagert werden. Diese Option sperrt die Arbeitsseiten des Modells im RAM, um sicherzustellen, dass sie nicht auf die Festplatte ausgelagert werden. Dies kann die Leistung verbessern, indem Page Faults vermieden und ein schneller Datenzugriff sichergestellt werden.",
 	"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Aktiviere Memory Mapping (mmap), um Modelldaten zu laden. Diese Option ermöglicht es dem System, den Festplattenspeicher als Erweiterung des RAM zu verwenden, indem Festplattendateien so behandelt werden, als ob sie im RAM wären. Dies kann die Modellleistung verbessern, indem ein schnellerer Datenzugriff ermöglicht wird. Es kann jedoch nicht auf allen Systemen korrekt funktionieren und einen erheblichen Teil des Festplattenspeichers beanspruchen.",
 	"Enable Message Rating": "Nachrichtenbewertung aktivieren",
@@ -349,20 +351,21 @@
 	"Enter Chunk Overlap": "Geben Sie die Blocküberlappung ein",
 	"Enter Chunk Size": "Geben Sie die Blockgröße ein",
 	"Enter description": "Geben Sie eine Beschreibung ein",
-	"Enter Exa API Key": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
+	"Enter Exa API Key": "Geben Sie den Exa-API-Schlüssel ein",
 	"Enter Github Raw URL": "Geben Sie die Github Raw-URL ein",
 	"Enter Google PSE API Key": "Geben Sie den Google PSE-API-Schlüssel ein",
 	"Enter Google PSE Engine Id": "Geben Sie die Google PSE-Engine-ID ein",
 	"Enter Image Size (e.g. 512x512)": "Geben Sie die Bildgröße ein (z. B. 512x512)",
 	"Enter Jina API Key": "Geben Sie den Jina-API-Schlüssel ein",
-	"Enter Kagi Search API Key": "",
+	"Enter Kagi Search API Key": "Geben sie den Kagi Search API-Schlüssel ein",
 	"Enter language codes": "Geben Sie die Sprachcodes ein",
 	"Enter Model ID": "Geben Sie die Modell-ID ein",
 	"Enter model tag (e.g. {{modelTag}})": "Geben Sie den Model-Tag ein",
 	"Enter Mojeek Search API Key": "Geben Sie den Mojeek Search API-Schlüssel ein",
 	"Enter Number of Steps (e.g. 50)": "Geben Sie die Anzahl an Schritten ein (z. B. 50)",
-	"Enter proxy URL (e.g. https://user:password@host:port)": "",
-	"Enter reasoning effort": "",
+	"Enter proxy URL (e.g. https://user:password@host:port)": "Geben sie die Proxy-URL ein (z. B. https://user:password@host:port)",
+	"Enter reasoning effort": "Geben Sie den Schlussfolgerungsaufwand ein",
 	"Enter Sampler (e.g. Euler a)": "Geben Sie den Sampler ein (z. B. Euler a)",
 	"Enter Scheduler (e.g. Karras)": "Geben Sie den Scheduler ein (z. B. Karras)",
 	"Enter Score": "Punktzahl eingeben",
@@ -379,33 +382,33 @@
 	"Enter stop sequence": "Stop-Sequenz eingeben",
 	"Enter system prompt": "Systemprompt eingeben",
 	"Enter Tavily API Key": "Geben Sie den Tavily-API-Schlüssel ein",
-	"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "",
+	"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Geben sie die öffentliche URL Ihrer WebUI ein. Diese URL wird verwendet, um Links in den Benachrichtigungen zu generieren.",
 	"Enter Tika Server URL": "Geben Sie die Tika-Server-URL ein",
 	"Enter Top K": "Geben Sie Top K ein",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "Geben Sie die URL ein (z. B. http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://localhost:11434)": "Geben Sie die URL ein (z. B. http://localhost:11434)",
-	"Enter your current password": "",
+	"Enter your current password": "Geben Sie Ihr aktuelles Passwort ein",
 	"Enter Your Email": "Geben Sie Ihre E-Mail-Adresse ein",
 	"Enter Your Full Name": "Geben Sie Ihren vollständigen Namen ein",
 	"Enter your message": "Geben Sie Ihre Nachricht ein",
-	"Enter your new password": "",
+	"Enter your new password": "Geben Sie Ihr neues Passwort ein",
 	"Enter Your Password": "Geben Sie Ihr Passwort ein",
 	"Enter Your Role": "Geben Sie Ihre Rolle ein",
 	"Enter Your Username": "Geben Sie Ihren Benutzernamen ein",
-	"Enter your webhook URL": "",
+	"Enter your webhook URL": "Geben Sie Ihre Webhook-URL ein",
 	"Error": "Fehler",
 	"ERROR": "FEHLER",
-	"Error accessing Google Drive: {{error}}": "",
-	"Error uploading file: {{error}}": "",
+	"Error accessing Google Drive: {{error}}": "Fehler beim Zugriff auf Google Drive: {{error}}",
+	"Error uploading file: {{error}}": "Fehler beim Hochladen der Datei: {{error}}",
 	"Evaluations": "Evaluationen",
-	"Exa API Key": "",
+	"Exa API Key": "Exa-API-Schlüssel",
 	"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Beispiel: (&(objectClass=inetOrgPerson)(uid=%s))",
 	"Example: ALL": "Beispiel: ALL",
-	"Example: mail": "",
+	"Example: mail": "Beispiel: mail",
 	"Example: ou=users,dc=foo,dc=example": "Beispiel: ou=users,dc=foo,dc=example",
 	"Example: sAMAccountName or uid or userPrincipalName": "Beispiel: sAMAccountName or uid or userPrincipalName",
 	"Exclude": "Ausschließen",
-	"Execute code for analysis": "",
+	"Execute code for analysis": "Code für Analyse ausführen",
 	"Experimental": "Experimentell",
 	"Explore the cosmos": "Erforschen Sie das Universum",
 	"Export": "Exportieren",
@@ -423,12 +426,12 @@
 	"External Models": "Externe Modelle",
 	"Failed to add file.": "Fehler beim Hinzufügen der Datei.",
 	"Failed to create API Key.": "Fehler beim Erstellen des API-Schlüssels.",
-	"Failed to fetch models": "",
+	"Failed to fetch models": "Fehler beim Abrufen der Modelle",
 	"Failed to read clipboard contents": "Fehler beim Abruf der Zwischenablage",
-	"Failed to save models configuration": "",
+	"Failed to save models configuration": "Fehler beim Speichern der Modellkonfiguration",
 	"Failed to update settings": "Fehler beim Aktualisieren der Einstellungen",
 	"Failed to upload file.": "Fehler beim Hochladen der Datei.",
-	"Features Permissions": "",
+	"Features Permissions": "Funktionen-Berechtigungen",
 	"February": "Februar",
 	"Feedback History": "Feedback-Verlauf",
 	"Feedbacks": "Feedbacks",
@@ -440,7 +443,7 @@
 	"File not found.": "Datei nicht gefunden.",
 	"File removed successfully.": "Datei erfolgreich entfernt.",
 	"File size should not exceed {{maxSize}} MB.": "Datei darf nicht größer als {{maxSize}} MB sein.",
-	"File uploaded successfully": "",
+	"File uploaded successfully": "Datei erfolgreich hochgeladen",
 	"Files": "Dateien",
 	"Filter is now globally disabled": "Filter ist jetzt global deaktiviert",
 	"Filter is now globally enabled": "Filter ist jetzt global aktiviert",
@@ -458,7 +461,7 @@
 	"Format your variables using brackets like this:": "Formatieren Sie Ihre Variablen mit Klammern, wie hier:",
 	"Frequency Penalty": "Frequenzstrafe",
 	"Function": "Funktion",
-	"Function Calling": "",
+	"Function Calling": "Funktionsaufruf",
 	"Function created successfully": "Funktion erfolgreich erstellt",
 	"Function deleted successfully": "Funktion erfolgreich gelöscht",
 	"Function Description": "Funktionsbeschreibung",
@@ -473,14 +476,14 @@
 	"Functions imported successfully": "Funktionen erfolgreich importiert",
 	"General": "Allgemein",
 	"General Settings": "Allgemeine Einstellungen",
-	"Generate an image": "",
+	"Generate an image": "Bild erzeugen",
 	"Generate Image": "Bild erzeugen",
 	"Generating search query": "Suchanfrage wird erstellt",
 	"Get started": "Loslegen",
 	"Get started with {{WEBUI_NAME}}": "Loslegen mit {{WEBUI_NAME}}",
 	"Global": "Global",
 	"Good Response": "Gute Antwort",
-	"Google Drive": "",
+	"Google Drive": "Google Drive",
 	"Google PSE API Key": "Google PSE-API-Schlüssel",
 	"Google PSE Engine Id": "Google PSE-Engine-ID",
 	"Group created successfully": "Gruppe erfolgreich erstellt",
@@ -504,14 +507,14 @@
 	"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Ich bestätige, dass ich gelesen habe und die Auswirkungen meiner Aktion verstehe. Mir sind die Risiken bewusst, die mit der Ausführung beliebigen Codes verbunden sind, und ich habe die Vertrauenswürdigkeit der Quelle überprüft.",
 	"ID": "ID",
 	"Ignite curiosity": "Neugier entfachen",
-	"Image": "",
-	"Image Compression": "",
-	"Image Generation": "",
+	"Image": "Bild",
+	"Image Compression": "Bildkomprimierung",
+	"Image Generation": "Bildgenerierung",
 	"Image Generation (Experimental)": "Bildgenerierung (experimentell)",
 	"Image Generation Engine": "Bildgenerierungs-Engine",
-	"Image Max Compression Size": "",
-	"Image Prompt Generation": "",
-	"Image Prompt Generation Prompt": "",
+	"Image Max Compression Size": "Maximale Bildkomprimierungsgröße",
+	"Image Prompt Generation": "Bild-Prompt-Generierung",
+	"Image Prompt Generation Prompt": "Prompt für die Bild-Prompt-Generierung",
 	"Image Settings": "Bildeinstellungen",
 	"Images": "Bilder",
 	"Import Chats": "Unterhaltungen importieren",
@@ -532,7 +535,7 @@
 	"Interface": "Benutzeroberfläche",
 	"Invalid file format.": "Ungültiges Dateiformat.",
 	"Invalid Tag": "Ungültiger Tag",
-	"is typing...": "",
+	"is typing...": "schreibt ...",
 	"January": "Januar",
 	"Jina API Key": "Jina-API-Schlüssel",
 	"join our Discord for help.": "Treten Sie unserem Discord bei, um Hilfe zu erhalten.",
@@ -542,7 +545,7 @@
 	"June": "Juni",
 	"JWT Expiration": "JWT-Ablauf",
 	"JWT Token": "JWT-Token",
-	"Kagi Search API Key": "",
+	"Kagi Search API Key": "Kagi Search API-Schlüssel",
 	"Keep Alive": "Verbindung aufrechterhalten",
 	"Key": "Schlüssel",
 	"Keyboard shortcuts": "Tastenkombinationen",
@@ -552,12 +555,14 @@
 	"Knowledge deleted successfully.": "Wissen erfolgreich gelöscht.",
 	"Knowledge reset successfully.": "Wissen erfolgreich zurückgesetzt.",
 	"Knowledge updated successfully": "Wissen erfolgreich aktualisiert",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Label",
 	"Landing Page Mode": "Startseitenmodus",
 	"Language": "Sprache",
 	"Last Active": "Zuletzt aktiv",
 	"Last Modified": "Zuletzt bearbeitet",
-	"Last reply": "",
+	"Last reply": "Letzte Antwort",
 	"LDAP": "LDAP",
 	"LDAP server updated": "LDAP-Server aktualisiert",
 	"Leaderboard": "Bestenliste",
@@ -566,20 +571,21 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Leer lassen, um alle Modelle vom \"{{URL}}/models\"-Endpunkt einzuschließen",
 	"Leave empty to include all models or select specific models": "Leer lassen, um alle Modelle einzuschließen oder spezifische Modelle auszuwählen",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Leer lassen, um den Standardprompt zu verwenden, oder geben Sie einen benutzerdefinierten Prompt ein",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Hell",
 	"Listening...": "Höre zu...",
-	"Llama.cpp": "",
+	"Llama.cpp": "Llama.cpp",
 	"LLMs can make mistakes. Verify important information.": "LLMs können Fehler machen. Überprüfe wichtige Informationen.",
 	"Local": "Lokal",
 	"Local Models": "Lokale Modelle",
 	"Lost": "Verloren",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Von der OpenWebUI-Community",
+	"Made by Open WebUI Community": "Von der OpenWebUI-Community",
 	"Make sure to enclose them with": "Umschließe Variablen mit",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Stellen Sie sicher, dass sie eine workflow.json-Datei im API-Format von ComfyUI exportieren.",
 	"Manage": "Verwalten",
 	"Manage Arena Models": "Arena-Modelle verwalten",
-	"Manage Models": "",
+	"Manage Models": "Modelle verwalten",
 	"Manage Ollama": "Ollama verwalten",
 	"Manage Ollama API Connections": "Ollama-API-Verbindungen verwalten",
 	"Manage OpenAI API Connections": "OpenAI-API-Verbindungen verwalten",
@@ -624,17 +630,17 @@
 	"Modelfile Content": "Modelfile-Inhalt",
 	"Models": "Modelle",
 	"Models Access": "Modell-Zugriff",
-	"Models configuration saved successfully": "",
+	"Models configuration saved successfully": "Modellkonfiguration erfolgreich gespeichert",
 	"Mojeek Search API Key": "Mojeek Search API-Schlüssel",
 	"more": "mehr",
 	"More": "Mehr",
 	"Name": "Name",
 	"Name your knowledge base": "Benennen Sie Ihren Wissensspeicher",
-	"Native": "",
+	"Native": "Nativ",
 	"New Chat": "Neue Unterhaltung",
-	"New Folder": "",
+	"New Folder": "Neuer Ordner",
 	"New Password": "Neues Passwort",
-	"new-channel": "",
+	"new-channel": "neuer-kanal",
 	"No content found": "Kein Inhalt gefunden",
 	"No content to speak": "Kein Inhalt zum Vorlesen",
 	"No distance available": "Keine Distanz verfügbar",
@@ -643,11 +649,11 @@
 	"No files found.": "Keine Dateien gefunden.",
 	"No groups with access, add a group to grant access": "Keine Gruppen mit Zugriff, fügen Sie eine Gruppe hinzu, um Zugriff zu gewähren",
 	"No HTML, CSS, or JavaScript content found.": "Keine HTML-, CSS- oder JavaScript-Inhalte gefunden.",
-	"No inference engine with management support found": "",
+	"No inference engine with management support found": "Keine Inferenz-Engine mit Management-Unterstützung gefunden",
 	"No knowledge found": "Kein Wissen gefunden",
 	"No model IDs": "Keine Modell-IDs",
 	"No models found": "Keine Modelle gefunden",
-	"No models selected": "",
+	"No models selected": "Keine Modelle ausgewählt",
 	"No results found": "Keine Ergebnisse gefunden",
 	"No search query generated": "Keine Suchanfrage generiert",
 	"No source available": "Keine Quelle verfügbar",
@@ -658,8 +664,8 @@
 	"Not helpful": "Nich hilfreich",
 	"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Hinweis: Wenn Sie eine Mindestpunktzahl festlegen, werden in der Suche nur Dokumente mit einer Punktzahl größer oder gleich der Mindestpunktzahl zurückgegeben.",
 	"Notes": "Notizen",
-	"Notification Sound": "",
-	"Notification Webhook": "",
+	"Notification Sound": "Benachrichtigungston",
+	"Notification Webhook": "Benachrichtigungs-Webhook",
 	"Notifications": "Benachrichtigungen",
 	"November": "November",
 	"num_gpu (Ollama)": "num_gpu (Ollama)",
@@ -724,8 +730,8 @@
 	"Please carefully review the following warnings:": "Bitte überprüfen Sie die folgenden Warnungen sorgfältig:",
 	"Please enter a prompt": "Bitte geben Sie einen Prompt ein",
 	"Please fill in all fields.": "Bitte füllen Sie alle Felder aus.",
-	"Please select a model first.": "",
-	"Please select a model.": "",
+	"Please select a model first.": "Bitte wählen Sie zuerst ein Modell aus.",
+	"Please select a model.": "Bitte wählen Sie ein Modell aus.",
 	"Please select a reason": "Bitte wählen Sie einen Grund aus",
 	"Port": "Port",
 	"Positive attitude": "Positive Einstellung",
@@ -734,7 +740,7 @@
 	"Previous 30 days": "Vorherige 30 Tage",
 	"Previous 7 days": "Vorherige 7 Tage",
 	"Profile Image": "Profilbild",
-	"Prompt": "",
+	"Prompt": "Prompt",
 	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Prompt (z. B. \"Erzähle mir eine interessante Tatsache über das Römische Reich\")",
 	"Prompt Content": "Prompt-Inhalt",
 	"Prompt created successfully": "Prompt erfolgreich erstellt",
@@ -742,7 +748,7 @@
 	"Prompt updated successfully": "Prompt erfolgreich aktualisiert",
 	"Prompts": "Prompts",
 	"Prompts Access": "Prompt-Zugriff",
-	"Proxy URL": "",
+	"Proxy URL": "Proxy-URL",
 	"Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" von Ollama.com beziehen",
 	"Pull a model from Ollama.com": "Modell von Ollama.com beziehen",
 	"Query Generation Prompt": "Abfragegenerierungsprompt",
@@ -750,11 +756,11 @@
 	"RAG Template": "RAG-Vorlage",
 	"Rating": "Bewertung",
 	"Re-rank models by topic similarity": "Modelle nach thematischer Ähnlichkeit neu ordnen",
-	"Read": "",
+	"Read": "Lesen",
 	"Read Aloud": "Vorlesen",
-	"Reasoning Effort": "",
+	"Reasoning Effort": "Schlussfolgerungsaufwand",
 	"Record voice": "Stimme aufnehmen",
-	"Redirecting you to OpenWebUI Community": "Sie werden zur OpenWebUI-Community weitergeleitet",
+	"Redirecting you to Open WebUI Community": "Sie werden zur OpenWebUI-Community weitergeleitet",
 	"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. (Default: 40)": "Reduziert die Wahrscheinlichkeit, Unsinn zu generieren. Ein höherer Wert (z.B. 100) liefert vielfältigere Antworten, während ein niedrigerer Wert (z.B. 10) konservativer ist. (Standard: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Beziehen Sie sich auf sich selbst als \"Benutzer\" (z. B. \"Benutzer lernt Spanisch\")",
 	"References from": "Referenzen aus",
@@ -765,22 +771,22 @@
 	"Remove": "Entfernen",
 	"Remove Model": "Modell entfernen",
 	"Rename": "Umbenennen",
-	"Reorder Models": "",
+	"Reorder Models": "Modelle neu anordnen",
 	"Repeat Last N": "Wiederhole die letzten N",
-	"Reply in Thread": "",
+	"Reply in Thread": "Im Thread antworten",
 	"Request Mode": "Anforderungsmodus",
 	"Reranking Model": "Reranking-Modell",
 	"Reranking model disabled": "Reranking-Modell deaktiviert",
 	"Reranking model set to \"{{reranking_model}}\"": "Reranking-Modell \"{{reranking_model}}\" fesgelegt",
 	"Reset": "Zurücksetzen",
-	"Reset All Models": "",
+	"Reset All Models": "Alle Modelle zurücksetzen",
 	"Reset Upload Directory": "Upload-Verzeichnis zurücksetzen",
 	"Reset Vector Storage/Knowledge": "Vektorspeicher/Wissen zurücksetzen",
-	"Reset view": "",
+	"Reset view": "Ansicht zurücksetzen",
 	"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Benachrichtigungen können nicht aktiviert werden, da die Website-Berechtigungen abgelehnt wurden. Bitte besuchen Sie Ihre Browser-Einstellungen, um den erforderlichen Zugriff zu gewähren.",
 	"Response splitting": "Antwortaufteilung",
 	"Result": "Ergebnis",
-	"Retrieval Query Generation": "",
+	"Retrieval Query Generation": "Abfragegenerierung",
 	"Rich Text Input for Chat": "Rich-Text-Eingabe für Unterhaltungen",
 	"RK": "RK",
 	"Role": "Rolle",
@@ -810,11 +816,11 @@
 	"Search options": "Suchoptionen",
 	"Search Prompts": "Prompts durchsuchen...",
 	"Search Result Count": "Anzahl der Suchergebnisse",
-	"Search the internet": "",
+	"Search the internet": "Im Internet suchen",
 	"Search Tools": "Werkzeuge durchsuchen...",
 	"SearchApi API Key": "SearchApi-API-Schlüssel",
 	"SearchApi Engine": "SearchApi-Engine",
-	"Searched {{count}} sites": "",
+	"Searched {{count}} sites": "{{count}} Websites durchsucht",
 	"Searching \"{{searchQuery}}\"": "Suche nach \"{{searchQuery}}\"",
 	"Searching Knowledge for \"{{searchQuery}}\"": "Suche im Wissen nach \"{{searchQuery}}\"",
 	"Searxng Query URL": "Searxng-Abfrage-URL",
@@ -829,7 +835,7 @@
 	"Select a pipeline": "Wählen Sie eine Pipeline",
 	"Select a pipeline url": "Wählen Sie eine Pipeline-URL",
 	"Select a tool": "Wählen Sie ein Werkzeug",
-	"Select an Ollama instance": "",
+	"Select an Ollama instance": "Wählen Sie eine Ollama-Instanz",
 	"Select Engine": "Engine auswählen",
 	"Select Knowledge": "Wissensdatenbank auswählen",
 	"Select model": "Modell auswählen",
@@ -856,7 +862,7 @@
 	"Set Scheduler": "Scheduler festlegen",
 	"Set Steps": "Schrittgröße festlegen",
 	"Set Task Model": "Aufgabenmodell festlegen",
-	"Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "",
+	"Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Legen Sie die Anzahl der Schichten fest, die auf die GPU ausgelagert werden. Eine Erhöhung dieses Wertes kann die Leistung für Modelle, die für die GPU-Beschleunigung optimiert sind, erheblich verbessern, kann jedoch auch mehr Strom und GPU-Ressourcen verbrauchen.",
 	"Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Legt die Anzahl der für die Berechnung verwendeten GPU-Geräte fest. Diese Option steuert, wie viele GPU-Geräte (falls verfügbar) zur Verarbeitung eingehender Anfragen verwendet werden. Eine Erhöhung dieses Wertes kann die Leistung für Modelle, die für GPU-Beschleunigung optimiert sind, erheblich verbessern, kann jedoch auch mehr Strom und GPU-Ressourcen verbrauchen.",
 	"Set Voice": "Stimme festlegen",
 	"Set whisper model": "Whisper-Modell festlegen",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Einstellungen erfolgreich gespeichert!",
 	"Share": "Teilen",
 	"Share Chat": "Unterhaltung teilen",
-	"Share to OpenWebUI Community": "Mit OpenWebUI Community teilen",
+	"Share to Open WebUI Community": "Mit OpenWebUI Community teilen",
 	"Show": "Anzeigen",
 	"Show \"What's New\" modal on login": "\"Was gibt's Neues\"-Modal beim Anmelden anzeigen",
 	"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
@@ -883,7 +889,7 @@
 	"Sign up": "Registrieren",
 	"Sign up to {{WEBUI_NAME}}": "Bei {{WEBUI_NAME}} registrieren",
 	"Signing in to {{WEBUI_NAME}}": "Wird bei {{WEBUI_NAME}} angemeldet",
-	"sk-1234": "",
+	"sk-1234": "sk-1234",
 	"Source": "Quelle",
 	"Speech Playback Speed": "Sprachwiedergabegeschwindigkeit",
 	"Speech recognition error: {{error}}": "Spracherkennungsfehler: {{error}}",
@@ -903,7 +909,7 @@
 	"System": "System",
 	"System Instructions": "Systemanweisungen",
 	"System Prompt": "System-Prompt",
-	"Tags Generation": "",
+	"Tags Generation": "Tag-Generierung",
 	"Tags Generation Prompt": "Prompt für Tag-Generierung",
 	"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "Tail-Free Sampling wird verwendet, um den Einfluss weniger wahrscheinlicher Tokens auf die Ausgabe zu reduzieren. Ein höherer Wert (z.B. 2.0) reduziert den Einfluss stärker, während ein Wert von 1.0 diese Einstellung deaktiviert. (Standard: 1)",
 	"Tap to interrupt": "Zum Unterbrechen tippen",
@@ -921,7 +927,7 @@
 	"The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory.  (Default: 512)": "Die Batch-Größe bestimmt, wie viele Textanfragen gleichzeitig verarbeitet werden. Eine größere Batch-Größe kann die Leistung und Geschwindigkeit des Modells erhöhen, erfordert jedoch auch mehr Speicher. (Standard: 512)",
 	"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Die Entwickler hinter diesem Plugin sind leidenschaftliche Freiwillige aus der Community. Wenn Sie dieses Plugin hilfreich finden, erwägen Sie bitte, zu seiner Entwicklung beizutragen.",
 	"The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "Die Bewertungs-Bestenliste basiert auf dem Elo-Bewertungssystem und wird in Echtzeit aktualisiert.",
-	"The LDAP attribute that maps to the mail that users use to sign in.": "",
+	"The LDAP attribute that maps to the mail that users use to sign in.": "Das LDAP-Attribut, das der Mail zugeordnet ist, die Benutzer zum Anmelden verwenden.",
 	"The LDAP attribute that maps to the username that users use to sign in.": "Das LDAP-Attribut, das dem Benutzernamen zugeordnet ist, den Benutzer zum Anmelden verwenden.",
 	"The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "Die Bestenliste befindet sich derzeit in der Beta-Phase, und es ist möglich, dass wir die Bewertungsberechnungen anpassen, während wir den Algorithmus verfeinern.",
 	"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Die maximale Dateigröße in MB. Wenn die Dateigröße dieses Limit überschreitet, wird die Datei nicht hochgeladen.",
@@ -943,7 +949,8 @@
 	"This will delete all models including custom models and cannot be undone.": "Dies wird alle Modelle einschließlich benutzerdefinierter Modelle löschen und kann nicht rückgängig gemacht werden.",
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dadurch wird die Wissensdatenbank zurückgesetzt und alle Dateien synchronisiert. Möchten Sie fortfahren?",
 	"Thorough explanation": "Ausführliche Erklärung",
-	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}}": "Nachgedacht für {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika-Server-URL erforderlich.",
 	"Tiktoken": "Tiktoken",
@@ -958,7 +965,7 @@
 	"To access the GGUF models available for downloading,": "Um auf die verfügbaren GGUF-Modelle zuzugreifen,",
 	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Um auf das WebUI zugreifen zu können, wenden Sie sich bitte an einen Administrator. Administratoren können den Benutzerstatus über das Admin-Panel verwalten.",
 	"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Um Wissensdatenbanken hier anzuhängen, fügen Sie sie zunächst dem Arbeitsbereich \"Wissen\" hinzu.",
-	"To learn more about available endpoints, visit our documentation.": "",
+	"To learn more about available endpoints, visit our documentation.": "Um mehr über verfügbare Endpunkte zu erfahren, besuchen Sie unsere Dokumentation.",
 	"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Um Ihre Privatsphäre zu schützen, werden nur Bewertungen, Modell-IDs, Tags und Metadaten aus Ihrem Feedback geteilt – Ihre Unterhaltungen bleiben privat und werden nicht einbezogen.",
 	"To select actions here, add them to the \"Functions\" workspace first.": "Um Aktionen auszuwählen, fügen Sie diese zunächst dem Arbeitsbereich „Funktionen“ hinzu.",
 	"To select filters here, add them to the \"Functions\" workspace first.": "Um Filter auszuwählen, fügen Sie diese zunächst dem Arbeitsbereich „Funktionen“ hinzu.",
@@ -980,7 +987,7 @@
 	"Tools": "Werkzeuge",
 	"Tools Access": "Werkzeugzugriff",
 	"Tools are a function calling system with arbitrary code execution": "Wekzeuge sind ein Funktionssystem mit beliebiger Codeausführung",
-	"Tools Function Calling Prompt": "",
+	"Tools Function Calling Prompt": "Prompt für Funktionssystemaufrufe",
 	"Tools have a function calling system that allows arbitrary code execution": "Werkezuge verfügen über ein Funktionssystem, das die Ausführung beliebigen Codes ermöglicht",
 	"Tools have a function calling system that allows arbitrary code execution.": "Werkzeuge verfügen über ein Funktionssystem, das die Ausführung beliebigen Codes ermöglicht.",
 	"Top K": "Top K",
@@ -992,7 +999,7 @@
 	"TTS Voice": "TTS-Stimme",
 	"Type": "Art",
 	"Type Hugging Face Resolve (Download) URL": "Geben Sie die Hugging Face Resolve-URL ein",
-	"Uh-oh! There was an issue with the response.": "",
+	"Uh-oh! There was an issue with the response.": "Oh nein! Es gab ein Problem mit der Antwort.",
 	"UI": "Oberfläche",
 	"Unarchive All": "Alle wiederherstellen",
 	"Unarchive All Archived Chats": "Alle archivierten Unterhaltungen wiederherstellen",
@@ -1038,7 +1045,7 @@
 	"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
 	"Version": "Version",
 	"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} von {{totalVersions}}",
-	"View Replies": "",
+	"View Replies": "Antworten anzeigen",
 	"Visibility": "Sichtbarkeit",
 	"Voice": "Stimme",
 	"Voice Input": "Spracheingabe",
@@ -1051,11 +1058,11 @@
 	"Web Loader Settings": "Web Loader Einstellungen",
 	"Web Search": "Websuche",
 	"Web Search Engine": "Suchmaschine",
-	"Web Search in Chat": "",
-	"Web Search Query Generation": "",
+	"Web Search in Chat": "Websuche im Chat",
+	"Web Search Query Generation": "Abfragegenerierung für Websuche",
 	"Webhook URL": "Webhook URL",
 	"WebUI Settings": "WebUI-Einstellungen",
-	"WebUI URL": "",
+	"WebUI URL": "WebUI-URL",
 	"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI wird Anfragen an \"{{url}}/api/chat\" senden",
 	"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI wird Anfragen an \"{{url}}/chat/completions\" senden",
 	"What are you trying to achieve?": "Was versuchen Sie zu erreichen?",
@@ -1070,7 +1077,7 @@
 	"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "Funktioniert zusammen mit top-k. Ein höherer Wert (z.B. 0,95) führt zu vielfältigerem Text, während ein niedrigerer Wert (z.B. 0,5) fokussierteren und konservativeren Text erzeugt. (Standard: 0,9)",
 	"Workspace": "Arbeitsbereich",
 	"Workspace Permissions": "Arbeitsbereichsberechtigungen",
-	"Write": "",
+	"Write": "Schreiben",
 	"Write a prompt suggestion (e.g. Who are you?)": "Schreiben Sie einen Promptvorschlag (z. B. Wer sind Sie?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Schreibe eine kurze Zusammenfassung in 50 Wörtern, die [Thema oder Schlüsselwort] zusammenfasst.",
 	"Write something...": "Schreiben Sie etwas...",
@@ -1080,8 +1087,8 @@
 	"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Sie können nur mit maximal {{maxCount}} Datei(en) gleichzeitig chatten.",
 	"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Personalisieren Sie Interaktionen mit LLMs, indem Sie über die Schaltfläche \"Verwalten\" Erinnerungen hinzufügen.",
 	"You cannot upload an empty file.": "Sie können keine leere Datei hochladen.",
-	"You do not have permission to access this feature.": "",
-	"You do not have permission to upload files": "",
+	"You do not have permission to access this feature.": "Sie haben keine Berechtigung, auf diese Funktion zuzugreifen.",
+	"You do not have permission to upload files": "Sie haben keine Berechtigung, Dateien hochzuladen",
 	"You do not have permission to upload files.": "Sie haben keine Berechtigung zum Hochladen von Dateien.",
 	"You have no archived conversations.": "Du hast keine archivierten Unterhaltungen.",
 	"You have shared this chat": "Sie haben diese Unterhaltung geteilt",

+ 10 - 3
src/lib/i18n/locales/dg-DG/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Click to select",
 	"Click here to select a csv file.": "",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "Documents",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "does not connect external, data stays safe locally.",
+	"Domain Filter List": "",
 	"Don't have an account?": "No account? Much sad.",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Enter Overlap of Chunks",
 	"Enter Chunk Size": "Enter Size of Chunk",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "",
 	"Enter Google PSE API Key": "",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Doge Speak",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Light",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "",
-	"Made by OpenWebUI Community": "Made by OpenWebUI Community",
+	"Made by Open WebUI Community": "Made by Open WebUI Community",
 	"Make sure to enclose them with": "Make sure to enclose them with",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "",
 	"Reasoning Effort": "",
 	"Record voice": "Record Bark",
-	"Redirecting you to OpenWebUI Community": "Redirecting you to OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "Redirecting you to Open WebUI Community",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Settings saved successfully! Very success!",
 	"Share": "",
 	"Share Chat": "",
-	"Share to OpenWebUI Community": "Share to OpenWebUI Community much community",
+	"Share to Open WebUI Community": "Share to Open WebUI Community much community",
 	"Show": "Show much show",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/el-GR/translation.json

@@ -163,6 +163,7 @@
 	"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.": "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Τεκμηρίωση",
 	"Documents": "Έγγραφα",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "δεν κάνει καμία εξωτερική σύνδεση, και τα δεδομένα σας παραμένουν ασφαλή στον τοπικά φιλοξενούμενο διακομιστή σας.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Δεν έχετε λογαριασμό;",
 	"don't install random functions from sources you don't trust.": "μην εγκαθιστάτε τυχαίες λειτουργίες από πηγές που δεν εμπιστεύεστε.",
 	"don't install random tools from sources you don't trust.": "μην εγκαθιστάτε τυχαία εργαλεία από πηγές που δεν εμπιστεύεστε.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Εισάγετε την Επικάλυψη Τμημάτων",
 	"Enter Chunk Size": "Εισάγετε το Μέγεθος Τμημάτων",
 	"Enter description": "Εισάγετε την περιγραφή",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Εισάγετε το Github Raw URL",
 	"Enter Google PSE API Key": "Εισάγετε το Κλειδί API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Η γνώση διαγράφηκε με επιτυχία.",
 	"Knowledge reset successfully.": "Η γνώση επαναφέρθηκε με επιτυχία.",
 	"Knowledge updated successfully": "Η γνώση ενημερώθηκε με επιτυχία",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Ετικέτα",
 	"Landing Page Mode": "Λειτουργία Σελίδας Άφιξης",
 	"Language": "Γλώσσα",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Αφήστε κενό για να συμπεριλάβετε όλα τα μοντέλα από το endpoint \"{{URL}}/models\"",
 	"Leave empty to include all models or select specific models": "Αφήστε κενό για να χρησιμοποιήσετε όλα τα μοντέλα ή επιλέξτε συγκεκριμένα μοντέλα",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Αφήστε κενό για να χρησιμοποιήσετε την προεπιλεγμένη προτροπή, ή εισάγετε μια προσαρμοσμένη προτροπή",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Φως",
 	"Listening...": "Ακούγεται...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Τοπικά Μοντέλα",
 	"Lost": "Χαμένος",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Δημιουργήθηκε από την Κοινότητα OpenWebUI",
+	"Made by Open WebUI Community": "Δημιουργήθηκε από την Κοινότητα OpenWebUI",
 	"Make sure to enclose them with": "Βεβαιωθείτε ότι τα περικλείετε με",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Βεβαιωθείτε ότι εξάγετε ένα αρχείο workflow.json ως μορφή API από το ComfyUI.",
 	"Manage": "Διαχείριση",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Ανάγνωση Φωναχτά",
 	"Reasoning Effort": "",
 	"Record voice": "Εγγραφή φωνής",
-	"Redirecting you to OpenWebUI Community": "Μετακατεύθυνση στην Κοινότητα OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Μετακατεύθυνση στην Κοινότητα 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. (Default: 40)": "Μειώνει την πιθανότητα δημιουργίας ανοησιών. Μια υψηλότερη τιμή (π.χ. 100) θα δώσει πιο ποικίλες απαντήσεις, ενώ μια χαμηλότερη τιμή (π.χ. 10) θα δημιουργήσει πιο συντηρητικές απαντήσεις. (Προεπιλογή: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Αναφέρεστε στον εαυτό σας ως \"User\" (π.χ., \"User μαθαίνει Ισπανικά\")",
 	"References from": "Αναφορές από",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Οι Ρυθμίσεις αποθηκεύτηκαν με επιτυχία!",
 	"Share": "Κοινή Χρήση",
 	"Share Chat": "Κοινή Χρήση Συνομιλίας",
-	"Share to OpenWebUI Community": "Κοινή Χρήση στην Κοινότητα OpenWebUI",
+	"Share to Open WebUI Community": "Κοινή Χρήση στην Κοινότητα OpenWebUI",
 	"Show": "Εμφάνιση",
 	"Show \"What's New\" modal on login": "Εμφάνιση του παράθυρου \"Τι νέο υπάρχει\" κατά την είσοδο",
 	"Show Admin Details in Account Pending Overlay": "Εμφάνιση Λεπτομερειών Διαχειριστή στο Υπέρθεση Εκκρεμής Λογαριασμού",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Αυτό θα επαναφέρει τη βάση γνώσης και θα συγχρονίσει όλα τα αρχεία. Θέλετε να συνεχίσετε;",
 	"Thorough explanation": "Λεπτομερής εξήγηση",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Απαιτείται το URL διακομιστή Tika.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/en-GB/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "",
 	"Click here to select a csv file.": "",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "",
+	"Domain Filter List": "",
 	"Don't have an account?": "",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "",
 	"Enter Chunk Size": "",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "",
 	"Enter Google PSE API Key": "",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "",
-	"Made by OpenWebUI Community": "",
+	"Made by Open WebUI Community": "",
 	"Make sure to enclose them with": "",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "",
 	"Reasoning Effort": "",
 	"Record voice": "",
-	"Redirecting you to OpenWebUI Community": "",
+	"Redirecting you to Open WebUI Community": "",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "",
 	"Share": "",
 	"Share Chat": "",
-	"Share to OpenWebUI Community": "",
+	"Share to Open WebUI Community": "",
 	"Show": "",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/en-US/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "",
 	"Click here to select a csv file.": "",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "",
+	"Domain Filter List": "",
 	"Don't have an account?": "",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "",
 	"Enter Chunk Size": "",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "",
 	"Enter Google PSE API Key": "",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "",
-	"Made by OpenWebUI Community": "",
+	"Made by Open WebUI Community": "",
 	"Make sure to enclose them with": "",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "",
 	"Reasoning Effort": "",
 	"Record voice": "",
-	"Redirecting you to OpenWebUI Community": "",
+	"Redirecting you to Open WebUI Community": "",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "",
 	"Share": "",
 	"Share Chat": "",
-	"Share to OpenWebUI Community": "",
+	"Share to Open WebUI Community": "",
 	"Show": "",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

File diff suppressed because it is too large
+ 307 - 301
src/lib/i18n/locales/es-ES/translation.json


+ 10 - 3
src/lib/i18n/locales/eu-ES/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klikatu hemen",
 	"Click here to download user import template file.": "Klikatu hemen erabiltzaileen inportazio txantiloia deskargatzeko.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klikatu hemen faster-whisper-i buruz gehiago ikasteko eta eredu erabilgarriak ikusteko.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klikatu hemen hautatzeko",
 	"Click here to select a csv file.": "Klikatu hemen csv fitxategi bat hautatzeko.",
 	"Click here to select a py file.": "Klikatu hemen py fitxategi bat hautatzeko.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentazioa",
 	"Documents": "Dokumentuak",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ez du kanpo konexiorik egiten, eta zure datuak modu seguruan mantentzen dira zure zerbitzari lokalean.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Ez duzu konturik?",
 	"don't install random functions from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko funtzioak.",
 	"don't install random tools from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko tresnak.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Sartu Zatien Gainjartzea (chunk overlap)",
 	"Enter Chunk Size": "Sartu Zati Tamaina",
 	"Enter description": "Sartu deskribapena",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Sartu Github Raw URLa",
 	"Enter Google PSE API Key": "Sartu Google PSE API Gakoa",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Ezagutza ongi ezabatu da.",
 	"Knowledge reset successfully.": "Ezagutza ongi berrezarri da.",
 	"Knowledge updated successfully": "Ezagutza ongi eguneratu da.",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Etiketa",
 	"Landing Page Mode": "Hasiera Orriaren Modua",
 	"Language": "Hizkuntza",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Utzi hutsik \"{{URL}}/models\" endpointuko eredu guztiak sartzeko",
 	"Leave empty to include all models or select specific models": "Utzi hutsik eredu guztiak sartzeko edo hautatu eredu zehatzak",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Utzi hutsik prompt lehenetsia erabiltzeko, edo sartu prompt pertsonalizatu bat",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Argia",
 	"Listening...": "Entzuten...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Modelo lokalak",
 	"Lost": "Galduta",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "OpenWebUI Komunitateak egina",
+	"Made by Open WebUI Community": "OpenWebUI Komunitateak egina",
 	"Make sure to enclose them with": "Ziurtatu hauek gehitzen dituzula",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Ziurtatu workflow.json fitxategia API formatu gisa esportatzen duzula ComfyUI-tik.",
 	"Manage": "Kudeatu",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Irakurri ozen",
 	"Reasoning Effort": "",
 	"Record voice": "Grabatu ahotsa",
-	"Redirecting you to OpenWebUI Community": "OpenWebUI Komunitatera berbideratzen",
+	"Redirecting you to Open WebUI Community": "OpenWebUI Komunitatera berbideratzen",
 	"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. (Default: 40)": "Zentzugabekeriak sortzeko probabilitatea murrizten du. Balio altuago batek (adib. 100) erantzun anitzagoak emango ditu, balio baxuago batek (adib. 10) kontserbadoreagoa izango den bitartean. (Lehenetsia: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Egin erreferentzia zure buruari \"Erabiltzaile\" gisa (adib., \"Erabiltzailea gaztelania ikasten ari da\")",
 	"References from": "Erreferentziak hemendik",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Ezarpenak ongi gorde dira!",
 	"Share": "Partekatu",
 	"Share Chat": "Partekatu txata",
-	"Share to OpenWebUI Community": "Partekatu OpenWebUI komunitatearekin",
+	"Share to Open WebUI Community": "Partekatu OpenWebUI komunitatearekin",
 	"Show": "Erakutsi",
 	"Show \"What's New\" modal on login": "Erakutsi \"Berritasunak\" modala saioa hastean",
 	"Show Admin Details in Account Pending Overlay": "Erakutsi administratzaile xehetasunak kontu zain geruzan",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Honek ezagutza-basea berrezarri eta fitxategi guztiak sinkronizatuko ditu. Jarraitu nahi duzu?",
 	"Thorough explanation": "Azalpen sakona",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika zerbitzariaren URLa beharrezkoa da.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/fa-IR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "برای کمک اینجا را کلیک کنید.",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "اسناد",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "هیچ اتصال خارجی ایجاد نمی کند و داده های شما به طور ایمن در سرور میزبان محلی شما باقی می ماند.",
+	"Domain Filter List": "",
 	"Don't have an account?": "حساب کاربری ندارید؟",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "مقدار Chunk Overlap را وارد کنید",
 	"Enter Chunk Size": "مقدار Chunk Size را وارد کنید",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "ادرس Github Raw را وارد کنید",
 	"Enter Google PSE API Key": "کلید API گوگل PSE را وارد کنید",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "زبان",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "روشن",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "ساخته شده توسط OpenWebUI Community",
+	"Made by Open WebUI Community": "ساخته شده توسط OpenWebUI Community",
 	"Make sure to enclose them with": "مطمئن شوید که آنها را با این محصور کنید:",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "خواندن به صورت صوتی",
 	"Reasoning Effort": "",
 	"Record voice": "ضبط صدا",
-	"Redirecting you to OpenWebUI Community": "در حال هدایت به OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "در حال هدایت به OpenWebUI Community",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "تنظیمات با موفقیت ذخیره شد!",
 	"Share": "اشتراک\u200cگذاری",
 	"Share Chat": "اشتراک\u200cگذاری چت",
-	"Share to OpenWebUI Community": "اشتراک گذاری با OpenWebUI Community",
+	"Share to Open WebUI Community": "اشتراک گذاری با OpenWebUI Community",
 	"Show": "نمایش",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "توضیح کامل",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/fi-FI/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klikkaa tästä",
 	"Click here to download user import template file.": "Lataa käyttäjien tuontipohjatiedosto klikkaamalla tästä.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klikkaa tästä oppiaksesi lisää faster-whisperista ja nähdäksesi saatavilla olevat mallit.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klikkaa tästä valitaksesi",
 	"Click here to select a csv file.": "Klikkaa tästä valitaksesi CSV-tiedosto.",
 	"Click here to select a py file.": "Klikkaa tästä valitaksesi py-tiedosto.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentaatio",
 	"Documents": "Asiakirjat",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ei tee ulkoisia yhteyksiä, ja tietosi pysyvät turvallisesti paikallisesti isännöidyllä palvelimellasi.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Eikö sinulla ole tiliä?",
 	"don't install random functions from sources you don't trust.": "älä asenna satunnaisia toimintoja lähteistä, joihin et luota.",
 	"don't install random tools from sources you don't trust.": "älä asenna satunnaisia työkaluja lähteistä, joihin et luota.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Syötä osien päällekkäisyys",
 	"Enter Chunk Size": "Syötä osien koko",
 	"Enter description": "Kirjoita kuvaus",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Kirjoita Github Raw -URL-osoite",
 	"Enter Google PSE API Key": "Kirjoita Google PSE API -avain",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Tietokanta poistettu onnistuneesti.",
 	"Knowledge reset successfully.": "Tietokanta nollattu onnistuneesti.",
 	"Knowledge updated successfully": "Tietokanta päivitetty onnistuneesti",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Tunniste",
 	"Landing Page Mode": "Etusivun tila",
 	"Language": "Kieli",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit \"{{URL}}/models\" -päätepistestä",
 	"Leave empty to include all models or select specific models": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit tai valitse tietyt mallit",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Vaalea",
 	"Listening...": "Kuuntelee...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Paikalliset mallit",
 	"Lost": "Mennyt",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Tehnyt OpenWebUI-yhteisö",
+	"Made by Open WebUI Community": "Tehnyt OpenWebUI-yhteisö",
 	"Make sure to enclose them with": "Varmista, että suljet ne",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Muista viedä workflow.json-tiedosto API-muodossa ComfyUI:sta.",
 	"Manage": "Hallitse",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Lue ääneen",
 	"Reasoning Effort": "",
 	"Record voice": "Nauhoita ääni",
-	"Redirecting you to OpenWebUI Community": "Ohjataan sinut OpenWebUI-yhteisöön",
+	"Redirecting you to Open WebUI Community": "Ohjataan sinut OpenWebUI-yhteisöön",
 	"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. (Default: 40)": "Vähentää merkityksetöntä sisältöä tuottavan todennäköisyyttä. Korkeampi arvo (esim. 100) antaa monipuolisempia vastauksia, kun taas alhaisempi arvo (esim. 10) on konservatiivisempi. (Oletus: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Viittaa itseen \"Käyttäjänä\" (esim. \"Käyttäjä opiskelee espanjaa\")",
 	"References from": "Viitteet lähteistä",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Asetukset tallennettu onnistuneesti!",
 	"Share": "Jaa",
 	"Share Chat": "Jaa keskustelu",
-	"Share to OpenWebUI Community": "Jaa OpenWebUI-yhteisöön",
+	"Share to Open WebUI Community": "Jaa OpenWebUI-yhteisöön",
 	"Show": "Näytä",
 	"Show \"What's New\" modal on login": "Näytä \"Mitä uutta\" -modaali kirjautumisen yhteydessä",
 	"Show Admin Details in Account Pending Overlay": "Näytä ylläpitäjän tiedot odottavan tilin päällä",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Tämä nollaa tietokannan ja synkronoi kaikki tiedostot. Haluatko jatkaa?",
 	"Thorough explanation": "Perusteellinen selitys",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika Server URL vaaditaan.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/fr-CA/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Cliquez ici pour",
 	"Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation utilisateur.",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Cliquez ici pour sélectionner",
 	"Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier CSV.",
 	"Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentation",
 	"Documents": "Documents",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ne fait aucune connexion externe et garde vos données en sécurité sur votre serveur local.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Entrez le chevauchement de chunk",
 	"Enter Chunk Size": "Entrez la taille de bloc",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Entrez l'URL brute de GitHub",
 	"Enter Google PSE API Key": "Entrez la clé API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Langue",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Lumineux",
 	"Listening...": "En train d'écouter...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Modèles locaux",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Réalisé par la communauté OpenWebUI",
+	"Made by Open WebUI Community": "Réalisé par la communauté OpenWebUI",
 	"Make sure to enclose them with": "Assurez-vous de les inclure dans",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Gérer",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Lire à haute voix",
 	"Reasoning Effort": "",
 	"Record voice": "Enregistrer la voix",
-	"Redirecting you to OpenWebUI Community": "Redirection vers la communauté OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Redirection vers la communauté 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Désignez-vous comme « Utilisateur » (par ex. « L'utilisateur apprend l'espagnol »)",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Paramètres enregistrés avec succès !",
 	"Share": "Partager",
 	"Share Chat": "Partage de conversation",
-	"Share to OpenWebUI Community": "Partager avec la communauté OpenWebUI",
+	"Share to Open WebUI Community": "Partager avec la communauté OpenWebUI",
 	"Show": "Montrer",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Afficher les détails de l'administrateur dans la superposition en attente du compte",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Explication approfondie",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "URL du serveur Tika requise.",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/fr-FR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Cliquez ici pour",
 	"Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation des utilisateurs.",
 	"Click here to learn more about faster-whisper and see the available models.": "Cliquez ici pour en savoir plus sur faster-whisper et voir les modèles disponibles.",
+	"Click here to see available models.": "",
 	"Click here to select": "Cliquez ici pour sélectionner",
 	"Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier .csv.",
 	"Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentation",
 	"Documents": "Documents",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "n'établit aucune connexion externe et garde vos données en sécurité sur votre serveur local.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"don't install random functions from sources you don't trust.": "n'installez pas de fonctions aléatoires provenant de sources auxquelles vous ne faites pas confiance.",
 	"don't install random tools from sources you don't trust.": "n'installez pas d'outils aléatoires provenant de sources auxquelles vous ne faites pas confiance.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Entrez le chevauchement des chunks",
 	"Enter Chunk Size": "Entrez la taille des chunks",
 	"Enter description": "Entrez la description",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Entrez l'URL brute de GitHub",
 	"Enter Google PSE API Key": "Entrez la clé API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Connaissance supprimée avec succès.",
 	"Knowledge reset successfully.": "Connaissance réinitialisée avec succès.",
 	"Knowledge updated successfully": "Connaissance mise à jour avec succès",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Étiquette",
 	"Landing Page Mode": "Mode de la page d'accueil",
 	"Language": "Langue",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laissez vide pour inclure tous les modèles depuis le point de terminaison \"{{URL}}/models\"",
 	"Leave empty to include all models or select specific models": "Laissez vide pour inclure tous les modèles ou sélectionnez des modèles spécifiques",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Laissez vide pour utiliser le prompt par défaut, ou entrez un prompt personnalisé",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Clair",
 	"Listening...": "Écoute en cours...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "Modèles locaux",
 	"Lost": "Perdu",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Réalisé par la communauté OpenWebUI",
+	"Made by Open WebUI Community": "Réalisé par la communauté OpenWebUI",
 	"Make sure to enclose them with": "Assurez-vous de les inclure dans",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Veillez à exporter un fichier workflow.json au format API depuis ComfyUI.",
 	"Manage": "Gérer",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Lire à haute voix",
 	"Reasoning Effort": "Effort de raisonnement",
 	"Record voice": "Enregistrer la voix",
-	"Redirecting you to OpenWebUI Community": "Redirection vers la communauté OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Redirection vers la communauté 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. (Default: 40)": "Réduit la probabilité de générer des non-sens. Une valeur plus élevée (par exemple 100) donnera des réponses plus diversifiées, tandis qu'une valeur plus basse (par exemple 10) sera plus conservatrice. (Par défaut : 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Désignez-vous comme « Utilisateur » (par ex. « L'utilisateur apprend l'espagnol »)",
 	"References from": "Références de",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Paramètres enregistrés avec succès !",
 	"Share": "Partager",
 	"Share Chat": "Partage de conversation",
-	"Share to OpenWebUI Community": "Partager avec la communauté OpenWebUI",
+	"Share to Open WebUI Community": "Partager avec la communauté OpenWebUI",
 	"Show": "Afficher",
 	"Show \"What's New\" modal on login": "Afficher la fenêtre modale \"Quoi de neuf\" lors de la connexion",
 	"Show Admin Details in Account Pending Overlay": "Afficher les coordonnées de l'administrateur aux comptes en attente",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Cela réinitialisera la base de connaissances et synchronisera tous les fichiers. Souhaitez-vous continuer ?",
 	"Thorough explanation": "Explication approfondie",
 	"Thought for {{DURATION}}": "Réflexion de {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "URL du serveur Tika requise.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/he-IL/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "לחץ כאן כדי",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "מסמכים",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "לא מבצע חיבורים חיצוניים, והנתונים שלך נשמרים באופן מאובטח בשרת המקומי שלך.",
+	"Domain Filter List": "",
 	"Don't have an account?": "אין לך חשבון?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "הזן חפיפת נתונים",
 	"Enter Chunk Size": "הזן גודל נתונים",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "הזן כתובת URL של Github Raw",
 	"Enter Google PSE API Key": "הזן מפתח API של Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "שפה",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "בהיר",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "נוצר על ידי קהילת OpenWebUI",
+	"Made by Open WebUI Community": "נוצר על ידי קהילת OpenWebUI",
 	"Make sure to enclose them with": "ודא להקיף אותם עם",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "קרא בקול",
 	"Reasoning Effort": "",
 	"Record voice": "הקלט קול",
-	"Redirecting you to OpenWebUI Community": "מפנה אותך לקהילת OpenWebUI",
+	"Redirecting you to Open WebUI Community": "מפנה אותך לקהילת 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "ההגדרות נשמרו בהצלחה!",
 	"Share": "שתף",
 	"Share Chat": "שתף צ'אט",
-	"Share to OpenWebUI Community": "שתף לקהילת OpenWebUI",
+	"Share to Open WebUI Community": "שתף לקהילת OpenWebUI",
 	"Show": "הצג",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "תיאור מפורט",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/hi-IN/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "यहां क्लिक करें",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "चयन करने के लिए यहां क्लिक करें।",
 	"Click here to select a csv file.": "सीएसवी फ़ाइल का चयन करने के लिए यहां क्लिक करें।",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "दस्तावेज़",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "कोई बाहरी कनेक्शन नहीं बनाता है, और आपका डेटा आपके स्थानीय रूप से होस्ट किए गए सर्वर पर सुरक्षित रूप से रहता है।",
+	"Domain Filter List": "",
 	"Don't have an account?": "कोई खाता नहीं है?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "चंक ओवरलैप दर्ज करें",
 	"Enter Chunk Size": "खंड आकार दर्ज करें",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Github Raw URL दर्ज करें",
 	"Enter Google PSE API Key": "Google PSE API कुंजी दर्ज करें",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "भाषा",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "सुन",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "OpenWebUI समुदाय द्वारा निर्मित",
+	"Made by Open WebUI Community": "OpenWebUI समुदाय द्वारा निर्मित",
 	"Make sure to enclose them with": "उन्हें संलग्न करना सुनिश्चित करें",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "जोर से पढ़ें",
 	"Reasoning Effort": "",
 	"Record voice": "आवाज रिकॉर्ड करना",
-	"Redirecting you to OpenWebUI Community": "आपको OpenWebUI समुदाय पर पुनर्निर्देशित किया जा रहा है",
+	"Redirecting you to Open WebUI Community": "आपको 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "सेटिंग्स सफलतापूर्वक सहेजी गईं!",
 	"Share": "साझा करें",
 	"Share Chat": "चैट साझा करें",
-	"Share to OpenWebUI Community": "OpenWebUI समुदाय में साझा करें",
+	"Share to Open WebUI Community": "OpenWebUI समुदाय में साझा करें",
 	"Show": "दिखाओ",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "विस्तृत व्याख्या",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/hr-HR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Kliknite ovdje za",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Kliknite ovdje za odabir",
 	"Click here to select a csv file.": "Kliknite ovdje da odaberete csv datoteku.",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentacija",
 	"Documents": "Dokumenti",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ne uspostavlja vanjske veze, a vaši podaci ostaju sigurno na vašem lokalno hostiranom poslužitelju.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nemate račun?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Unesite preklapanje dijelova",
 	"Enter Chunk Size": "Unesite veličinu dijela",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Unesite Github sirovi URL",
 	"Enter Google PSE API Key": "Unesite Google PSE API ključ",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Jezik",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Svijetlo",
 	"Listening...": "Slušam...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokalni modeli",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Izradio OpenWebUI Community",
+	"Made by Open WebUI Community": "Izradio OpenWebUI Community",
 	"Make sure to enclose them with": "Provjerite da ih zatvorite s",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Upravljaj",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Čitaj naglas",
 	"Reasoning Effort": "",
 	"Record voice": "Snimanje glasa",
-	"Redirecting you to OpenWebUI Community": "Preusmjeravanje na OpenWebUI zajednicu",
+	"Redirecting you to Open WebUI Community": "Preusmjeravanje na OpenWebUI zajednicu",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Nazivajte se \"Korisnik\" (npr. \"Korisnik uči španjolski\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Postavke su uspješno spremljene!",
 	"Share": "Podijeli",
 	"Share Chat": "Podijeli razgovor",
-	"Share to OpenWebUI Community": "Podijeli u OpenWebUI zajednici",
+	"Share to Open WebUI Community": "Podijeli u OpenWebUI zajednici",
 	"Show": "Pokaži",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Detaljno objašnjenje",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/hu-HU/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Kattints ide",
 	"Click here to download user import template file.": "Kattints ide a felhasználó importálási sablon letöltéséhez.",
 	"Click here to learn more about faster-whisper and see the available models.": "Kattints ide, hogy többet tudj meg a faster-whisperről és lásd az elérhető modelleket.",
+	"Click here to see available models.": "",
 	"Click here to select": "Kattints ide a kiválasztáshoz",
 	"Click here to select a csv file.": "Kattints ide egy CSV fájl kiválasztásához.",
 	"Click here to select a py file.": "Kattints ide egy py fájl kiválasztásához.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentáció",
 	"Documents": "Dokumentumok",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "nem létesít külső kapcsolatokat, és az adataid biztonságban maradnak a helyileg hosztolt szervereden.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nincs még fiókod?",
 	"don't install random functions from sources you don't trust.": "ne telepíts véletlenszerű funkciókat olyan forrásokból, amelyekben nem bízol.",
 	"don't install random tools from sources you don't trust.": "ne telepíts véletlenszerű eszközöket olyan forrásokból, amelyekben nem bízol.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Add meg a darab átfedést",
 	"Enter Chunk Size": "Add meg a darab méretet",
 	"Enter description": "Add meg a leírást",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Add meg a Github Raw URL-t",
 	"Enter Google PSE API Key": "Add meg a Google PSE API kulcsot",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Tudásbázis sikeresen törölve.",
 	"Knowledge reset successfully.": "Tudásbázis sikeresen visszaállítva.",
 	"Knowledge updated successfully": "Tudásbázis sikeresen frissítve",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Kezdőlap mód",
 	"Language": "Nyelv",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "Hagyja üresen az összes modell használatához, vagy válasszon ki konkrét modelleket",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Hagyja üresen az alapértelmezett prompt használatához, vagy adjon meg egyéni promptot",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Világos",
 	"Listening...": "Hallgatás...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Helyi modellek",
 	"Lost": "Elveszett",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Az OpenWebUI közösség által készítve",
+	"Made by Open WebUI Community": "Az OpenWebUI közösség által készítve",
 	"Make sure to enclose them with": "Győződjön meg róla, hogy körülveszi őket",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Győződjön meg róla, hogy exportál egy workflow.json fájlt API formátumban a ComfyUI-ból.",
 	"Manage": "Kezelés",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Felolvasás",
 	"Reasoning Effort": "",
 	"Record voice": "Hang rögzítése",
-	"Redirecting you to OpenWebUI Community": "Átirányítás az OpenWebUI közösséghez",
+	"Redirecting you to Open WebUI Community": "Átirányítás az OpenWebUI közösséghez",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Hivatkozzon magára \"Felhasználó\"-ként (pl. \"A Felhasználó spanyolul tanul\")",
 	"References from": "Hivatkozások innen",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Beállítások sikeresen mentve!",
 	"Share": "Megosztás",
 	"Share Chat": "Beszélgetés megosztása",
-	"Share to OpenWebUI Community": "Megosztás az OpenWebUI közösséggel",
+	"Share to Open WebUI Community": "Megosztás az OpenWebUI közösséggel",
 	"Show": "Mutat",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Admin részletek megjelenítése a függő fiók átfedésben",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Ez visszaállítja a tudásbázist és szinkronizálja az összes fájlt. Szeretné folytatni?",
 	"Thorough explanation": "Alapos magyarázat",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika szerver URL szükséges.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/id-ID/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klik di sini untuk",
 	"Click here to download user import template file.": "Klik di sini untuk mengunduh file templat impor pengguna.",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Klik di sini untuk memilih",
 	"Click here to select a csv file.": "Klik di sini untuk memilih file csv.",
 	"Click here to select a py file.": "Klik di sini untuk memilih file py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentasi",
 	"Documents": "Dokumen",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat koneksi eksternal apa pun, dan data Anda tetap aman di server yang dihosting secara lokal.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Tidak memiliki akun?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Masukkan Tumpang Tindih Chunk",
 	"Enter Chunk Size": "Masukkan Ukuran Potongan",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Masukkan URL Mentah Github",
 	"Enter Google PSE API Key": "Masukkan Kunci API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Bahasa",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Cahaya",
 	"Listening...": "Mendengarkan",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Model Lokal",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Dibuat oleh Komunitas OpenWebUI",
+	"Made by Open WebUI Community": "Dibuat oleh Komunitas OpenWebUI",
 	"Make sure to enclose them with": "Pastikan untuk melampirkannya dengan",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Mengelola",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Baca dengan Keras",
 	"Reasoning Effort": "",
 	"Record voice": "Rekam suara",
-	"Redirecting you to OpenWebUI Community": "Mengarahkan Anda ke Komunitas OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Mengarahkan Anda ke Komunitas 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Merujuk diri Anda sebagai \"Pengguna\" (misalnya, \"Pengguna sedang belajar bahasa Spanyol\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Pengaturan berhasil disimpan!",
 	"Share": "Berbagi",
 	"Share Chat": "Bagikan Obrolan",
-	"Share to OpenWebUI Community": "Bagikan ke Komunitas OpenWebUI",
+	"Share to Open WebUI Community": "Bagikan ke Komunitas OpenWebUI",
 	"Show": "Tampilkan",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Tampilkan Detail Admin di Hamparan Akun Tertunda",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Penjelasan menyeluruh",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ie-GA/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Cliceáil anseo chun",
 	"Click here to download user import template file.": "Cliceáil anseo chun an comhad iompórtála úsáideora a íoslódáil.",
 	"Click here to learn more about faster-whisper and see the available models.": "Cliceáil anseo chun níos mó a fhoghlaim faoi cogar níos tapúla agus na múnlaí atá ar fáil a fheiceáil.",
+	"Click here to see available models.": "",
 	"Click here to select": "Cliceáil anseo chun roghnú",
 	"Click here to select a csv file.": "Cliceáil anseo chun comhad csv a roghnú.",
 	"Click here to select a py file.": "Cliceáil anseo chun comhad py a roghnú.",
@@ -290,6 +291,7 @@
 	"Documentation": "Doiciméadú",
 	"Documents": "Doiciméid",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ní dhéanann sé aon naisc sheachtracha, agus fanann do chuid sonraí go slán ar do fhreastalaí a óstáiltear go háitiúil.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Níl cuntas agat?",
 	"don't install random functions from sources you don't trust.": "ná suiteáil feidhmeanna randamacha ó fhoinsí nach bhfuil muinín agat.",
 	"don't install random tools from sources you don't trust.": "ná suiteáil uirlisí randamacha ó fhoinsí nach bhfuil muinín agat.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Cuir isteach Chunk Forluí",
 	"Enter Chunk Size": "Cuir isteach Méid an Chunc",
 	"Enter description": "Iontráil cur síos",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "Cuir isteach Eochair Exa API",
 	"Enter Github Raw URL": "Cuir isteach URL Github Raw",
 	"Enter Google PSE API Key": "Cuir isteach Eochair API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "D'éirigh leis an eolas a scriosadh.",
 	"Knowledge reset successfully.": "D'éirigh le hathshocrú eolais.",
 	"Knowledge updated successfully": "D'éirigh leis an eolas a nuashonrú",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Lipéad",
 	"Landing Page Mode": "Mód Leathanach Tuirlingthe",
 	"Language": "Teanga",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Fág folamh chun gach múnla ón gcríochphointe \"{{URL}}/models\" a chur san áireamh",
 	"Leave empty to include all models or select specific models": "Fág folamh chun gach múnla a chur san áireamh nó roghnaigh múnlaí sonracha",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Fág folamh chun an leid réamhshocraithe a úsáid, nó cuir isteach leid saincheaptha",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Solas",
 	"Listening...": "Éisteacht...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "Múnlaí Áitiúla",
 	"Lost": "Cailleadh",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Déanta ag OpenWebUI Community",
+	"Made by Open WebUI Community": "Déanta ag OpenWebUI Community",
 	"Make sure to enclose them with": "Déan cinnte iad a cheangal le",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Déan cinnte comhad workflow.json a onnmhairiú mar fhormáid API ó ComfyUI.",
 	"Manage": "Bainistiú",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Léigh Ard",
 	"Reasoning Effort": "Iarracht Réasúnúcháin",
 	"Record voice": "Taifead guth",
-	"Redirecting you to OpenWebUI Community": "Tú a atreorú chuig OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "Tú a atreorú chuig OpenWebUI Community",
 	"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. (Default: 40)": "Laghdaíonn sé an dóchúlacht go giniúint nonsense. Tabharfaidh luach níos airde (m.sh. 100) freagraí níos éagsúla, agus beidh luach níos ísle (m.sh. 10) níos coimeádaí. (Réamhshocrú: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Tagairt duit féin mar \"Úsáideoir\" (m.sh., \"Tá an úsáideoir ag foghlaim Spáinnis\")",
 	"References from": "Tagairtí ó",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Socruithe sábhálta go rathúil!",
 	"Share": "Comhroinn",
 	"Share Chat": "Comhroinn Comhrá",
-	"Share to OpenWebUI Community": "Comhroinn le Pobal OpenWebUI",
+	"Share to Open WebUI Community": "Comhroinn le Pobal OpenWebUI",
 	"Show": "Taispeáin",
 	"Show \"What's New\" modal on login": "Taispeáin módúil \"Cad atá Nua\" ar logáil isteach",
 	"Show Admin Details in Account Pending Overlay": "Taispeáin Sonraí Riaracháin sa Chuntas ar Feitheamh Forleagan",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Déanfaidh sé seo an bonn eolais a athshocrú agus gach comhad a shioncronú. Ar mhaith leat leanúint ar aghaidh?",
 	"Thorough explanation": "Míniú críochnúil",
 	"Thought for {{DURATION}}": "Smaoineamh ar {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Teastaíonn URL Freastalaí Tika.",
 	"Tiktoken": "Tictoken",

+ 10 - 3
src/lib/i18n/locales/it-IT/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Clicca qui per",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Clicca qui per selezionare",
 	"Click here to select a csv file.": "Clicca qui per selezionare un file csv.",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "Documenti",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "non effettua connessioni esterne e i tuoi dati rimangono al sicuro sul tuo server ospitato localmente.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Non hai un account?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Inserisci la sovrapposizione chunk",
 	"Enter Chunk Size": "Inserisci la dimensione chunk",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Immettere l'URL grezzo di Github",
 	"Enter Google PSE API Key": "Inserisci la chiave API PSE di Google",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Lingua",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Chiaro",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Realizzato dalla comunità OpenWebUI",
+	"Made by Open WebUI Community": "Realizzato dalla comunità OpenWebUI",
 	"Make sure to enclose them with": "Assicurati di racchiuderli con",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Leggi ad alta voce",
 	"Reasoning Effort": "",
 	"Record voice": "Registra voce",
-	"Redirecting you to OpenWebUI Community": "Reindirizzamento alla comunità OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Reindirizzamento alla comunità 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Impostazioni salvate con successo!",
 	"Share": "Condividi",
 	"Share Chat": "Condividi chat",
-	"Share to OpenWebUI Community": "Condividi con la comunità OpenWebUI",
+	"Share to Open WebUI Community": "Condividi con la comunità OpenWebUI",
 	"Show": "Mostra",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Spiegazione dettagliata",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ja-JP/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "ここをクリックして",
 	"Click here to download user import template file.": "ユーザーテンプレートをインポートするにはここをクリックしてください。",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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スクリプトファイルを選択するにはここをクリックしてください。",
@@ -290,6 +291,7 @@
 	"Documentation": "ドキュメント",
 	"Documents": "ドキュメント",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。",
+	"Domain Filter List": "",
 	"Don't have an account?": "アカウントをお持ちではありませんか?",
 	"don't install random functions from sources you don't trust.": "信頼出来ないソースからランダムFunctionをインストールしないでください。",
 	"don't install random tools from sources you don't trust.": "信頼出来ないソースからランダムツールをインストールしないでください。",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "チャンクオーバーラップを入力してください",
 	"Enter Chunk Size": "チャンクサイズを入力してください",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Github Raw URLを入力",
 	"Enter Google PSE API Key": "Google PSE APIキーの入力",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "ナレッジベースの削除に成功しました",
 	"Knowledge reset successfully.": "ナレッジベースのリセットに成功しました",
 	"Knowledge updated successfully": "ナレッジベースのアップデートに成功しました",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "ランディングページモード",
 	"Language": "言語",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "カスタムプロンプトを入力。空欄ならデフォルトプロンプト",
+	"Leave model field empty to use the default model.": "",
 	"Light": "ライト",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "ローカルモデル",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "OpenWebUI コミュニティによって作成",
+	"Made by Open WebUI Community": "OpenWebUI コミュニティによって作成",
 	"Make sure to enclose them with": "必ず次で囲んでください",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "管理",
@@ -754,7 +760,7 @@
 	"Read Aloud": "読み上げ",
 	"Reasoning Effort": "",
 	"Record voice": "音声を録音",
-	"Redirecting you to OpenWebUI Community": "OpenWebUI コミュニティにリダイレクトしています",
+	"Redirecting you to Open WebUI Community": "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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "設定が正常に保存されました!",
 	"Share": "共有",
 	"Share Chat": "チャットを共有",
-	"Share to OpenWebUI Community": "OpenWebUI コミュニティに共有",
+	"Share to Open WebUI Community": "OpenWebUI コミュニティに共有",
 	"Show": "表示",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "詳細な説明",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ka-GE/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "დააკლიკე აქ",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "ასარჩევად, დააკლიკე აქ",
 	"Click here to select a csv file.": "ასარჩევად, დააკლიკე აქ",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "დოკუმენტები",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "არ ამყარებს გარე კავშირებს და თქვენი მონაცემები უსაფრთხოდ რჩება თქვენს ადგილობრივ სერვერზე.",
+	"Domain Filter List": "",
 	"Don't have an account?": "არ გაქვს ანგარიში?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "შეიყვანეთ ნაწილის გადახურვა",
 	"Enter Chunk Size": "შეიყვანე ბლოკის ზომა",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "შეიყვანეთ Github Raw URL",
 	"Enter Google PSE API Key": "შეიყვანეთ Google PSE API გასაღები",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "ენა",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "მსუბუქი",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "დამზადებულია OpenWebUI საზოგადოების მიერ",
+	"Made by Open WebUI Community": "დამზადებულია OpenWebUI საზოგადოების მიერ",
 	"Make sure to enclose them with": "დარწმუნდით, რომ დაურთეთ ისინი",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "ხმის ჩაწერა",
 	"Reasoning Effort": "",
 	"Record voice": "ხმის ჩაწერა",
-	"Redirecting you to OpenWebUI Community": "გადამისამართდებით OpenWebUI საზოგადოებაში",
+	"Redirecting you to Open WebUI Community": "გადამისამართდებით 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "პარამეტრები წარმატებით განახლდა!",
 	"Share": "გაზიარება",
 	"Share Chat": "გაზიარება",
-	"Share to OpenWebUI Community": "გააზიარე OpenWebUI საზოგადოებაში ",
+	"Share to Open WebUI Community": "გააზიარე OpenWebUI საზოგადოებაში ",
 	"Show": "ჩვენება",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "ვრცლად აღწერა",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ko-KR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "여기를 클릭하면",
 	"Click here to download user import template file.": "사용자 삽입 템플렛 파일을 다운받으려면 여기를 클릭하세요",
 	"Click here to learn more about faster-whisper and see the available models.": "빠른 속삭임에 대해 배우거나 가능한 모델을 보려면 여기를 클릭하세요",
+	"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.": "py 파일을 선택하려면 여기를 클릭하세요.",
@@ -290,6 +291,7 @@
 	"Documentation": "문서 조사",
 	"Documents": "문서",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "외부와 어떠한 연결도 하지 않으며, 데이터는 로컬에서 호스팅되는 서버에 안전하게 유지됩니다.",
+	"Domain Filter List": "",
 	"Don't have an account?": "계정이 없으신가요?",
 	"don't install random functions from sources you don't trust.": "불분명한 출처를 가진 임의의 함수를 설치하지마세요",
 	"don't install random tools from sources you don't trust.": "불분명한 출처를 가진 임의의 도구를 설치하지마세요",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "청크 오버랩 입력",
 	"Enter Chunk Size": "청크 크기 입력",
 	"Enter description": "설명 입력",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Github Raw URL 입력",
 	"Enter Google PSE API Key": "Google PSE API 키 입력",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "성공적으로 지식 기반이 삭제되었습니다",
 	"Knowledge reset successfully.": "성공적으로 지식 기반이 초기화되었습니다",
 	"Knowledge updated successfully": "성공적으로 지식 기반이 업데이트되었습니다",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "랜딩페이지 모드",
 	"Language": "언어",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "특정 모델을 선택하거나 모든 모델을 포함하고 싶으면 빈칸으로 남겨두세요",
 	"Leave empty to use the default prompt, or enter a custom prompt": "기본 프롬프트를 사용하기 위해 빈칸으로 남겨두거나, 커스텀 프롬프트를 입력하세요",
+	"Leave model field empty to use the default model.": "",
 	"Light": "라이트",
 	"Listening...": "듣는 중...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "로컬 모델",
 	"Lost": "패배",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "OpenWebUI 커뮤니티에 의해 개발됨",
+	"Made by Open WebUI Community": "OpenWebUI 커뮤니티에 의해 개발됨",
 	"Make sure to enclose them with": "꼭 다음으로 감싸세요:",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "꼭 workflow.json 파일을 ComfyUI의 API 형식대로 내보내세요",
 	"Manage": "관리",
@@ -754,7 +760,7 @@
 	"Read Aloud": "읽어주기",
 	"Reasoning Effort": "",
 	"Record voice": "음성 녹음",
-	"Redirecting you to OpenWebUI Community": "OpenWebUI 커뮤니티로 리디렉션 중",
+	"Redirecting you to Open WebUI Community": "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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "스스로를 \"사용자\" 라고 지칭하세요. (예: \"사용자는 영어를 배우고 있습니다\")",
 	"References from": "출처",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "설정이 성공적으로 저장되었습니다!",
 	"Share": "공유",
 	"Share Chat": "채팅 공유",
-	"Share to OpenWebUI Community": "OpenWebUI 커뮤니티에 공유",
+	"Share to Open WebUI Community": "OpenWebUI 커뮤니티에 공유",
 	"Show": "보기",
 	"Show \"What's New\" modal on login": "로그인시 \"새로운 기능\" 모달 보기",
 	"Show Admin Details in Account Pending Overlay": "사용자용 계정 보류 설명창에, 관리자 상세 정보 노출",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "지식 기반과 모든 파일 연동을 초기화합니다. 계속 하시겠습니까?",
 	"Thorough explanation": "완전한 설명",
 	"Thought for {{DURATION}}": "{{DURATION}} 동안 생각함",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "티카(Tika)",
 	"Tika Server URL required.": "티카 서버 URL이 필요합니다",
 	"Tiktoken": "틱토큰 (Tiktoken)",

+ 10 - 3
src/lib/i18n/locales/lt-LT/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Paspauskite čia, kad:",
 	"Click here to download user import template file.": "Pasauskite čia norėdami sukurti naudotojo įkėlimo šablono rinkmeną",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Spauskite čia norėdami pasirinkti",
 	"Click here to select a csv file.": "Spauskite čia tam, kad pasirinkti csv failą",
 	"Click here to select a py file.": "Spauskite čia norėdami pasirinkti py failą",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentacija",
 	"Documents": "Dokumentai",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "neturi jokių išorinių ryšių ir duomenys lieka serveryje.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Neturite paskyros?",
 	"don't install random functions from sources you don't trust.": "neinstaliuokite funkcijų iš nepatikimų šaltinių",
 	"don't install random tools from sources you don't trust.": "neinstaliuokite įrankių iš nepatikimų šaltinių",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Įveskite blokų persidengimą",
 	"Enter Chunk Size": "Įveskite blokų dydį",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Įveskite GitHub Raw nuorodą",
 	"Enter Google PSE API Key": "Įveskite Google PSE API raktą",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Kalba",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Šviesus",
 	"Listening...": "Klausoma...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokalūs modeliai",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Sukurta OpenWebUI bendruomenės",
+	"Made by Open WebUI Community": "Sukurta OpenWebUI bendruomenės",
 	"Make sure to enclose them with": "Užtikrinktie, kad įtraukiate viduje:",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Tvarkyti",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Skaityti garsiai",
 	"Reasoning Effort": "",
 	"Record voice": "Įrašyti balsą",
-	"Redirecting you to OpenWebUI Community": "Perkeliam Jus į OpenWebUI bendruomenę",
+	"Redirecting you to Open WebUI Community": "Perkeliam Jus į OpenWebUI bendruomenę",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Vadinkite save Naudotoju (pvz. Naudotojas mokosi prancūzų kalbos)",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Parametrai sėkmingai išsaugoti!",
 	"Share": "Dalintis",
 	"Share Chat": "Dalintis pokalbiu",
-	"Share to OpenWebUI Community": "Dalintis su OpenWebUI bendruomene",
+	"Share to Open WebUI Community": "Dalintis su OpenWebUI bendruomene",
 	"Show": "Rodyti",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Rodyti administratoriaus duomenis laukiant paskyros patvirtinimo",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Platus paaiškinimas",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Reiklainga Tika serverio nuorodą",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ms-MY/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klik disini untuk",
 	"Click here to download user import template file.": "Klik disini untuk memuat turun fail templat import pengguna",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Klik disini untuk memilih",
 	"Click here to select a csv file.": "Klik disini untuk memilih fail csv",
 	"Click here to select a py file.": "Klik disini untuk memilih fail py",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentasi",
 	"Documents": "Dokumen",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat sebarang sambungan luaran, dan data anda kekal selamat pada pelayan yang dihoskan ditempat anda",
+	"Domain Filter List": "",
 	"Don't have an account?": "Anda tidak mempunyai akaun?",
 	"don't install random functions from sources you don't trust.": "jangan pasang mana-mana fungsi daripada sumber yang anda tidak percayai.",
 	"don't install random tools from sources you don't trust.": "jangan pasang mana-mana alat daripada sumber yang anda tidak percayai.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Masukkan Tindihan 'Chunk'",
 	"Enter Chunk Size": "Masukkan Saiz 'Chunk'",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Masukkan URL 'Github Raw'",
 	"Enter Google PSE API Key": "Masukkan kunci API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Bahasa",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Cerah",
 	"Listening...": "Mendengar...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Model Tempatan",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Dicipta oleh Komuniti OpenWebUI",
+	"Made by Open WebUI Community": "Dicipta oleh Komuniti OpenWebUI",
 	"Make sure to enclose them with": "Pastikan untuk melampirkannya dengan",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Urus",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Baca dengan lantang",
 	"Reasoning Effort": "",
 	"Record voice": "Rakam suara",
-	"Redirecting you to OpenWebUI Community": "Membawa anda ke Komuniti OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Membawa anda ke Komuniti 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Rujuk diri anda sebagai \"User\" (cth, \"Pengguna sedang belajar bahasa Sepanyol\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Tetapan berjaya disimpan!",
 	"Share": "Kongsi",
 	"Share Chat": "Kongsi Perbualan",
-	"Share to OpenWebUI Community": "Kongsi kepada Komuniti OpenWebUI",
+	"Share to Open WebUI Community": "Kongsi kepada Komuniti OpenWebUI",
 	"Show": "Tunjukkan",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Tunjukkan Butiran Pentadbir dalam Akaun Menunggu Tindanan",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Penjelasan menyeluruh",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "URL Pelayan Tika diperlukan.",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/nb-NO/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klikk her for å",
 	"Click here to download user import template file.": "Klikk her for å hente ned malfilen for import av brukere.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klikk her for å lære mer om faster-whisper, og se de tilgjengelige modellene.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klikk her for å velge",
 	"Click here to select a csv file.": "Klikk her for å velge en CSV-fil.",
 	"Click here to select a py file.": "Klikk her for å velge en PY-fil.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentasjon",
 	"Documents": "Dokumenter",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ikke ingen tilkobling til eksterne tjenester. Dataene dine forblir sikkert på den lokale serveren.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Har du ingen konto?",
 	"don't install random functions from sources you don't trust.": "ikke installer tilfeldige funksjoner fra kilder du ikke stoler på.",
 	"don't install random tools from sources you don't trust.": "ikke installer tilfeldige verktøy fra kilder du ikke stoler på.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Angi Chunk-overlapp",
 	"Enter Chunk Size": "Angi Chunk-størrelse",
 	"Enter description": "Angi beskrivelse",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Angi Github Raw-URL",
 	"Enter Google PSE API Key": "Angi API-nøkkel for Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Kunnskap slettet.",
 	"Knowledge reset successfully.": "Tilbakestilling av kunnskap vellykket.",
 	"Knowledge updated successfully": "Kunnskap oppdatert",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Etikett",
 	"Landing Page Mode": "Modus for startside",
 	"Language": "Språk",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "La stå tomt for å inkludere alle modeller fra endepunktet \"{{URL}}/api/models\"",
 	"Leave empty to include all models or select specific models": "La stå tomt for å inkludere alle modeller",
 	"Leave empty to use the default prompt, or enter a custom prompt": "La stå tomt for å bruke standard ledetekst, eller angi en tilpasset ledetekst",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Lys",
 	"Listening...": "Lytter ...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokale modeller",
 	"Lost": "Tapt",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Laget av OpenWebUI-fellesskapet",
+	"Made by Open WebUI Community": "Laget av OpenWebUI-fellesskapet",
 	"Make sure to enclose them with": "Sørg for å omslutte dem med",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Sørg for å eksportere en workflow.json-fil i API-formatet fra ComfyUI.",
 	"Manage": "Administrer",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Les høyt",
 	"Reasoning Effort": "",
 	"Record voice": "Ta opp tale",
-	"Redirecting you to OpenWebUI Community": "Omdirigerer deg til OpenWebUI-fellesskapet",
+	"Redirecting you to Open WebUI Community": "Omdirigerer deg til OpenWebUI-fellesskapet",
 	"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. (Default: 40)": "Reduserer sannsynligheten for å generere meningsløse svar. En høyere verdi (f.eks. 100) vil gi mer varierte svar, mens en lavere verdi (f.eks. 10) vil være mer konservativ. (Standard: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Omtal deg selv som \"Bruker\" (f.eks. \"Bruker lærer spansk\")",
 	"References from": "Henviser fra",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Innstillinger lagret!",
 	"Share": "Del",
 	"Share Chat": "Del chat",
-	"Share to OpenWebUI Community": "Del med OpenWebUI-fellesskapet",
+	"Share to Open WebUI Community": "Del med OpenWebUI-fellesskapet",
 	"Show": "Vis",
 	"Show \"What's New\" modal on login": "Vis \"Hva er nytt\"-modal ved innlogging",
 	"Show Admin Details in Account Pending Overlay": "Vis administratordetaljer i ventende kontovisning",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette tilbakestiller kunnskapsbasen og synkroniserer alle filer. Vil du fortsette?",
 	"Thorough explanation": "Grundig forklaring",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Server-URL for Tika kreves.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/nl-NL/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klik hier om",
 	"Click here to download user import template file.": "Klik hier om het sjabloonbestand voor gebruikersimport te downloaden.",
 	"Click here to learn more about faster-whisper and see the available models.": "Klik hier om meer te leren over faster-whisper en de beschikbare modellen te bekijken.",
+	"Click here to see available models.": "",
 	"Click here to select": "Klik hier om te selecteren",
 	"Click here to select a csv file.": "Klik hier om een csv file te selecteren.",
 	"Click here to select a py file.": "Klik hier om een py-bestand te selecteren.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentatie",
 	"Documents": "Documenten",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "maakt geen externe verbindingen, en je gegevens blijven veilig op je lokaal gehoste server.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Heb je geen account?",
 	"don't install random functions from sources you don't trust.": "installeer geen willekeurige functies van bronnen die je niet vertrouwd",
 	"don't install random tools from sources you don't trust.": "installeer geen willekeurige gereedschappen van bronnen die je niet vertrouwd",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Voeg Chunk Overlap toe",
 	"Enter Chunk Size": "Voeg Chunk Size toe",
 	"Enter description": "Voer beschrijving in",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Voer de Github Raw-URL in",
 	"Enter Google PSE API Key": "Voer de Google PSE API-sleutel in",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Kennis succesvol verwijderd",
 	"Knowledge reset successfully.": "Kennis succesvol gereset",
 	"Knowledge updated successfully": "Kennis succesvol bijgewerkt",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Label",
 	"Landing Page Mode": "Landingspaginamodus",
 	"Language": "Taal",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laat leeg om alle modellen van het \"{{URL}}/models\" endpoint toe te voegen",
 	"Leave empty to include all models or select specific models": "Laat leeg om alle modellen mee te nemen, of selecteer specifieke modellen",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Laat leeg om de standaard prompt te gebruiken, of selecteer een aangepaste prompt",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Licht",
 	"Listening...": "Aan het luisteren...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokale modellen",
 	"Lost": "Verloren",
 	"LTR": "LNR",
-	"Made by OpenWebUI Community": "Gemaakt door OpenWebUI Community",
+	"Made by Open WebUI Community": "Gemaakt door OpenWebUI Community",
 	"Make sure to enclose them with": "Zorg ervoor dat je ze omringt met",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Zorg ervoor dat je een workflow.json-bestand als API-formaat exporteert vanuit ComfyUI.",
 	"Manage": "Beheren",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Voorlezen",
 	"Reasoning Effort": "",
 	"Record voice": "Neem stem op",
-	"Redirecting you to OpenWebUI Community": "Je wordt doorgestuurd naar OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "Je wordt doorgestuurd naar OpenWebUI Community",
 	"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. (Default: 40)": "Vermindert de kans op het genereren van onzin. Een hogere waarde (bijv. 100) zal meer diverse antwoorden geven, terwijl een lagere waarde (bijv. 10) conservatiever zal zijn. (Standaard: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Refereer naar jezelf als \"user\" (bv. \"User is Spaans aan het leren\"",
 	"References from": "Referenties van",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Instellingen succesvol opgeslagen!",
 	"Share": "Delen",
 	"Share Chat": "Deel chat",
-	"Share to OpenWebUI Community": "Deel naar OpenWebUI-community",
+	"Share to Open WebUI Community": "Deel naar OpenWebUI-community",
 	"Show": "Toon",
 	"Show \"What's New\" modal on login": "Toon \"Wat is nieuw\" bij inloggen",
 	"Show Admin Details in Account Pending Overlay": "Admin-details weergeven in overlay in afwachting van account",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dit zal de kennisdatabase resetten en alle bestanden synchroniseren. Wilt u doorgaan?",
 	"Thorough explanation": "Gevorderde uitleg",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Tika Server-URL vereist",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/pa-IN/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "ਡਾਕੂਮੈਂਟ",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ਕੋਈ ਬਾਹਰੀ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਬਣਾਉਂਦਾ, ਅਤੇ ਤੁਹਾਡਾ ਡਾਟਾ ਤੁਹਾਡੇ ਸਥਾਨਕ ਸਰਵਰ 'ਤੇ ਸੁਰੱਖਿਅਤ ਰਹਿੰਦਾ ਹੈ।",
+	"Domain Filter List": "",
 	"Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "ਚੰਕ ਓਵਰਲੈਪ ਦਰਜ ਕਰੋ",
 	"Enter Chunk Size": "ਚੰਕ ਆਕਾਰ ਦਰਜ ਕਰੋ",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Github ਕੱਚਾ URL ਦਾਖਲ ਕਰੋ",
 	"Enter Google PSE API Key": "Google PSE API ਕੁੰਜੀ ਦਾਖਲ ਕਰੋ",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "ਭਾਸ਼ਾ",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "ਹਲਕਾ",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਦੁਆਰਾ ਬਣਾਇਆ ਗਿਆ",
+	"Made by Open WebUI Community": "ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਦੁਆਰਾ ਬਣਾਇਆ ਗਿਆ",
 	"Make sure to enclose them with": "ਸੁਨਿਸ਼ਚਿਤ ਕਰੋ ਕਿ ਉਨ੍ਹਾਂ ਨੂੰ ਘੇਰੋ",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "ਜੋਰ ਨਾਲ ਪੜ੍ਹੋ",
 	"Reasoning Effort": "",
 	"Record voice": "ਆਵਾਜ਼ ਰਿਕਾਰਡ ਕਰੋ",
-	"Redirecting you to OpenWebUI Community": "ਤੁਹਾਨੂੰ ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਵੱਲ ਰੀਡਾਇਰੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
+	"Redirecting you to Open WebUI Community": "ਤੁਹਾਨੂੰ ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਵੱਲ ਰੀਡਾਇਰੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "ਸੈਟਿੰਗਾਂ ਸਫਲਤਾਪੂਰਵਕ ਸੰਭਾਲੀਆਂ ਗਈਆਂ!",
 	"Share": "ਸਾਂਝਾ ਕਰੋ",
 	"Share Chat": "ਗੱਲਬਾਤ ਸਾਂਝੀ ਕਰੋ",
-	"Share to OpenWebUI Community": "ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਨਾਲ ਸਾਂਝਾ ਕਰੋ",
+	"Share to Open WebUI Community": "ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਨਾਲ ਸਾਂਝਾ ਕਰੋ",
 	"Show": "ਦਿਖਾਓ",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "ਵਿਸਥਾਰ ਨਾਲ ਵਿਆਖਿਆ",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/pl-PL/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Kliknij tutaj, żeby",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Kliknij tutaj, aby wybrać",
 	"Click here to select a csv file.": "Kliknij tutaj, żeby wybrać plik CSV",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "Dokumenty",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "nie nawiązuje żadnych zewnętrznych połączeń, a Twoje dane pozostają bezpiecznie na Twoim lokalnie hostowanym serwerze.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nie masz konta?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Wprowadź zakchodzenie bloku",
 	"Enter Chunk Size": "Wprowadź rozmiar bloku",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Wprowadź nieprzetworzony adres URL usługi Github",
 	"Enter Google PSE API Key": "Wprowadź klucz API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Język",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Jasny",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Stworzone przez społeczność OpenWebUI",
+	"Made by Open WebUI Community": "Stworzone przez społeczność OpenWebUI",
 	"Make sure to enclose them with": "Upewnij się, że są one zamknięte w",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Czytaj na głos",
 	"Reasoning Effort": "",
 	"Record voice": "Nagraj głos",
-	"Redirecting you to OpenWebUI Community": "Przekierowujemy Cię do społeczności OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Przekierowujemy Cię do społeczności 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Ustawienia zapisane pomyślnie!",
 	"Share": "Udostępnij",
 	"Share Chat": "Udostępnij czat",
-	"Share to OpenWebUI Community": "Dziel się z społecznością OpenWebUI",
+	"Share to Open WebUI Community": "Dziel się z społecznością OpenWebUI",
 	"Show": "Pokaż",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Dokładne wyjaśnienie",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/pt-BR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Clique aqui para",
 	"Click here to download user import template file.": "Clique aqui para baixar o arquivo de modelo de importação de usuários.",
 	"Click here to learn more about faster-whisper and see the available models.": "Clique aqui para aprender mais sobre Whisper e ver os modelos disponíveis.",
+	"Click here to see available models.": "",
 	"Click here to select": "Clique aqui para enviar",
 	"Click here to select a csv file.": "Clique aqui para enviar um arquivo csv.",
 	"Click here to select a py file.": "Clique aqui para enviar um arquivo python.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentação",
 	"Documents": "Documentos",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz nenhuma conexão externa, e seus dados permanecem seguros no seu servidor local.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Não tem uma conta?",
 	"don't install random functions from sources you don't trust.": "não instale funções aleatórias de fontes que você não confia.",
 	"don't install random tools from sources you don't trust.": "não instale ferramentas aleatórias de fontes que você não confia.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Digite a Sobreposição de Chunk",
 	"Enter Chunk Size": "Digite o Tamanho do Chunk",
 	"Enter description": "Digite a descrição",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Digite a URL bruta do Github",
 	"Enter Google PSE API Key": "Digite a Chave API do Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Conhecimento excluído com sucesso.",
 	"Knowledge reset successfully.": "Conhecimento resetado com sucesso.",
 	"Knowledge updated successfully": "Conhecimento atualizado com sucesso",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Rótulo",
 	"Landing Page Mode": "Modo Landing Page",
 	"Language": "Idioma",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixe vazio para incluir todos os modelos do endpoint \"{{URL}}/models\"",
 	"Leave empty to include all models or select specific models": "Deixe vazio para incluir todos os modelos ou selecione modelos especificos",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Deixe vazio para usar o prompt padrão, ou insira um prompt personalizado",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Claro",
 	"Listening...": "Escutando...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Modelos Locais",
 	"Lost": "Perdeu",
 	"LTR": "Esquerda para Direita",
-	"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
+	"Made by Open WebUI Community": "Feito pela Comunidade OpenWebUI",
 	"Make sure to enclose them with": "Certifique-se de encerrá-los com",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Certifique-se de exportar um arquivo workflow.json como o formato API do ComfyUI.",
 	"Manage": "Gerenciar",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Ler em Voz Alta",
 	"Reasoning Effort": "",
 	"Record voice": "Gravar voz",
-	"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
+	"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. (Default: 40)": "Reduz a probabilidade de gerar absurdos. Um valor mais alto (por exemplo, 100) dará respostas mais diversas, enquanto um valor mais baixo (por exemplo, 10) será mais conservador. (Padrão: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Refira-se como \"Usuário\" (por exemplo, \"Usuário está aprendendo espanhol\")",
 	"References from": "Referências de",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Configurações salvas com sucesso!",
 	"Share": "Compartilhar",
 	"Share Chat": "Compartilhar Chat",
-	"Share to OpenWebUI Community": "Compartilhar com a Comunidade OpenWebUI",
+	"Share to Open WebUI Community": "Compartilhar com a Comunidade OpenWebUI",
 	"Show": "Mostrar",
 	"Show \"What's New\" modal on login": "Mostrar \"O que há de Novo\" no login",
 	"Show Admin Details in Account Pending Overlay": "Mostrar Detalhes do Administrador na Sobreposição de Conta Pendentes",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Esta ação resetará a base de conhecimento e sincronizará todos os arquivos. Deseja continuar?",
 	"Thorough explanation": "Explicação detalhada",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "URL do servidor Tika necessária.",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/pt-PT/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Clique aqui para",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Clique aqui para selecionar",
 	"Click here to select a csv file.": "Clique aqui para selecionar um ficheiro csv.",
 	"Click here to select a py file.": "Clique aqui para selecionar um ficheiro py",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentação",
 	"Documents": "Documentos",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e os seus dados permanecem seguros no seu servidor alojado localmente.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Não tem uma conta?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Escreva a Sobreposição de Fragmento",
 	"Enter Chunk Size": "Escreva o Tamanho do Fragmento",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Escreva o URL cru do Github",
 	"Enter Google PSE API Key": "Escreva a chave da API PSE do Google",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Idioma",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Claro",
 	"Listening...": "A escutar...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Modelos Locais",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
+	"Made by Open WebUI Community": "Feito pela Comunidade OpenWebUI",
 	"Make sure to enclose them with": "Certifique-se de colocá-los entre",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Gerir",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Ler em Voz Alta",
 	"Reasoning Effort": "",
 	"Record voice": "Gravar voz",
-	"Redirecting you to OpenWebUI Community": "Redirecionando-o para a Comunidade OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Redirecionando-o 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Refera-se a si próprio como \"User\" (por exemplo, \"User está a aprender Espanhol\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Configurações guardadas com sucesso!",
 	"Share": "Partilhar",
 	"Share Chat": "Partilhar Conversa",
-	"Share to OpenWebUI Community": "Partilhar com a Comunidade OpenWebUI",
+	"Share to Open WebUI Community": "Partilhar com a Comunidade OpenWebUI",
 	"Show": "Mostrar",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Mostrar Detalhes do Administrador na sobreposição de Conta Pendente",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Explicação Minuciosa",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/ro-RO/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Apasă aici pentru",
 	"Click here to download user import template file.": "Apasă aici pentru a descărca fișierul șablon de import utilizator.",
 	"Click here to learn more about faster-whisper and see the available models.": "Faceți clic aici pentru a afla mai multe despre faster-whisper și pentru a vedea modelele disponibile.",
+	"Click here to see available models.": "",
 	"Click here to select": "Apasă aici pentru a selecta",
 	"Click here to select a csv file.": "Apasă aici pentru a selecta un fișier csv.",
 	"Click here to select a py file.": "Apasă aici pentru a selecta un fișier py.",
@@ -290,6 +291,7 @@
 	"Documentation": "Documentație",
 	"Documents": "Documente",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "nu face nicio conexiune externă, iar datele tale rămân în siguranță pe serverul găzduit local.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nu ai un cont?",
 	"don't install random functions from sources you don't trust.": "nu instala funcții aleatorii din surse în care nu ai încredere.",
 	"don't install random tools from sources you don't trust.": "nu instala instrumente aleatorii din surse în care nu ai încredere.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Introduceți Suprapunerea Blocului",
 	"Enter Chunk Size": "Introduceți Dimensiunea Blocului",
 	"Enter description": "Introduceți descrierea",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Introduceți URL-ul Raw de pe Github",
 	"Enter Google PSE API Key": "Introduceți Cheia API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Cunoștințele au fost șterse cu succes.",
 	"Knowledge reset successfully.": "Resetarea cunoștințelor a fost efectuată cu succes.",
 	"Knowledge updated successfully": "Cunoașterea a fost actualizată cu succes",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Modul Pagină de Aterizare",
 	"Language": "Limbă",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "Lăsați gol pentru a include toate modelele sau selectați modele specifice",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Lăsați gol pentru a utiliza promptul implicit sau introduceți un prompt personalizat",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Luminos",
 	"Listening...": "Ascult...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Modele Locale",
 	"Lost": "Pierdut",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Realizat de Comunitatea OpenWebUI",
+	"Made by Open WebUI Community": "Realizat de Comunitatea OpenWebUI",
 	"Make sure to enclose them with": "Asigurați-vă că le închideți cu",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Asigură-te că exporți un fișier {{workflow.json}} în format API din {{ComfyUI}}.",
 	"Manage": "Gestionează",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Citește cu Voce Tare",
 	"Reasoning Effort": "",
 	"Record voice": "Înregistrează vocea",
-	"Redirecting you to OpenWebUI Community": "Vă redirecționăm către Comunitatea OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Vă redirecționăm către Comunitatea 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Referiți-vă la dvs. ca \"Utilizator\" (de ex., \"Utilizatorul învață spaniolă\")",
 	"References from": "Referințe din",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Setările au fost salvate cu succes!",
 	"Share": "Partajează",
 	"Share Chat": "Partajează Conversația",
-	"Share to OpenWebUI Community": "Partajează cu Comunitatea OpenWebUI",
+	"Share to Open WebUI Community": "Partajează cu Comunitatea OpenWebUI",
 	"Show": "Afișează",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Afișează Detaliile Administratorului în Suprapunerea Contului În Așteptare",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Aceasta va reseta baza de cunoștințe și va sincroniza toate fișierele. Doriți să continuați?",
 	"Thorough explanation": "Explicație detaliată",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Este necesar URL-ul serverului Tika.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/ru-RU/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Нажмите здесь, чтобы",
 	"Click here to download user import template file.": "Нажмите здесь, чтобы загрузить файл шаблона импорта пользователя",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "Нажмите здесь, чтобы выбрать py-файл",
@@ -290,6 +291,7 @@
 	"Documentation": "Документация",
 	"Documents": "Документы",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "не устанавливает никаких внешних соединений, и ваши данные надежно хранятся на вашем локальном сервере.",
+	"Domain Filter List": "",
 	"Don't have an account?": "У вас нет аккаунта?",
 	"don't install random functions from sources you don't trust.": "не устанавливайте случайные функции из источников, которым вы не доверяете.",
 	"don't install random tools from sources you don't trust.": "не устанавливайте случайные инструменты из источников, которым вы не доверяете.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Введите перекрытие фрагмента",
 	"Enter Chunk Size": "Введите размер фрагмента",
 	"Enter description": "Введите описание",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Введите необработанный URL-адрес Github",
 	"Enter Google PSE API Key": "Введите ключ API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Знания успешно удалены.",
 	"Knowledge reset successfully.": "Знания успешно сброшены.",
 	"Knowledge updated successfully": "Знания успешно обновлены",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Режим Целевой Страницы",
 	"Language": "Язык",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Оставьте пустым, чтобы использовать промпт по умолчанию, или введите пользовательский промпт",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Светлый",
 	"Listening...": "Слушаю...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Локальные модели",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Сделано сообществом OpenWebUI",
+	"Made by Open WebUI Community": "Сделано сообществом OpenWebUI",
 	"Make sure to enclose them with": "Убедитесь, что они заключены в",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Убедитесь, что экспортируете файл workflow.json в формате API из ComfyUI.",
 	"Manage": "Управлять",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Прочитать вслух",
 	"Reasoning Effort": "",
 	"Record voice": "Записать голос",
-	"Redirecting you to OpenWebUI Community": "Перенаправляем вас в сообщество OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Перенаправляем вас в сообщество 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Называйте себя \"User\" (например, \"User is learning Spanish\").",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Настройки успешно сохранены!",
 	"Share": "Поделиться",
 	"Share Chat": "Поделиться чатом",
-	"Share to OpenWebUI Community": "Поделиться с сообществом OpenWebUI",
+	"Share to Open WebUI Community": "Поделиться с сообществом OpenWebUI",
 	"Show": "Показать",
 	"Show \"What's New\" modal on login": "Показывать окно «Что нового» при входе в систему",
 	"Show Admin Details in Account Pending Overlay": "Показывать данные администратора в оверлее ожидающей учетной записи",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Это сбросит базу знаний и синхронизирует все файлы. Хотите продолжить?",
 	"Thorough explanation": "Подробное объяснение",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Требуется URL-адрес сервера Tika.",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/sk-SK/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Kliknite tu na",
 	"Click here to download user import template file.": "Kliknite tu pre stiahnutie šablóny súboru na import užívateľov.",
 	"Click here to learn more about faster-whisper and see the available models.": "Kliknite sem a dozviete sa viac o faster-whisper a pozrite si dostupné modely.",
+	"Click here to see available models.": "",
 	"Click here to select": "Kliknite sem pre výber",
 	"Click here to select a csv file.": "Kliknite sem pre výber súboru typu csv.",
 	"Click here to select a py file.": "Kliknite sem pre výber {{py}} súboru.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentácia",
 	"Documents": "Dokumenty",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "nevytvára žiadne externé pripojenia a vaše dáta zostávajú bezpečne na vašom lokálnom serveri.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Nemáte účet?",
 	"don't install random functions from sources you don't trust.": "Neinštalujte náhodné funkcie zo zdrojov, ktorým nedôverujete.",
 	"don't install random tools from sources you don't trust.": "Neinštalujte náhodné nástroje zo zdrojov, ktorým nedôverujete.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Zadajte prekryv časti",
 	"Enter Chunk Size": "Zadajte veľkosť časti",
 	"Enter description": "Zadajte popis",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Zadajte URL adresu Github Raw",
 	"Enter Google PSE API Key": "Zadajte kľúč rozhrania API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Znalosti boli úspešne odstránené.",
 	"Knowledge reset successfully.": "Úspešné obnovenie znalostí.",
 	"Knowledge updated successfully": "Znalosti úspešne aktualizované",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "Režim vstupnej stránky",
 	"Language": "Jazyk",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "Nechajte prázdne pre zahrnutie všetkých modelov alebo vyberte konkrétne modely.",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Nechajte prázdne pre použitie predvoleného podnetu, alebo zadajte vlastný podnet.",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Svetlo",
 	"Listening...": "Počúvanie...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokálne modely",
 	"Lost": "Stratený",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Vytvorené komunitou OpenWebUI",
+	"Made by Open WebUI Community": "Vytvorené komunitou OpenWebUI",
 	"Make sure to enclose them with": "Uistite sa, že sú uzavreté pomocou",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Uistite sa, že exportujete súbor workflow.json vo formáte API z ComfyUI.",
 	"Manage": "Spravovať",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Čítať nahlas",
 	"Reasoning Effort": "",
 	"Record voice": "Nahrať hlas",
-	"Redirecting you to OpenWebUI Community": "Presmerovanie na komunitu OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Presmerovanie na komunitu 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Odkazujte na seba ako na \"užívateľa\" (napr. \"Užívateľ sa učí španielsky\").",
 	"References from": "Referencie z",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Nastavenia boli úspešne uložené!",
 	"Share": "Zdieľať",
 	"Share Chat": "Zdieľať chat",
-	"Share to OpenWebUI Community": "Zdieľať s komunitou OpenWebUI",
+	"Share to Open WebUI Community": "Zdieľať s komunitou OpenWebUI",
 	"Show": "Zobraziť",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Zobraziť podrobnosti administrátora v prekryvnom okne s čakajúcim účtom",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostnú databázu a synchronizuje všetky súbory. Prajete si pokračovať?",
 	"Thorough explanation": "Obsiahle vysvetlenie",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Je vyžadovaná URL adresa servera Tika.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/sr-RS/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Кликните овде да",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "Документација",
 	"Documents": "Документи",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "не отвара никакве спољне везе и ваши подаци остају сигурно на вашем локално хостованом серверу.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Немате налог?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Унесите преклапање делова",
 	"Enter Chunk Size": "Унесите величину дела",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Унесите Гитхуб Раw УРЛ адресу",
 	"Enter Google PSE API Key": "Унесите Гоогле ПСЕ АПИ кључ",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Етикета",
 	"Landing Page Mode": "Режим почетне стране",
 	"Language": "Језик",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Светла",
 	"Listening...": "Слушам...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "Локални модели",
 	"Lost": "Пораза",
 	"LTR": "ЛНД",
-	"Made by OpenWebUI Community": "Израдила OpenWebUI заједница",
+	"Made by Open WebUI Community": "Израдила OpenWebUI заједница",
 	"Make sure to enclose them with": "Уверите се да их затворите са",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Управљај",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Прочитај наглас",
 	"Reasoning Effort": "Јачина размишљања",
 	"Record voice": "Сними глас",
-	"Redirecting you to OpenWebUI Community": "Преусмеравање на OpenWebUI заједницу",
+	"Redirecting you to Open WebUI Community": "Преусмеравање на 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "Референце од",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Подешавања успешно сачувана!",
 	"Share": "Подели",
 	"Share Chat": "Подели ћаскање",
-	"Share to OpenWebUI Community": "Подели са OpenWebUI заједницом",
+	"Share to Open WebUI Community": "Подели са OpenWebUI заједницом",
 	"Show": "Прикажи",
 	"Show \"What's New\" modal on login": "Прикажи \"Погледај шта је ново\" прозорче при пријави",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Ово ће обрисати базу знања и ускладити све датотеке. Да ли желите наставити?",
 	"Thorough explanation": "Детаљно објашњење",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/sv-SE/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Klicka här för att",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Klicka här för att välja",
 	"Click here to select a csv file.": "Klicka här för att välja en csv-fil.",
 	"Click here to select a py file.": "Klicka här för att välja en python-fil.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dokumentation",
 	"Documents": "Dokument",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "gör inga externa anslutningar, och dina data förblir säkra på din lokalt värdade server.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Har du inget konto?",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Ange chunköverlappning",
 	"Enter Chunk Size": "Ange chunkstorlek",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Ange Github Raw URL",
 	"Enter Google PSE API Key": "Ange Google PSE API-nyckel",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Språk",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Ljus",
 	"Listening...": "Lyssnar...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Lokala modeller",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Skapad av OpenWebUI Community",
+	"Made by Open WebUI Community": "Skapad av OpenWebUI Community",
 	"Make sure to enclose them with": "Se till att bifoga dem med",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "Hantera",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Läs igenom",
 	"Reasoning Effort": "",
 	"Record voice": "Spela in röst",
-	"Redirecting you to OpenWebUI Community": "Omdirigerar dig till OpenWebUI Community",
+	"Redirecting you to Open WebUI Community": "Omdirigerar dig till OpenWebUI Community",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Referera till dig själv som \"Användare\" (t.ex. \"Användaren lär sig spanska\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Inställningar sparades framgångsrikt!",
 	"Share": "Dela",
 	"Share Chat": "Dela chatt",
-	"Share to OpenWebUI Community": "Dela till OpenWebUI Community",
+	"Share to Open WebUI Community": "Dela till OpenWebUI Community",
 	"Show": "Visa",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Visa administratörsinformation till väntande konton",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Djupare förklaring",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/th-TH/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "คลิกที่นี่เพื่อ",
 	"Click here to download user import template file.": "คลิกที่นี่เพื่อดาวน์โหลดไฟล์แม่แบบนำเข้าผู้ใช้",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"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.": "คลิกที่นี่เพื่อเลือกไฟล์ py",
@@ -290,6 +291,7 @@
 	"Documentation": "เอกสารประกอบ",
 	"Documents": "เอกสาร",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "ไม่เชื่อมต่อภายนอกใดๆ และข้อมูลของคุณจะอยู่บนเซิร์ฟเวอร์ที่โฮสต์ในท้องถิ่นของคุณอย่างปลอดภัย",
+	"Domain Filter List": "",
 	"Don't have an account?": "ยังไม่มีบัญชี?",
 	"don't install random functions from sources you don't trust.": "อย่าติดตั้งฟังก์ชันแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ",
 	"don't install random tools from sources you don't trust.": "อย่าติดตั้งเครื่องมือแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "ใส่การทับซ้อนส่วนข้อมูล",
 	"Enter Chunk Size": "ใส่ขนาดส่วนข้อมูล",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "ใส่ URL ดิบของ Github",
 	"Enter Google PSE API Key": "ใส่คีย์ API ของ Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "ภาษา",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "แสง",
 	"Listening...": "กำลังฟัง...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "โมเดลท้องถิ่น",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "สร้างโดยชุมชน OpenWebUI",
+	"Made by Open WebUI Community": "สร้างโดยชุมชน OpenWebUI",
 	"Make sure to enclose them with": "",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "จัดการ",
@@ -754,7 +760,7 @@
 	"Read Aloud": "อ่านออกเสียง",
 	"Reasoning Effort": "",
 	"Record voice": "บันทึกเสียง",
-	"Redirecting you to OpenWebUI Community": "กำลังเปลี่ยนเส้นทางคุณไปยังชุมชน OpenWebUI",
+	"Redirecting you to Open WebUI Community": "กำลังเปลี่ยนเส้นทางคุณไปยังชุมชน 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "เรียกตัวเองว่า \"ผู้ใช้\" (เช่น \"ผู้ใช้กำลังเรียนภาษาสเปน\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "บันทึกการตั้งค่าเรียบร้อยแล้ว!",
 	"Share": "แชร์",
 	"Share Chat": "แชร์แชท",
-	"Share to OpenWebUI Community": "แชร์ไปยังชุมชน OpenWebUI",
+	"Share to Open WebUI Community": "แชร์ไปยังชุมชน OpenWebUI",
 	"Show": "แสดง",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "แสดงรายละเอียดผู้ดูแลระบบในหน้าจอรอการอนุมัติบัญชี",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "คำอธิบายอย่างละเอียด",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "จำเป็นต้องมี URL ของเซิร์ฟเวอร์ Tika",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/tk-TW/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "",
 	"Click here to download user import template file.": "",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "",
 	"Click here to select a csv file.": "",
 	"Click here to select a py file.": "",
@@ -290,6 +291,7 @@
 	"Documentation": "",
 	"Documents": "",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "",
+	"Domain Filter List": "",
 	"Don't have an account?": "",
 	"don't install random functions from sources you don't trust.": "",
 	"don't install random tools from sources you don't trust.": "",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "",
 	"Enter Chunk Size": "",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "",
 	"Enter Google PSE API Key": "",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "",
 	"Listening...": "",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "",
-	"Made by OpenWebUI Community": "",
+	"Made by Open WebUI Community": "",
 	"Make sure to enclose them with": "",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "",
 	"Manage": "",
@@ -754,7 +760,7 @@
 	"Read Aloud": "",
 	"Reasoning Effort": "",
 	"Record voice": "",
-	"Redirecting you to OpenWebUI Community": "",
+	"Redirecting you to Open WebUI Community": "",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "",
 	"Share": "",
 	"Share Chat": "",
-	"Share to OpenWebUI Community": "",
+	"Share to Open WebUI Community": "",
 	"Show": "",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "",
 	"Tiktoken": "",

+ 10 - 3
src/lib/i18n/locales/tr-TR/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Şunu yapmak için buraya tıklayın:",
 	"Click here to download user import template file.": "Kullanıcı içe aktarma şablon dosyasını indirmek için buraya tıklayın.",
 	"Click here to learn more about faster-whisper and see the available models.": "faster-whisper hakkında daha fazla bilgi edinmek ve mevcut modelleri görmek için buraya tıklayın.",
+	"Click here to see available models.": "",
 	"Click here to select": "Seçmek için buraya tıklayın",
 	"Click here to select a csv file.": "Bir CSV dosyası seçmek için buraya tıklayın.",
 	"Click here to select a py file.": "Bir py dosyası seçmek için buraya tıklayın.",
@@ -290,6 +291,7 @@
 	"Documentation": "Dökümantasyon",
 	"Documents": "Belgeler",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Hesabınız yok mu?",
 	"don't install random functions from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele fonksiyonlar yüklemeyin.",
 	"don't install random tools from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele araçlar yüklemeyin.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Chunk Örtüşmesini Girin",
 	"Enter Chunk Size": "Chunk Boyutunu Girin",
 	"Enter description": "Açıklama girin",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Github Raw URL'sini girin",
 	"Enter Google PSE API Key": "Google PSE API Anahtarını Girin",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Bilgi başarıyla silindi.",
 	"Knowledge reset successfully.": "Bilgi başarıyla sıfırlandı.",
 	"Knowledge updated successfully": "Bilgi başarıyla güncellendi",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Dil",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "Tüm modelleri dahil etmek için boş bırakın veya belirli modelleri seçin",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Varsayılan promptu kullanmak için boş bırakın veya özel bir prompt girin",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Açık",
 	"Listening...": "Dinleniyor...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "Yerel Modeller",
 	"Lost": "Kayıp",
 	"LTR": "Soldan Sağa",
-	"Made by OpenWebUI Community": "OpenWebUI Topluluğu tarafından yapılmıştır",
+	"Made by Open WebUI Community": "OpenWebUI Topluluğu tarafından yapılmıştır",
 	"Make sure to enclose them with": "Değişkenlerinizi şu şekilde biçimlendirin:",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "ComfyUI'dan API formatında bir workflow.json dosyası olarak dışa aktardığınızdan emin olun.",
 	"Manage": "Yönet",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Sesli Oku",
 	"Reasoning Effort": "",
 	"Record voice": "Ses kaydı yap",
-	"Redirecting you to OpenWebUI Community": "OpenWebUI Topluluğuna yönlendiriliyorsunuz",
+	"Redirecting you to Open WebUI Community": "OpenWebUI Topluluğuna yönlendiriliyorsunuz",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Kendinizden \"User\" olarak bahsedin (örneğin, \"User İspanyolca öğreniyor\")",
 	"References from": "Referanslar arasından",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Ayarlar başarıyla kaydedildi!",
 	"Share": "Paylaş",
 	"Share Chat": "Sohbeti Paylaş",
-	"Share to OpenWebUI Community": "OpenWebUI Topluluğu ile Paylaş",
+	"Share to Open WebUI Community": "OpenWebUI Topluluğu ile Paylaş",
 	"Show": "Göster",
 	"Show \"What's New\" modal on login": "Girişte \"Yenilikler\" modalını göster",
 	"Show Admin Details in Account Pending Overlay": "Yönetici Ayrıntılarını Hesap Bekliyor Ekranında Göster",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Bu, bilgi tabanını sıfırlayacak ve tüm dosyaları senkronize edecek. Devam etmek istiyor musunuz?",
 	"Thorough explanation": "Kapsamlı açıklama",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "Tika Sunucu URL'si gereklidir.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/uk-UA/translation.json

@@ -163,6 +163,7 @@
 	"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.": "Натисніть тут, щоб обрати py-файл.",
@@ -290,6 +291,7 @@
 	"Documentation": "Документація",
 	"Documents": "Документи",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "не встановлює жодних зовнішніх з'єднань, і ваші дані залишаються в безпеці на вашому локальному сервері.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Немає облікового запису?",
 	"don't install random functions from sources you don't trust.": "не встановлюйте випадкові функції з джерел, яким ви не довіряєте.",
 	"don't install random tools from sources you don't trust.": "не встановлюйте випадкові інструменти з джерел, яким ви не довіряєте.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Введіть перекриття фрагменту",
 	"Enter Chunk Size": "Введіть розмір фрагменту",
 	"Enter description": "Введіть опис",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "Введіть ключ API Exa",
 	"Enter Github Raw URL": "Введіть Raw URL-адресу Github",
 	"Enter Google PSE API Key": "Введіть ключ API Google PSE",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "Знання успішно видалено.",
 	"Knowledge reset successfully.": "Знання успішно скинуто.",
 	"Knowledge updated successfully": "Знання успішно оновлено",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "Мітка",
 	"Landing Page Mode": "Режим головної сторінки",
 	"Language": "Мова",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Залиште порожнім, щоб включити всі моделі з кінцевої точки \"{{URL}}/models\"",
 	"Leave empty to include all models or select specific models": "Залиште порожнім, щоб включити всі моделі, або виберіть конкретні моделі.",
 	"Leave empty to use the default prompt, or enter a custom prompt": "Залиште порожнім для використання стандартного запиту, або введіть власний запит",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Світла",
 	"Listening...": "Слухаю...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "Локальні моделі",
 	"Lost": "Втрачене",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Зроблено спільнотою OpenWebUI",
+	"Made by Open WebUI Community": "Зроблено спільнотою OpenWebUI",
 	"Make sure to enclose them with": "Переконайтеся, що вони закриті",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Обов'язково експортуйте файл workflow.json у форматі API з ComfyUI.",
 	"Manage": "Керувати",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Читати вголос",
 	"Reasoning Effort": "Зусилля на міркування",
 	"Record voice": "Записати голос",
-	"Redirecting you to OpenWebUI Community": "Перенаправляємо вас до спільноти OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Перенаправляємо вас до спільноти 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. (Default: 40)": "Знижує ймовірність генерації безглуздих відповідей. Вищі значення (напр., 100) призведуть до більш різноманітних відповідей, тоді як нижчі значення (напр., 10) будуть більш обережними. (За замовчуванням: 40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Називайте себе \"Користувач\" (напр., \"Користувач вивчає іспанську мову\")",
 	"References from": "Посилання з",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Налаштування успішно збережено!",
 	"Share": "Поділитися",
 	"Share Chat": "Поділитися чатом",
-	"Share to OpenWebUI Community": "Поділитися зі спільнотою OpenWebUI",
+	"Share to Open WebUI Community": "Поділитися зі спільнотою OpenWebUI",
 	"Show": "Показати",
 	"Show \"What's New\" modal on login": "Показати модальне вікно \"Що нового\" під час входу.",
 	"Show Admin Details in Account Pending Overlay": "Відобразити дані адміна у вікні очікування облікового запису",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "Це скине базу знань і синхронізує всі файли. Ви бажаєте продовжити?",
 	"Thorough explanation": "Детальне пояснення",
 	"Thought for {{DURATION}}": "Думка для {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "Потрібна URL-адреса сервера Tika.",
 	"Tiktoken": "Tiktoken",

+ 10 - 3
src/lib/i18n/locales/ur-PK/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "یہاں کلک کریں تاکہ",
 	"Click here to download user import template file.": "صارف امپورٹ ٹیمپلیٹ فائل ڈاؤن لوڈ کرنے کے لیے یہاں کلک کریں",
 	"Click here to learn more about faster-whisper and see the available models.": "تیز ویسپر کے بارے میں مزید جاننے اور دستیاب ماڈلز دیکھنے کے لیے یہاں کلک کریں",
+	"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.": "یہاں کلک کریں تاکہ پی وائی فائل منتخب کریں",
@@ -290,6 +291,7 @@
 	"Documentation": "دستاویزات",
 	"Documents": "دستاویزات",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "آپ کا ڈیٹا مقامی طور پر میزبانی شدہ سرور پر محفوظ رہتا ہے اور کوئی بیرونی رابطے نہیں بناتا",
+	"Domain Filter List": "",
 	"Don't have an account?": "کیا آپ کے پاس اکاؤنٹ نہیں ہے؟",
 	"don't install random functions from sources you don't trust.": "غیر معتبر ذرائع سے بے ترتیب فنکشنز انسٹال نہ کریں",
 	"don't install random tools from sources you don't trust.": "جو ذرائع آپ پر بھروسہ نہیں کرتے ان سے بے ترتیب ٹولز انسٹال نہ کریں",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "چنک اوورلیپ درج کریں",
 	"Enter Chunk Size": "چنک سائز درج کریں",
 	"Enter description": "تفصیل درج کریں",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "گیٹ ہب را یو آر ایل درج کریں",
 	"Enter Google PSE API Key": "گوگل PSE API کلید درج کریں",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "معلومات کامیابی سے حذف ہو گئیں",
 	"Knowledge reset successfully.": "علم کو کامیابی کے ساتھ دوبارہ ترتیب دیا گیا",
 	"Knowledge updated successfully": "علم کامیابی سے تازہ کر دیا گیا ہے",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "لینڈر صفحہ موڈ",
 	"Language": "زبان",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "تمام ماڈلز کو شامل کرنے کے لئے خالی چھوڑ دیں یا مخصوص ماڈلز منتخب کریں",
 	"Leave empty to use the default prompt, or enter a custom prompt": "خالی چھوڑیں تاکہ ڈیفالٹ پرامپٹ استعمال ہو، یا ایک حسب ضرورت پرامپٹ درج کریں",
+	"Leave model field empty to use the default model.": "",
 	"Light": "روشنی",
 	"Listening...": "سن رہے ہیں...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "مقامی ماڈلز",
 	"Lost": "گم شدہ",
 	"LTR": "بائیں سے دائیں",
-	"Made by OpenWebUI Community": "اوپن ویب یو آئی کمیونٹی کی جانب سے تیار کردہ",
+	"Made by Open WebUI Community": "اوپن ویب یو آئی کمیونٹی کی جانب سے تیار کردہ",
 	"Make sure to enclose them with": "انہیں کے ساتھ شامل کریں",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "یقینی بنائیں کہ ComfyUI سے workflow.json فائل کو API فارمیٹ میں ایکسپورٹ کریں",
 	"Manage": "مینیج کریں",
@@ -754,7 +760,7 @@
 	"Read Aloud": "بُلند آواز میں پڑھیں",
 	"Reasoning Effort": "",
 	"Record voice": "صوت ریکارڈ کریں",
-	"Redirecting you to OpenWebUI Community": "آپ کو اوپن ویب یو آئی کمیونٹی کی طرف ری ڈائریکٹ کیا جا رہا ہے",
+	"Redirecting you to Open WebUI Community": "آپ کو اوپن ویب یو آئی کمیونٹی کی طرف ری ڈائریکٹ کیا جا رہا ہے",
 	"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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "خود کو \"صارف\" کے طور پر حوالہ دیں (جیسے، \"صارف ہسپانوی سیکھ رہا ہے\")",
 	"References from": "سے حوالہ جات",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "ترتیبات کامیابی کے ساتھ محفوظ ہو گئیں!",
 	"Share": "اشتراک کریں",
 	"Share Chat": "چیٹ شیئر کریں",
-	"Share to OpenWebUI Community": "اوپن ویب یوآئی کمیونٹی کے ساتھ شیئر کریں\n",
+	"Share to Open WebUI Community": "اوپن ویب یوآئی کمیونٹی کے ساتھ شیئر کریں\n",
 	"Show": "دکھائیں",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "اکاؤنٹ پینڈنگ اوورلے میں ایڈمن کی تفصیلات دکھائیں",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "یہ علمی بنیاد کو دوبارہ ترتیب دے گا اور تمام فائلز کو متوازن کرے گا کیا آپ جاری رکھنا چاہتے ہیں؟",
 	"Thorough explanation": "مکمل وضاحت",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "ٹیکہ",
 	"Tika Server URL required.": "ٹکا سرور یو آر ایل درکار ہے",
 	"Tiktoken": "ٹک ٹوکن",

+ 10 - 3
src/lib/i18n/locales/vi-VN/translation.json

@@ -163,6 +163,7 @@
 	"Click here to": "Nhấn vào đây để",
 	"Click here to download user import template file.": "Bấm vào đây để tải xuống tệp template của người dùng.",
 	"Click here to learn more about faster-whisper and see the available models.": "",
+	"Click here to see available models.": "",
 	"Click here to select": "Bấm vào đây để chọn",
 	"Click here to select a csv file.": "Nhấn vào đây để chọn tệp csv",
 	"Click here to select a py file.": "Nhấn vào đây để chọn tệp py",
@@ -290,6 +291,7 @@
 	"Documentation": "Tài liệu",
 	"Documents": "Tài liệu",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "không thực hiện bất kỳ kết nối ngoài nào, và dữ liệu của bạn vẫn được lưu trữ an toàn trên máy chủ lưu trữ cục bộ của bạn.",
+	"Domain Filter List": "",
 	"Don't have an account?": "Không có tài khoản?",
 	"don't install random functions from sources you don't trust.": "không cài đặt các function từ các nguồn mà bạn không tin tưởng.",
 	"don't install random tools from sources you don't trust.": "không cài đặt các tools từ các nguồn mà bạn không tin tưởng.",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "Nhập Chunk chồng lấn (overlap)",
 	"Enter Chunk Size": "Nhập Kích thước Chunk",
 	"Enter description": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "",
 	"Enter Github Raw URL": "Nhập URL cho Github Raw",
 	"Enter Google PSE API Key": "Nhập Google PSE API Key",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "",
 	"Knowledge reset successfully.": "",
 	"Knowledge updated successfully": "",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "",
 	"Landing Page Mode": "",
 	"Language": "Ngôn ngữ",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
 	"Leave empty to include all models or select specific models": "",
 	"Leave empty to use the default prompt, or enter a custom prompt": "",
+	"Leave model field empty to use the default model.": "",
 	"Light": "Sáng",
 	"Listening...": "Đang nghe...",
 	"Llama.cpp": "",
@@ -574,7 +580,7 @@
 	"Local Models": "",
 	"Lost": "",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "Được tạo bởi Cộng đồng OpenWebUI",
+	"Made by Open WebUI Community": "Được tạo bởi Cộng đồng OpenWebUI",
 	"Make sure to enclose them with": "Hãy chắc chắn bao quanh chúng bằng",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "Đảm bảo xuất tệp Workflow.json đúng format API của ComfyUI.",
 	"Manage": "Quản lý",
@@ -754,7 +760,7 @@
 	"Read Aloud": "Đọc ra loa",
 	"Reasoning Effort": "",
 	"Record voice": "Ghi âm",
-	"Redirecting you to OpenWebUI Community": "Đang chuyển hướng bạn đến Cộng đồng OpenWebUI",
+	"Redirecting you to Open WebUI Community": "Đang chuyển hướng bạn đến Cộng đồng 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. (Default: 40)": "",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Hãy coi bản thân mình như \"Người dùng\" (ví dụ: \"Người dùng đang học Tiếng Tây Ban Nha\")",
 	"References from": "",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "Cài đặt đã được lưu thành công!",
 	"Share": "Chia sẻ",
 	"Share Chat": "Chia sẻ Chat",
-	"Share to OpenWebUI Community": "Chia sẻ đến Cộng đồng OpenWebUI",
+	"Share to Open WebUI Community": "Chia sẻ đến Cộng đồng OpenWebUI",
 	"Show": "Hiển thị",
 	"Show \"What's New\" modal on login": "",
 	"Show Admin Details in Account Pending Overlay": "Hiển thị thông tin của Quản trị viên trên màn hình hiển thị Tài khoản đang chờ xử lý",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
 	"Thorough explanation": "Giải thích kỹ lưỡng",
 	"Thought for {{DURATION}}": "",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "",
 	"Tika Server URL required.": "Bắt buộc phải nhập URL cho Tika Server ",
 	"Tiktoken": "",

+ 20 - 13
src/lib/i18n/locales/zh-CN/translation.json

@@ -63,9 +63,9 @@
 	"Allowed Endpoints": "允许的端点",
 	"Already have an account?": "已经拥有账号了?",
 	"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "top_p的替代方法,目标是在质量和多样性之间取得平衡。参数p表示一个token相对于最有可能的token所需的最低概率。比如,当p=0.05且最有可能的token概率为0.9时,概率低于0.045的logits会被排除。(默认值:0.0)",
-	"Always": "",
+	"Always": "保持",
 	"Amazing": "很棒",
-	"an assistant": "AI模型",
+	"an assistant": "一个助手",
 	"Analyzed": "已分析",
 	"Analyzing...": "正在分析...",
 	"and": "和",
@@ -163,6 +163,7 @@
 	"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.": "点击此处选择 py 文件。",
@@ -183,8 +184,8 @@
 	"ComfyUI API Key": "ComfyUI API 密钥",
 	"ComfyUI Base URL": "ComfyUI 基础地址",
 	"ComfyUI Base URL is required.": "ComfyUI 基础地址为必需填写。",
-	"ComfyUI Workflow": "ComfyUI Workflow",
-	"ComfyUI Workflow Nodes": "ComfyUI Workflow 节点",
+	"ComfyUI Workflow": "ComfyUI 工作流",
+	"ComfyUI Workflow Nodes": "ComfyUI 工作流节点",
 	"Command": "命令",
 	"Completions": "续写",
 	"Concurrent Requests": "并发请求",
@@ -290,6 +291,7 @@
 	"Documentation": "帮助文档",
 	"Documents": "文档",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "不会与外部建立任何连接,您的数据会安全地存储在本地托管的服务器上。",
+	"Domain Filter List": "",
 	"Don't have an account?": "没有账号?",
 	"don't install random functions from sources you don't trust.": "切勿随意从不完全可信的来源安装函数。",
 	"don't install random tools from sources you don't trust.": "切勿随意从不完全可信的来源安装工具。",
@@ -349,6 +351,7 @@
 	"Enter Chunk Overlap": "输入块重叠 (Chunk Overlap)",
 	"Enter Chunk Size": "输入块大小 (Chunk Size)",
 	"Enter description": "输入简介描述",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
 	"Enter Exa API Key": "输入 Exa API 密钥",
 	"Enter Github Raw URL": "输入 Github Raw 地址",
 	"Enter Google PSE API Key": "输入 Google PSE API 密钥",
@@ -522,8 +525,8 @@
 	"Import Prompts": "导入提示词",
 	"Import Tools": "导入工具",
 	"Include": "包括",
-	"Include `--api-auth` flag when running stable-diffusion-webui": "运行 stable-diffusion-webui 时包含 `--api-auth` 标志",
-	"Include `--api` flag when running stable-diffusion-webui": "运行 stable-diffusion-webui 时包含 `--api` 标志",
+	"Include `--api-auth` flag when running stable-diffusion-webui": "运行 stable-diffusion-webui 时包含 `--api-auth` 参数",
+	"Include `--api` flag when running stable-diffusion-webui": "运行 stable-diffusion-webui 时包含 `--api` 参数",
 	"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. (Default: 0.1)": "影响算法对生成文本反馈的响应速度。较低的学习率会导致调整速度较慢,而较高的学习率会使算法更具响应性。(默认值:0.1)",
 	"Info": "信息",
 	"Input commands": "输入命令",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "知识成功删除",
 	"Knowledge reset successfully.": "知识成功重置",
 	"Knowledge updated successfully": "知识成功更新",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "标签",
 	"Landing Page Mode": "默认主页样式",
 	"Language": "语言",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "留空表示包含所有来自 \"{{URL}}/models\" 的模型",
 	"Leave empty to include all models or select specific models": "留空表示包含所有模型或请选择模型",
 	"Leave empty to use the default prompt, or enter a custom prompt": "留空以使用默认提示词,或输入自定义提示词。",
+	"Leave model field empty to use the default model.": "",
 	"Light": "浅色",
 	"Listening...": "正在倾听...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "本地模型",
 	"Lost": "落败",
 	"LTR": "从左至右",
-	"Made by OpenWebUI Community": "由 OpenWebUI 社区制作",
+	"Made by Open WebUI Community": "由 OpenWebUI 社区制作",
 	"Make sure to enclose them with": "确保将它们包含在内",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "确保从 ComfyUI 导出 API 格式的 workflow.json 文件。",
 	"Manage": "管理",
@@ -750,11 +756,11 @@
 	"RAG Template": "RAG 提示词模板",
 	"Rating": "评价",
 	"Re-rank models by topic similarity": "根据主题相似性对模型重新排序",
-	"Read": "读",
+	"Read": "读",
 	"Read Aloud": "朗读",
 	"Reasoning Effort": "推理努力",
 	"Record voice": "录音",
-	"Redirecting you to OpenWebUI Community": "正在将您重定向到 OpenWebUI 社区",
+	"Redirecting you to Open WebUI Community": "正在将您重定向到 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. (Default: 40)": "降低产生无意义答案的概率。数值越大(如 100),答案就越多样化,而数值越小(如 10),答案就越保守。(默认值:40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "使用\"User\" (用户) 来指代自己(例如:“User 正在学习西班牙语”)",
 	"References from": "来自",
@@ -799,10 +805,10 @@
 	"Scroll to bottom when switching between branches": "在分支间切换时滚动到底部",
 	"Search": "搜索",
 	"Search a model": "搜索模型",
-	"Search Base": "Search Base",
+	"Search Base": "搜索库",
 	"Search Chats": "搜索对话",
 	"Search Collection": "搜索内容",
-	"Search Filters": "Search Filters",
+	"Search Filters": "搜索过滤器",
 	"search for tags": "搜索标签",
 	"Search Functions": "搜索函数",
 	"Search Knowledge": "搜索知识",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "设置已保存",
 	"Share": "分享",
 	"Share Chat": "分享对话",
-	"Share to OpenWebUI Community": "分享到 OpenWebUI 社区",
+	"Share to Open WebUI Community": "分享到 OpenWebUI 社区",
 	"Show": "显示",
 	"Show \"What's New\" modal on login": "在登录时显示“更新内容”弹窗",
 	"Show Admin Details in Account Pending Overlay": "在用户待激活界面中显示管理员邮箱等详细信息",
@@ -943,7 +949,8 @@
 	"This will delete all models including custom models and cannot be undone.": "这将删除所有模型,包括自定义模型,且无法撤销。",
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "这将重置知识库并替换所有文件为目录下文件。确认继续?",
 	"Thorough explanation": "解释较为详细",
-	"Thought for {{DURATION}}": "思考时间 {{DURATION}}",
+	"Thought for {{DURATION}}": "已推理 持续 {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "已推理 持续 {{DURATION}} 秒",
 	"Tika": "Tika",
 	"Tika Server URL required.": "请输入 Tika 服务器地址。",
 	"Tiktoken": "Tiktoken",

+ 29 - 22
src/lib/i18n/locales/zh-TW/translation.json

@@ -63,11 +63,11 @@
 	"Allowed Endpoints": "允許的端點",
 	"Already have an account?": "已經有帳號了嗎?",
 	"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "作為 top_p 的替代方案,旨在確保質量和多樣性的平衡。相對於最可能的 token 機率而言,參數 p 代表一個 token 被考慮在内的最低機率。例如,當 p=0.05 且最可能的 token 機率為 0.9 時,數值低於 0.045 的對數機率會被過濾掉。(預設值:0.0)",
-	"Always": "",
+	"Always": "總是",
 	"Amazing": "很棒",
 	"an assistant": "一位助手",
-	"Analyzed": "",
-	"Analyzing...": "",
+	"Analyzed": "分析完畢",
+	"Analyzing...": "分析中……",
 	"and": "和",
 	"and {{COUNT}} more": "和另外 {{COUNT}} 個",
 	"and create a new shared link.": "並建立新的共用連結。",
@@ -163,6 +163,7 @@
 	"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 檔案。",
@@ -172,11 +173,11 @@
 	"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "剪貼簿寫入權限遭拒。請檢查您的瀏覽器設定,授予必要的存取權限。",
 	"Clone": "複製",
 	"Clone Chat": "複製對話",
-	"Clone of {{TITLE}}": "",
+	"Clone of {{TITLE}}": "{{TITLE}} 的副本",
 	"Close": "關閉",
 	"Code execution": "程式碼執行",
 	"Code formatted successfully": "程式碼格式化成功",
-	"Code Interpreter": "",
+	"Code Interpreter": "程式碼解釋器",
 	"Collection": "收藏",
 	"Color": "顏色",
 	"ComfyUI": "ComfyUI",
@@ -238,7 +239,7 @@
 	"Default": "預設",
 	"Default (Open AI)": "預設 (OpenAI)",
 	"Default (SentenceTransformers)": "預設 (SentenceTransformers)",
-	"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.": "",
+	"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.": "預設模式透過在執行前呼叫工具一次,來與更廣泛的模型相容。原生模式則利用模型內建的工具呼叫能力,但需要模型本身就支援此功能。",
 	"Default Model": "預設模型",
 	"Default model updated": "預設模型已更新",
 	"Default Models": "預設模型",
@@ -290,6 +291,7 @@
 	"Documentation": "文件",
 	"Documents": "文件",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "不會建立任何外部連線,而且您的資料會安全地儲存在您本機伺服器上。",
+	"Domain Filter List": "",
 	"Don't have an account?": "還沒註冊帳號嗎?",
 	"don't install random functions from sources you don't trust.": "請勿從您無法信任的來源安裝隨機函式。",
 	"don't install random tools from sources you don't trust.": "請勿從您無法信任的來源安裝隨機工具。",
@@ -349,7 +351,8 @@
 	"Enter Chunk Overlap": "輸入區塊重疊",
 	"Enter Chunk Size": "輸入區塊大小",
 	"Enter description": "輸入描述",
-	"Enter Exa API Key": "",
+	"Enter domains separated by commas (e.g., example.com,site.org)": "",
+	"Enter Exa API Key": "輸入 Exa API 金鑰",
 	"Enter Github Raw URL": "輸入 GitHub Raw URL",
 	"Enter Google PSE API Key": "輸入 Google PSE API 金鑰",
 	"Enter Google PSE Engine Id": "輸入 Google PSE 引擎 ID",
@@ -398,14 +401,14 @@
 	"Error accessing Google Drive: {{error}}": "存取 Google Drive 時發生錯誤:{{error}}",
 	"Error uploading file: {{error}}": "上傳檔案時發生錯誤:{{error}}",
 	"Evaluations": "評估",
-	"Exa API Key": "",
+	"Exa API Key": "Exa API 金鑰",
 	"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "範例:(&(objectClass=inetOrgPerson)(uid=%s))",
 	"Example: ALL": "範例:ALL",
 	"Example: mail": "範例:mail",
 	"Example: ou=users,dc=foo,dc=example": "範例:ou=users,dc=foo,dc=example",
 	"Example: sAMAccountName or uid or userPrincipalName": "範例:sAMAccountName 或 uid 或 userPrincipalName",
 	"Exclude": "排除",
-	"Execute code for analysis": "",
+	"Execute code for analysis": "執行程式碼以進行分析",
 	"Experimental": "實驗性功能",
 	"Explore the cosmos": "探索宇宙",
 	"Export": "匯出",
@@ -458,7 +461,7 @@
 	"Format your variables using brackets like this:": "使用方括號格式化您的變數,如下所示:",
 	"Frequency Penalty": "頻率懲罰",
 	"Function": "函式",
-	"Function Calling": "",
+	"Function Calling": "函式呼叫",
 	"Function created successfully": "成功建立函式",
 	"Function deleted successfully": "成功刪除函式",
 	"Function Description": "函式描述",
@@ -473,7 +476,7 @@
 	"Functions imported successfully": "成功匯入函式",
 	"General": "一般",
 	"General Settings": "一般設定",
-	"Generate an image": "",
+	"Generate an image": "產生圖片",
 	"Generate Image": "產生圖片",
 	"Generating search query": "正在產生搜尋查詢",
 	"Get started": "開始使用",
@@ -552,6 +555,8 @@
 	"Knowledge deleted successfully.": "知識刪除成功。",
 	"Knowledge reset successfully.": "知識重設成功。",
 	"Knowledge updated successfully": "知識更新成功",
+	"Kokoro.js (Browser)": "",
+	"Kokoro.js Dtype": "",
 	"Label": "標籤",
 	"Landing Page Mode": "首頁模式",
 	"Language": "語言",
@@ -566,6 +571,7 @@
 	"Leave empty to include all models from \"{{URL}}/models\" endpoint": "留空以包含來自 \"{{URL}}/models\" 端點的所有模型",
 	"Leave empty to include all models or select specific models": "留空以包含所有模型或選擇特定模型",
 	"Leave empty to use the default prompt, or enter a custom prompt": "留空以使用預設提示詞,或輸入自訂提示詞",
+	"Leave model field empty to use the default model.": "",
 	"Light": "淺色",
 	"Listening...": "正在聆聽...",
 	"Llama.cpp": "Llama.cpp",
@@ -574,7 +580,7 @@
 	"Local Models": "本機模型",
 	"Lost": "已遺失",
 	"LTR": "從左到右",
-	"Made by OpenWebUI Community": "由 OpenWebUI 社群製作",
+	"Made by Open WebUI Community": "由 OpenWebUI 社群製作",
 	"Make sure to enclose them with": "請務必將它們放在",
 	"Make sure to export a workflow.json file as API format from ComfyUI.": "請確保從 ComfyUI 匯出 workflow.json 檔案為 API 格式。",
 	"Manage": "管理",
@@ -630,7 +636,7 @@
 	"More": "更多",
 	"Name": "名稱",
 	"Name your knowledge base": "命名您的知識庫",
-	"Native": "",
+	"Native": "原生",
 	"New Chat": "新增對話",
 	"New Folder": "新增資料夾",
 	"New Password": "新密碼",
@@ -725,7 +731,7 @@
 	"Please enter a prompt": "請輸入提示詞",
 	"Please fill in all fields.": "請填寫所有欄位。",
 	"Please select a model first.": "請先選擇型號。",
-	"Please select a model.": "",
+	"Please select a model.": "請選擇一個模型。",
 	"Please select a reason": "請選擇原因",
 	"Port": "連接埠",
 	"Positive attitude": "積極的態度",
@@ -734,7 +740,7 @@
 	"Previous 30 days": "過去 30 天",
 	"Previous 7 days": "過去 7 天",
 	"Profile Image": "個人檔案圖片",
-	"Prompt": "",
+	"Prompt": "提示詞",
 	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "提示詞(例如:告訴我關於羅馬帝國的一些趣事)",
 	"Prompt Content": "提示詞內容",
 	"Prompt created successfully": "提示詞建立成功",
@@ -754,7 +760,7 @@
 	"Read Aloud": "大聲朗讀",
 	"Reasoning Effort": "推理程度",
 	"Record voice": "錄音",
-	"Redirecting you to OpenWebUI Community": "正在將您重導向至 OpenWebUI 社群",
+	"Redirecting you to Open WebUI Community": "正在將您重導向至 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. (Default: 40)": "降低產生無意義內容的機率。較高的值(例如 100)會給出更多樣化的答案,而較低的值(例如 10)會更保守。(預設:40)",
 	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "以「使用者」稱呼自己(例如:「使用者正在學習西班牙文」)",
 	"References from": "引用來源",
@@ -810,7 +816,7 @@
 	"Search options": "搜尋選項",
 	"Search Prompts": "搜尋提示詞",
 	"Search Result Count": "搜尋結果數量",
-	"Search the internet": "",
+	"Search the internet": "搜尋網際網路",
 	"Search Tools": "搜尋工具",
 	"SearchApi API Key": "SearchApi API 金鑰",
 	"SearchApi Engine": "SearchApi 引擎",
@@ -869,7 +875,7 @@
 	"Settings saved successfully!": "設定已成功儲存!",
 	"Share": "分享",
 	"Share Chat": "分享對話",
-	"Share to OpenWebUI Community": "分享到 OpenWebUI 社群",
+	"Share to Open WebUI Community": "分享到 OpenWebUI 社群",
 	"Show": "顯示",
 	"Show \"What's New\" modal on login": "登入時顯示「新功能」對話框",
 	"Show Admin Details in Account Pending Overlay": "在帳號待審覆蓋層中顯示管理員詳細資訊",
@@ -944,6 +950,7 @@
 	"This will reset the knowledge base and sync all files. Do you wish to continue?": "這將重設知識庫並同步所有檔案。您確定要繼續嗎?",
 	"Thorough explanation": "詳細解釋",
 	"Thought for {{DURATION}}": "思考時間 {{DURATION}}",
+	"Thought for {{DURATION}} seconds": "",
 	"Tika": "Tika",
 	"Tika Server URL required.": "需要 Tika 伺服器 URL。",
 	"Tiktoken": "Tiktoken",
@@ -980,7 +987,7 @@
 	"Tools": "工具",
 	"Tools Access": "工具存取",
 	"Tools are a function calling system with arbitrary code execution": "工具是一個具有任意程式碼執行功能的函式呼叫系統",
-	"Tools Function Calling Prompt": "",
+	"Tools Function Calling Prompt": "工具函式呼叫提示詞",
 	"Tools have a function calling system that allows arbitrary code execution": "工具具有允許執行任意程式碼的函式呼叫系統",
 	"Tools have a function calling system that allows arbitrary code execution.": "工具具有允許執行任意程式碼的函式呼叫系統。",
 	"Top K": "Top K",
@@ -1051,7 +1058,7 @@
 	"Web Loader Settings": "網頁載入器設定",
 	"Web Search": "網頁搜尋",
 	"Web Search Engine": "網頁搜尋引擎",
-	"Web Search in Chat": "",
+	"Web Search in Chat": "在對話中進行網路搜尋",
 	"Web Search Query Generation": "網頁搜尋查詢生成",
 	"Webhook URL": "Webhook URL",
 	"WebUI Settings": "WebUI 設定",
@@ -1081,8 +1088,8 @@
 	"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "您可以透過下方的「管理」按鈕新增記憶,將您與大型語言模型的互動個人化,讓它們更有幫助並更符合您的需求。",
 	"You cannot upload an empty file.": "您無法上傳空檔案",
 	"You do not have permission to access this feature.": "您沒有權限訪問此功能",
-	"You do not have permission to upload files": "",
-	"You do not have permission to upload files.": "您沒有權限上傳檔案",
+	"You do not have permission to upload files": "您沒有權限上傳檔案",
+	"You do not have permission to upload files.": "您沒有權限上傳檔案",
 	"You have no archived conversations.": "您沒有已封存的對話。",
 	"You have shared this chat": "您已分享此對話",
 	"You're a helpful assistant.": "您是一位樂於助人的助手。",

+ 3 - 0
src/lib/stores/index.ts

@@ -41,6 +41,8 @@ export const shortCodesToEmojis = writable(
 	}, {})
 );
 
+export const TTSWorker = writable(null);
+
 export const chatId = writable('');
 export const chatTitle = writable('');
 
@@ -206,6 +208,7 @@ type Config = {
 		enable_admin_export: boolean;
 		enable_admin_chat_access: boolean;
 		enable_community_sharing: boolean;
+		enable_autocomplete_generation: boolean;
 	};
 	oauth: {
 		providers: {

+ 106 - 0
src/lib/workers/KokoroWorker.ts

@@ -0,0 +1,106 @@
+import WorkerInstance from '$lib/workers/kokoro.worker?worker';
+
+export class KokoroWorker {
+	private worker: Worker | null = null;
+	private initialized: boolean = false;
+	private dtype: string;
+	private requestQueue: Array<{
+		text: string;
+		voice: string;
+		resolve: (value: string) => void;
+		reject: (reason: any) => void;
+	}> = [];
+	private processing = false; // To track if a request is being processed
+
+	constructor(dtype: string = 'fp32') {
+		this.dtype = dtype;
+	}
+
+	public async init() {
+		if (this.worker) {
+			console.warn('KokoroWorker is already initialized.');
+			return;
+		}
+
+		this.worker = new WorkerInstance();
+
+		// Handle worker messages
+		this.worker.onmessage = (event) => {
+			const { status, error, audioUrl } = event.data;
+
+			if (status === 'init:complete') {
+				this.initialized = true;
+			} else if (status === 'init:error') {
+				console.error(error);
+				this.initialized = false;
+			} else if (status === 'generate:complete') {
+				// Resolve promise from queue
+				const request = this.requestQueue.shift();
+				if (request) {
+					request.resolve(audioUrl);
+					this.processNextRequest(); // Process next request in queue
+				}
+			} else if (status === 'generate:error') {
+				const request = this.requestQueue.shift();
+				if (request) {
+					request.reject(new Error(error));
+					this.processNextRequest(); // Continue processing next in queue
+				}
+			}
+		};
+
+		return new Promise<void>((resolve, reject) => {
+			this.worker!.postMessage({
+				type: 'init',
+				payload: { dtype: this.dtype }
+			});
+
+			const handleMessage = (event: MessageEvent) => {
+				if (event.data.status === 'init:complete') {
+					this.worker!.removeEventListener('message', handleMessage);
+					this.initialized = true;
+					resolve();
+				} else if (event.data.status === 'init:error') {
+					this.worker!.removeEventListener('message', handleMessage);
+					reject(new Error(event.data.error));
+				}
+			};
+
+			this.worker!.addEventListener('message', handleMessage);
+		});
+	}
+
+	public async generate({ text, voice }: { text: string; voice: string }): Promise<string> {
+		if (!this.initialized || !this.worker) {
+			throw new Error('KokoroTTS Worker is not initialized yet.');
+		}
+
+		return new Promise<string>((resolve, reject) => {
+			this.requestQueue.push({ text, voice, resolve, reject });
+			if (!this.processing) {
+				this.processNextRequest();
+			}
+		});
+	}
+
+	private processNextRequest() {
+		if (this.requestQueue.length === 0) {
+			this.processing = false;
+			return;
+		}
+
+		this.processing = true;
+		const { text, voice } = this.requestQueue[0]; // Get first request but don't remove yet
+		this.worker!.postMessage({ type: 'generate', payload: { text, voice } });
+	}
+
+	public terminate() {
+		if (this.worker) {
+			this.worker.terminate();
+			this.worker = null;
+			this.initialized = false;
+			this.requestQueue = [];
+			this.processing = false;
+		}
+	}
+}

+ 57 - 0
src/lib/workers/kokoro.worker.ts

@@ -0,0 +1,57 @@
+import { env } from '@huggingface/transformers';
+import { KokoroTTS } from 'kokoro-js';
+
+// TODO: Below doesn't work as expected, need to investigate further
+env.backends.onnx.wasm.wasmPaths = '/wasm/';
+
+let tts;
+let isInitialized = false; // Flag to track initialization status
+const DEFAULT_MODEL_ID = 'onnx-community/Kokoro-82M-v1.0-ONNX'; // Default model
+
+self.onmessage = async (event) => {
+	const { type, payload } = event.data;
+
+	if (type === 'init') {
+		let { model_id, dtype } = payload;
+		model_id = model_id || DEFAULT_MODEL_ID; // Use default model if none provided
+
+		self.postMessage({ status: 'init:start' });
+
+		try {
+			tts = await KokoroTTS.from_pretrained(model_id, {
+				dtype,
+				device: !!navigator?.gpu ? 'webgpu' : 'wasm' // Detect WebGPU
+			});
+			isInitialized = true; // Mark as initialized after successful loading
+			self.postMessage({ status: 'init:complete' });
+		} catch (error) {
+			isInitialized = false; // Ensure it's marked as false on failure
+			self.postMessage({ status: 'init:error', error: error.message });
+		}
+	}
+
+	if (type === 'generate') {
+		if (!isInitialized || !tts) {
+			// Ensure model is initialized
+			self.postMessage({ status: 'generate:error', error: 'TTS model not initialized' });
+			return;
+		}
+
+		const { text, voice } = payload;
+		self.postMessage({ status: 'generate:start' });
+
+		try {
+			const rawAudio = await tts.generate(text, { voice });
+			const blob = await rawAudio.toBlob();
+			const blobUrl = URL.createObjectURL(blob);
+			self.postMessage({ status: 'generate:complete', audioUrl: blobUrl });
+		} catch (error) {
+			self.postMessage({ status: 'generate:error', error: error.message });
+		}
+	}
+
+	if (type === 'status') {
+		// Respond with the current initialization status
+		self.postMessage({ status: 'status:check', initialized: isInitialized });
+	}
+};

Some files were not shown because too many files changed in this diff