Browse Source

Merge pull request #2921 from open-webui/dev

0.3.0
Timothy Jaeryang Baek 11 months ago
parent
commit
96a004d4d8
100 changed files with 7197 additions and 2142 deletions
  1. 33 0
      CHANGELOG.md
  2. 11 2
      README.md
  3. 209 61
      backend/apps/audio/main.py
  4. 7 6
      backend/apps/ollama/main.py
  5. 128 81
      backend/apps/openai/main.py
  6. 12 0
      backend/apps/rag/main.py
  7. 3 44
      backend/apps/rag/utils.py
  8. 25 6
      backend/apps/socket/main.py
  9. 114 17
      backend/config.py
  10. 349 86
      backend/main.py
  11. 4 1
      backend/requirements.txt
  12. 2 2
      backend/start.sh
  13. 48 1
      backend/utils/misc.py
  14. 0 10
      backend/utils/models.py
  15. 112 0
      backend/utils/task.py
  16. 1 1
      docs/CONTRIBUTING.md
  17. 2 2
      package-lock.json
  18. 1 1
      package.json
  19. 18 9
      src/app.html
  20. 3 3
      src/lib/apis/audio/index.ts
  21. 178 0
      src/lib/apis/index.ts
  22. 390 0
      src/lib/components/admin/Settings.svelte
  23. 302 0
      src/lib/components/admin/Settings/Audio.svelte
  24. 0 137
      src/lib/components/admin/Settings/Banners.svelte
  25. 7 3
      src/lib/components/admin/Settings/Connections.svelte
  26. 1 1
      src/lib/components/admin/Settings/Database.svelte
  27. 144 7
      src/lib/components/admin/Settings/Documents.svelte
  28. 1 1
      src/lib/components/admin/Settings/General.svelte
  29. 3 5
      src/lib/components/admin/Settings/Images.svelte
  30. 339 0
      src/lib/components/admin/Settings/Interface.svelte
  31. 1078 0
      src/lib/components/admin/Settings/Models.svelte
  32. 128 2
      src/lib/components/admin/Settings/Pipelines.svelte
  33. 2 2
      src/lib/components/admin/Settings/Users.svelte
  34. 285 0
      src/lib/components/admin/Settings/WebSearch.svelte
  35. 0 176
      src/lib/components/admin/SettingsModal.svelte
  36. 114 124
      src/lib/components/chat/Chat.svelte
  37. 394 542
      src/lib/components/chat/MessageInput.svelte
  38. 693 0
      src/lib/components/chat/MessageInput/CallOverlay.svelte
  39. 51 0
      src/lib/components/chat/MessageInput/CallOverlay/VideoInputMenu.svelte
  40. 1 1
      src/lib/components/chat/MessageInput/Documents.svelte
  41. 1 1
      src/lib/components/chat/MessageInput/Models.svelte
  42. 28 1
      src/lib/components/chat/MessageInput/PromptCommands.svelte
  43. 458 0
      src/lib/components/chat/MessageInput/VoiceRecording.svelte
  44. 1 1
      src/lib/components/chat/Messages/CompareMessages.svelte
  45. 18 7
      src/lib/components/chat/Messages/ResponseMessage.svelte
  46. 2 2
      src/lib/components/chat/ModelSelector/Selector.svelte
  47. 2 2
      src/lib/components/chat/Settings/About.svelte
  48. 1 1
      src/lib/components/chat/Settings/Account.svelte
  49. 1 1
      src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte
  50. 38 201
      src/lib/components/chat/Settings/Audio.svelte
  51. 2 2
      src/lib/components/chat/Settings/Chats.svelte
  52. 2 2
      src/lib/components/chat/Settings/General.svelte
  53. 0 181
      src/lib/components/chat/Settings/Interface.svelte
  54. 2 2
      src/lib/components/chat/Settings/Models.svelte
  55. 7 4
      src/lib/components/chat/Settings/Personalization.svelte
  56. 1 1
      src/lib/components/chat/Settings/Personalization/AddMemoryModal.svelte
  57. 2 2
      src/lib/components/chat/Settings/Personalization/ManageModal.svelte
  58. 10 79
      src/lib/components/chat/SettingsModal.svelte
  59. 1 1
      src/lib/components/common/Selector.svelte
  60. 1 1
      src/lib/components/documents/Settings/QueryParams.svelte
  61. 2 2
      src/lib/components/documents/Settings/WebParams.svelte
  62. 20 0
      src/lib/components/icons/Headphone.svelte
  63. 7 4
      src/lib/components/layout/Overlay/AccountPending.svelte
  64. 4 0
      src/lib/components/layout/Sidebar.svelte
  65. 1 1
      src/lib/components/layout/Sidebar/UserMenu.svelte
  66. 9 34
      src/lib/components/workspace/Documents.svelte
  67. 13 10
      src/lib/components/workspace/Models.svelte
  68. 106 0
      src/lib/components/workspace/Models/Knowledge.svelte
  69. 138 0
      src/lib/components/workspace/Models/Knowledge/Selector.svelte
  70. 8 18
      src/lib/components/workspace/Playground.svelte
  71. 2 1
      src/lib/constants.ts
  72. 38 8
      src/lib/i18n/locales/ar-BH/translation.json
  73. 38 8
      src/lib/i18n/locales/bg-BG/translation.json
  74. 38 8
      src/lib/i18n/locales/bn-BD/translation.json
  75. 38 8
      src/lib/i18n/locales/ca-ES/translation.json
  76. 38 8
      src/lib/i18n/locales/ceb-PH/translation.json
  77. 56 26
      src/lib/i18n/locales/de-DE/translation.json
  78. 38 8
      src/lib/i18n/locales/dg-DG/translation.json
  79. 36 6
      src/lib/i18n/locales/en-GB/translation.json
  80. 36 6
      src/lib/i18n/locales/en-US/translation.json
  81. 38 8
      src/lib/i18n/locales/es-ES/translation.json
  82. 38 8
      src/lib/i18n/locales/fa-IR/translation.json
  83. 38 8
      src/lib/i18n/locales/fi-FI/translation.json
  84. 38 8
      src/lib/i18n/locales/fr-CA/translation.json
  85. 38 8
      src/lib/i18n/locales/fr-FR/translation.json
  86. 38 8
      src/lib/i18n/locales/he-IL/translation.json
  87. 38 8
      src/lib/i18n/locales/hi-IN/translation.json
  88. 38 8
      src/lib/i18n/locales/hr-HR/translation.json
  89. 38 8
      src/lib/i18n/locales/it-IT/translation.json
  90. 38 8
      src/lib/i18n/locales/ja-JP/translation.json
  91. 38 8
      src/lib/i18n/locales/ka-GE/translation.json
  92. 38 8
      src/lib/i18n/locales/ko-KR/translation.json
  93. 38 8
      src/lib/i18n/locales/lt-LT/translation.json
  94. 38 8
      src/lib/i18n/locales/nb-NO/translation.json
  95. 38 8
      src/lib/i18n/locales/nl-NL/translation.json
  96. 38 8
      src/lib/i18n/locales/pa-IN/translation.json
  97. 38 8
      src/lib/i18n/locales/pl-PL/translation.json
  98. 38 8
      src/lib/i18n/locales/pt-BR/translation.json
  99. 38 8
      src/lib/i18n/locales/pt-PT/translation.json
  100. 38 8
      src/lib/i18n/locales/ru-RU/translation.json

+ 33 - 0
CHANGELOG.md

@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.3.0] - 2024-06-09
+
+### Added
+
+- **📚 Knowledge Support for Models**: Attach documents directly to models from the models workspace, enhancing the information available to each model.
+- **🎙️ Hands-Free Voice Call Feature**: Initiate voice calls without needing to use your hands, making interactions more seamless.
+- **📹 Video Call Feature**: Enable video calls with supported vision models like Llava and GPT-4o, adding a visual dimension to your communications.
+- **🎛️ Enhanced UI for Voice Recording**: Improved user interface for the voice recording feature, making it more intuitive and user-friendly.
+- **🌐 External STT Support**: Now support for external Speech-To-Text services, providing more flexibility in choosing your STT provider.
+- **⚙️ Unified Settings**: Consolidated settings including document settings under a new admin settings section for easier management.
+- **🌑 Dark Mode Splash Screen**: A new splash screen for dark mode, ensuring a consistent and visually appealing experience for dark mode users.
+- **📥 Upload Pipeline**: Directly upload pipelines from the admin settings > pipelines section, streamlining the pipeline management process.
+- **🌍 Improved Language Support**: Enhanced support for Chinese and Ukrainian languages, better catering to a global user base.
+
+### Fixed
+
+- **🛠️ Playground Issue**: Fixed the playground not functioning properly, ensuring a smoother user experience.
+- **🔥 Temperature Parameter Issue**: Corrected the issue where the temperature value '0' was not being passed correctly.
+- **📝 Prompt Input Clearing**: Resolved prompt input textarea not being cleared right away, ensuring a clean slate for new inputs.
+- **✨ Various UI Styling Issues**: Fixed numerous user interface styling problems for a more cohesive look.
+- **👥 Active Users Display**: Fixed active users showing active sessions instead of actual users, now reflecting accurate user activity.
+- **🌐 Community Platform Compatibility**: The Community Platform is back online and fully compatible with Open WebUI.
+
+### Changed
+
+- **📝 RAG Implementation**: Updated the RAG (Retrieval-Augmented Generation) implementation to use a system prompt for context, instead of overriding the user's prompt.
+- **🔄 Settings Relocation**: Moved Models, Connections, Audio, and Images settings to the admin settings for better organization.
+- **✍️ Improved Title Generation**: Enhanced the default prompt for title generation, yielding better results.
+- **🔧 Backend Task Management**: Tasks like title generation and search query generation are now managed on the backend side and controlled only by the admin.
+- **🔍 Editable Search Query Prompt**: You can now edit the search query generation prompt, offering more control over how queries are generated.
+- **📏 Prompt Length Threshold**: Set the prompt length threshold for search query generation from the admin settings, giving more customization options.
+- **📣 Settings Consolidation**: Merged the Banners admin setting with the Interface admin setting for a more streamlined settings area.
+
 ## [0.2.5] - 2024-06-05
 
 ### Added

+ 11 - 2
README.md

@@ -146,10 +146,19 @@ 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.
 
-### Moving from Ollama WebUI to Open WebUI
-
 Check our Migration Guide available in our [Open WebUI Documentation](https://docs.openwebui.com/migration/).
 
+### Using the Dev Branch 🌙
+
+> [!WARNING]
+> The `:dev` branch contains the latest unstable features and changes. Use it at your own risk as it may have bugs or incomplete features.
+
+If you want to try out the latest bleeding-edge features and are okay with occasional instability, you can use the `:dev` tag like this:
+
+```bash
+docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:dev
+```
+
 ## What's Next? 🌟
 
 Discover upcoming features on our roadmap in the [Open WebUI Documentation](https://docs.openwebui.com/roadmap/).

+ 209 - 61
backend/apps/audio/main.py

@@ -17,13 +17,12 @@ from fastapi.middleware.cors import CORSMiddleware
 from faster_whisper import WhisperModel
 from pydantic import BaseModel
 
-
+import uuid
 import requests
 import hashlib
 from pathlib import Path
 import json
 
-
 from constants import ERROR_MESSAGES
 from utils.utils import (
     decode_token,
@@ -41,10 +40,15 @@ from config import (
     WHISPER_MODEL_DIR,
     WHISPER_MODEL_AUTO_UPDATE,
     DEVICE_TYPE,
-    AUDIO_OPENAI_API_BASE_URL,
-    AUDIO_OPENAI_API_KEY,
-    AUDIO_OPENAI_API_MODEL,
-    AUDIO_OPENAI_API_VOICE,
+    AUDIO_STT_OPENAI_API_BASE_URL,
+    AUDIO_STT_OPENAI_API_KEY,
+    AUDIO_TTS_OPENAI_API_BASE_URL,
+    AUDIO_TTS_OPENAI_API_KEY,
+    AUDIO_STT_ENGINE,
+    AUDIO_STT_MODEL,
+    AUDIO_TTS_ENGINE,
+    AUDIO_TTS_MODEL,
+    AUDIO_TTS_VOICE,
     AppConfig,
 )
 
@@ -61,10 +65,17 @@ app.add_middleware(
 )
 
 app.state.config = AppConfig()
-app.state.config.OPENAI_API_BASE_URL = AUDIO_OPENAI_API_BASE_URL
-app.state.config.OPENAI_API_KEY = AUDIO_OPENAI_API_KEY
-app.state.config.OPENAI_API_MODEL = AUDIO_OPENAI_API_MODEL
-app.state.config.OPENAI_API_VOICE = AUDIO_OPENAI_API_VOICE
+
+app.state.config.STT_OPENAI_API_BASE_URL = AUDIO_STT_OPENAI_API_BASE_URL
+app.state.config.STT_OPENAI_API_KEY = AUDIO_STT_OPENAI_API_KEY
+app.state.config.STT_ENGINE = AUDIO_STT_ENGINE
+app.state.config.STT_MODEL = AUDIO_STT_MODEL
+
+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
+app.state.config.TTS_ENGINE = AUDIO_TTS_ENGINE
+app.state.config.TTS_MODEL = AUDIO_TTS_MODEL
+app.state.config.TTS_VOICE = AUDIO_TTS_VOICE
 
 # setting device type for whisper model
 whisper_device_type = DEVICE_TYPE if DEVICE_TYPE and DEVICE_TYPE == "cuda" else "cpu"
@@ -74,41 +85,101 @@ SPEECH_CACHE_DIR = Path(CACHE_DIR).joinpath("./audio/speech/")
 SPEECH_CACHE_DIR.mkdir(parents=True, exist_ok=True)
 
 
-class OpenAIConfigUpdateForm(BaseModel):
-    url: str
-    key: str
-    model: str
-    speaker: str
+class TTSConfigForm(BaseModel):
+    OPENAI_API_BASE_URL: str
+    OPENAI_API_KEY: str
+    ENGINE: str
+    MODEL: str
+    VOICE: str
+
+
+class STTConfigForm(BaseModel):
+    OPENAI_API_BASE_URL: str
+    OPENAI_API_KEY: str
+    ENGINE: str
+    MODEL: str
+
+
+class AudioConfigUpdateForm(BaseModel):
+    tts: TTSConfigForm
+    stt: STTConfigForm
+
+
+from pydub import AudioSegment
+from pydub.utils import mediainfo
+
+
+def is_mp4_audio(file_path):
+    """Check if the given file is an MP4 audio file."""
+    if not os.path.isfile(file_path):
+        print(f"File not found: {file_path}")
+        return False
+
+    info = mediainfo(file_path)
+    if (
+        info.get("codec_name") == "aac"
+        and info.get("codec_type") == "audio"
+        and info.get("codec_tag_string") == "mp4a"
+    ):
+        return True
+    return False
+
+
+def convert_mp4_to_wav(file_path, output_path):
+    """Convert MP4 audio file to WAV format."""
+    audio = AudioSegment.from_file(file_path, format="mp4")
+    audio.export(output_path, format="wav")
+    print(f"Converted {file_path} to {output_path}")
 
 
 @app.get("/config")
-async def get_openai_config(user=Depends(get_admin_user)):
+async def get_audio_config(user=Depends(get_admin_user)):
     return {
-        "OPENAI_API_BASE_URL": app.state.config.OPENAI_API_BASE_URL,
-        "OPENAI_API_KEY": app.state.config.OPENAI_API_KEY,
-        "OPENAI_API_MODEL": app.state.config.OPENAI_API_MODEL,
-        "OPENAI_API_VOICE": app.state.config.OPENAI_API_VOICE,
+        "tts": {
+            "OPENAI_API_BASE_URL": app.state.config.TTS_OPENAI_API_BASE_URL,
+            "OPENAI_API_KEY": app.state.config.TTS_OPENAI_API_KEY,
+            "ENGINE": app.state.config.TTS_ENGINE,
+            "MODEL": app.state.config.TTS_MODEL,
+            "VOICE": app.state.config.TTS_VOICE,
+        },
+        "stt": {
+            "OPENAI_API_BASE_URL": app.state.config.STT_OPENAI_API_BASE_URL,
+            "OPENAI_API_KEY": app.state.config.STT_OPENAI_API_KEY,
+            "ENGINE": app.state.config.STT_ENGINE,
+            "MODEL": app.state.config.STT_MODEL,
+        },
     }
 
 
 @app.post("/config/update")
-async def update_openai_config(
-    form_data: OpenAIConfigUpdateForm, user=Depends(get_admin_user)
+async def update_audio_config(
+    form_data: AudioConfigUpdateForm, user=Depends(get_admin_user)
 ):
-    if form_data.key == "":
-        raise HTTPException(status_code=400, detail=ERROR_MESSAGES.API_KEY_NOT_FOUND)
+    app.state.config.TTS_OPENAI_API_BASE_URL = form_data.tts.OPENAI_API_BASE_URL
+    app.state.config.TTS_OPENAI_API_KEY = form_data.tts.OPENAI_API_KEY
+    app.state.config.TTS_ENGINE = form_data.tts.ENGINE
+    app.state.config.TTS_MODEL = form_data.tts.MODEL
+    app.state.config.TTS_VOICE = form_data.tts.VOICE
 
-    app.state.config.OPENAI_API_BASE_URL = form_data.url
-    app.state.config.OPENAI_API_KEY = form_data.key
-    app.state.config.OPENAI_API_MODEL = form_data.model
-    app.state.config.OPENAI_API_VOICE = form_data.speaker
+    app.state.config.STT_OPENAI_API_BASE_URL = form_data.stt.OPENAI_API_BASE_URL
+    app.state.config.STT_OPENAI_API_KEY = form_data.stt.OPENAI_API_KEY
+    app.state.config.STT_ENGINE = form_data.stt.ENGINE
+    app.state.config.STT_MODEL = form_data.stt.MODEL
 
     return {
-        "status": True,
-        "OPENAI_API_BASE_URL": app.state.config.OPENAI_API_BASE_URL,
-        "OPENAI_API_KEY": app.state.config.OPENAI_API_KEY,
-        "OPENAI_API_MODEL": app.state.config.OPENAI_API_MODEL,
-        "OPENAI_API_VOICE": app.state.config.OPENAI_API_VOICE,
+        "tts": {
+            "OPENAI_API_BASE_URL": app.state.config.TTS_OPENAI_API_BASE_URL,
+            "OPENAI_API_KEY": app.state.config.TTS_OPENAI_API_KEY,
+            "ENGINE": app.state.config.TTS_ENGINE,
+            "MODEL": app.state.config.TTS_MODEL,
+            "VOICE": app.state.config.TTS_VOICE,
+        },
+        "stt": {
+            "OPENAI_API_BASE_URL": app.state.config.STT_OPENAI_API_BASE_URL,
+            "OPENAI_API_KEY": app.state.config.STT_OPENAI_API_KEY,
+            "ENGINE": app.state.config.STT_ENGINE,
+            "MODEL": app.state.config.STT_MODEL,
+        },
     }
 
 
@@ -125,13 +196,21 @@ async def speech(request: Request, user=Depends(get_verified_user)):
         return FileResponse(file_path)
 
     headers = {}
-    headers["Authorization"] = f"Bearer {app.state.config.OPENAI_API_KEY}"
+    headers["Authorization"] = f"Bearer {app.state.config.TTS_OPENAI_API_KEY}"
     headers["Content-Type"] = "application/json"
 
+    try:
+        body = body.decode("utf-8")
+        body = json.loads(body)
+        body["model"] = app.state.config.TTS_MODEL
+        body = json.dumps(body).encode("utf-8")
+    except Exception as e:
+        pass
+
     r = None
     try:
         r = requests.post(
-            url=f"{app.state.config.OPENAI_API_BASE_URL}/audio/speech",
+            url=f"{app.state.config.TTS_OPENAI_API_BASE_URL}/audio/speech",
             data=body,
             headers=headers,
             stream=True,
@@ -181,41 +260,110 @@ def transcribe(
         )
 
     try:
-        filename = file.filename
-        file_path = f"{UPLOAD_DIR}/{filename}"
+        ext = file.filename.split(".")[-1]
+
+        id = uuid.uuid4()
+        filename = f"{id}.{ext}"
+
+        file_dir = f"{CACHE_DIR}/audio/transcriptions"
+        os.makedirs(file_dir, exist_ok=True)
+        file_path = f"{file_dir}/{filename}"
+
+        print(filename)
+
         contents = file.file.read()
         with open(file_path, "wb") as f:
             f.write(contents)
             f.close()
 
-        whisper_kwargs = {
-            "model_size_or_path": WHISPER_MODEL,
-            "device": whisper_device_type,
-            "compute_type": "int8",
-            "download_root": WHISPER_MODEL_DIR,
-            "local_files_only": not WHISPER_MODEL_AUTO_UPDATE,
-        }
-
-        log.debug(f"whisper_kwargs: {whisper_kwargs}")
-
-        try:
-            model = WhisperModel(**whisper_kwargs)
-        except:
-            log.warning(
-                "WhisperModel initialization failed, attempting download with local_files_only=False"
+        if app.state.config.STT_ENGINE == "":
+            whisper_kwargs = {
+                "model_size_or_path": WHISPER_MODEL,
+                "device": whisper_device_type,
+                "compute_type": "int8",
+                "download_root": WHISPER_MODEL_DIR,
+                "local_files_only": not WHISPER_MODEL_AUTO_UPDATE,
+            }
+
+            log.debug(f"whisper_kwargs: {whisper_kwargs}")
+
+            try:
+                model = WhisperModel(**whisper_kwargs)
+            except:
+                log.warning(
+                    "WhisperModel initialization failed, attempting download with local_files_only=False"
+                )
+                whisper_kwargs["local_files_only"] = False
+                model = WhisperModel(**whisper_kwargs)
+
+            segments, info = model.transcribe(file_path, beam_size=5)
+            log.info(
+                "Detected language '%s' with probability %f"
+                % (info.language, info.language_probability)
             )
-            whisper_kwargs["local_files_only"] = False
-            model = WhisperModel(**whisper_kwargs)
 
-        segments, info = model.transcribe(file_path, beam_size=5)
-        log.info(
-            "Detected language '%s' with probability %f"
-            % (info.language, info.language_probability)
-        )
+            transcript = "".join([segment.text for segment in list(segments)])
 
-        transcript = "".join([segment.text for segment in list(segments)])
+            data = {"text": transcript.strip()}
 
-        return {"text": transcript.strip()}
+            # save the transcript to a json file
+            transcript_file = f"{file_dir}/{id}.json"
+            with open(transcript_file, "w") as f:
+                json.dump(data, f)
+
+            print(data)
+
+            return data
+
+        elif app.state.config.STT_ENGINE == "openai":
+            if is_mp4_audio(file_path):
+                print("is_mp4_audio")
+                os.rename(file_path, file_path.replace(".wav", ".mp4"))
+                # Convert MP4 audio file to WAV format
+                convert_mp4_to_wav(file_path.replace(".wav", ".mp4"), file_path)
+
+            headers = {"Authorization": f"Bearer {app.state.config.STT_OPENAI_API_KEY}"}
+
+            files = {"file": (filename, open(file_path, "rb"))}
+            data = {"model": "whisper-1"}
+
+            print(files, data)
+
+            r = None
+            try:
+                r = requests.post(
+                    url=f"{app.state.config.STT_OPENAI_API_BASE_URL}/audio/transcriptions",
+                    headers=headers,
+                    files=files,
+                    data=data,
+                )
+
+                r.raise_for_status()
+
+                data = r.json()
+
+                # save the transcript to a json file
+                transcript_file = f"{file_dir}/{id}.json"
+                with open(transcript_file, "w") as f:
+                    json.dump(data, f)
+
+                print(data)
+                return data
+            except Exception as e:
+                log.exception(e)
+                error_detail = "Open WebUI: Server Connection Error"
+                if r is not None:
+                    try:
+                        res = r.json()
+                        if "error" in res:
+                            error_detail = f"External: {res['error']['message']}"
+                    except:
+                        error_detail = f"External: {e}"
+
+                raise HTTPException(
+                    status_code=r.status_code if r != None else 500,
+                    detail=error_detail,
+                )
 
     except Exception as e:
         log.exception(e)

+ 7 - 6
backend/apps/ollama/main.py

@@ -41,8 +41,6 @@ from utils.utils import (
     get_admin_user,
 )
 
-from utils.models import get_model_id_from_custom_model_id
-
 
 from config import (
     SRC_LOG_LEVELS,
@@ -728,7 +726,6 @@ async def generate_chat_completion(
     model_info = Models.get_model_by_id(model_id)
 
     if model_info:
-        print(model_info)
         if model_info.base_model_id:
             payload["model"] = model_info.base_model_id
 
@@ -764,7 +761,7 @@ async def generate_chat_completion(
                     "frequency_penalty", None
                 )
 
-            if model_info.params.get("temperature", None):
+            if model_info.params.get("temperature", None) is not None:
                 payload["options"]["temperature"] = model_info.params.get(
                     "temperature", None
                 )
@@ -849,9 +846,14 @@ async def generate_chat_completion(
 
 
 # TODO: we should update this part once Ollama supports other types
+class OpenAIChatMessageContent(BaseModel):
+    type: str
+    model_config = ConfigDict(extra="allow")
+
+
 class OpenAIChatMessage(BaseModel):
     role: str
-    content: str
+    content: Union[str, OpenAIChatMessageContent]
 
     model_config = ConfigDict(extra="allow")
 
@@ -879,7 +881,6 @@ async def generate_openai_chat_completion(
     model_info = Models.get_model_by_id(model_id)
 
     if model_info:
-        print(model_info)
         if model_info.base_model_id:
             payload["model"] = model_info.base_model_id
 

+ 128 - 81
backend/apps/openai/main.py

@@ -345,108 +345,155 @@ async def get_models(url_idx: Optional[int] = None, user=Depends(get_current_use
             )
 
 
-@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
-async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
+@app.post("/chat/completions")
+@app.post("/chat/completions/{url_idx}")
+async def generate_chat_completion(
+    form_data: dict,
+    url_idx: Optional[int] = None,
+    user=Depends(get_verified_user),
+):
     idx = 0
+    payload = {**form_data}
 
-    body = await request.body()
-    # TODO: Remove below after gpt-4-vision fix from Open AI
-    # Try to decode the body of the request from bytes to a UTF-8 string (Require add max_token to fix gpt-4-vision)
+    model_id = form_data.get("model")
+    model_info = Models.get_model_by_id(model_id)
 
-    payload = None
+    if model_info:
+        if model_info.base_model_id:
+            payload["model"] = model_info.base_model_id
 
-    try:
-        if "chat/completions" in path:
-            body = body.decode("utf-8")
-            body = json.loads(body)
+        model_info.params = model_info.params.model_dump()
 
-            payload = {**body}
+        if model_info.params:
+            if model_info.params.get("temperature", None) is not None:
+                payload["temperature"] = float(model_info.params.get("temperature"))
 
-            model_id = body.get("model")
-            model_info = Models.get_model_by_id(model_id)
+            if model_info.params.get("top_p", None):
+                payload["top_p"] = int(model_info.params.get("top_p", None))
 
-            if model_info:
-                print(model_info)
-                if model_info.base_model_id:
-                    payload["model"] = model_info.base_model_id
+            if model_info.params.get("max_tokens", None):
+                payload["max_tokens"] = int(model_info.params.get("max_tokens", None))
 
-                model_info.params = model_info.params.model_dump()
+            if model_info.params.get("frequency_penalty", None):
+                payload["frequency_penalty"] = int(
+                    model_info.params.get("frequency_penalty", None)
+                )
+
+            if model_info.params.get("seed", None):
+                payload["seed"] = model_info.params.get("seed", None)
+
+            if model_info.params.get("stop", None):
+                payload["stop"] = (
+                    [
+                        bytes(stop, "utf-8").decode("unicode_escape")
+                        for stop in model_info.params["stop"]
+                    ]
+                    if model_info.params.get("stop", None)
+                    else None
+                )
 
-                if model_info.params:
-                    if model_info.params.get("temperature", None):
-                        payload["temperature"] = int(
-                            model_info.params.get("temperature")
+        if model_info.params.get("system", None):
+            # Check if the payload already has a system message
+            # If not, add a system message to the payload
+            if payload.get("messages"):
+                for message in payload["messages"]:
+                    if message.get("role") == "system":
+                        message["content"] = (
+                            model_info.params.get("system", None) + message["content"]
                         )
+                        break
+                else:
+                    payload["messages"].insert(
+                        0,
+                        {
+                            "role": "system",
+                            "content": model_info.params.get("system", None),
+                        },
+                    )
 
-                    if model_info.params.get("top_p", None):
-                        payload["top_p"] = int(model_info.params.get("top_p", None))
+    else:
+        pass
 
-                    if model_info.params.get("max_tokens", None):
-                        payload["max_tokens"] = int(
-                            model_info.params.get("max_tokens", None)
-                        )
+    model = app.state.MODELS[payload.get("model")]
+    idx = model["urlIdx"]
 
-                    if model_info.params.get("frequency_penalty", None):
-                        payload["frequency_penalty"] = int(
-                            model_info.params.get("frequency_penalty", None)
-                        )
+    if "pipeline" in model and model.get("pipeline"):
+        payload["user"] = {"name": user.name, "id": user.id}
 
-                    if model_info.params.get("seed", None):
-                        payload["seed"] = model_info.params.get("seed", None)
-
-                    if model_info.params.get("stop", None):
-                        payload["stop"] = (
-                            [
-                                bytes(stop, "utf-8").decode("unicode_escape")
-                                for stop in model_info.params["stop"]
-                            ]
-                            if model_info.params.get("stop", None)
-                            else None
-                        )
+    # Check if the model is "gpt-4-vision-preview" and set "max_tokens" to 4000
+    # This is a workaround until OpenAI fixes the issue with this model
+    if payload.get("model") == "gpt-4-vision-preview":
+        if "max_tokens" not in payload:
+            payload["max_tokens"] = 4000
+        log.debug("Modified payload:", payload)
 
-                if model_info.params.get("system", None):
-                    # Check if the payload already has a system message
-                    # If not, add a system message to the payload
-                    if payload.get("messages"):
-                        for message in payload["messages"]:
-                            if message.get("role") == "system":
-                                message["content"] = (
-                                    model_info.params.get("system", None)
-                                    + message["content"]
-                                )
-                                break
-                        else:
-                            payload["messages"].insert(
-                                0,
-                                {
-                                    "role": "system",
-                                    "content": model_info.params.get("system", None),
-                                },
-                            )
-            else:
-                pass
+    # Convert the modified body back to JSON
+    payload = json.dumps(payload)
+
+    print(payload)
 
-            model = app.state.MODELS[payload.get("model")]
+    url = app.state.config.OPENAI_API_BASE_URLS[idx]
+    key = app.state.config.OPENAI_API_KEYS[idx]
 
-            idx = model["urlIdx"]
+    print(payload)
 
-            if "pipeline" in model and model.get("pipeline"):
-                payload["user"] = {"name": user.name, "id": user.id}
+    headers = {}
+    headers["Authorization"] = f"Bearer {key}"
+    headers["Content-Type"] = "application/json"
 
-            # Check if the model is "gpt-4-vision-preview" and set "max_tokens" to 4000
-            # This is a workaround until OpenAI fixes the issue with this model
-            if payload.get("model") == "gpt-4-vision-preview":
-                if "max_tokens" not in payload:
-                    payload["max_tokens"] = 4000
-                log.debug("Modified payload:", payload)
+    r = None
+    session = None
+    streaming = False
 
-            # Convert the modified body back to JSON
-            payload = json.dumps(payload)
+    try:
+        session = aiohttp.ClientSession(trust_env=True)
+        r = await session.request(
+            method="POST",
+            url=f"{url}/chat/completions",
+            data=payload,
+            headers=headers,
+        )
 
-    except json.JSONDecodeError as e:
-        log.error("Error loading request body into a dictionary:", e)
+        r.raise_for_status()
 
-    print(payload)
+        # Check if response is SSE
+        if "text/event-stream" in r.headers.get("Content-Type", ""):
+            streaming = True
+            return StreamingResponse(
+                r.content,
+                status_code=r.status,
+                headers=dict(r.headers),
+                background=BackgroundTask(
+                    cleanup_response, response=r, session=session
+                ),
+            )
+        else:
+            response_data = await r.json()
+            return response_data
+    except Exception as e:
+        log.exception(e)
+        error_detail = "Open WebUI: Server Connection Error"
+        if r is not None:
+            try:
+                res = await r.json()
+                print(res)
+                if "error" in res:
+                    error_detail = f"External: {res['error']['message'] if 'message' in res['error'] else res['error']}"
+            except:
+                error_detail = f"External: {e}"
+        raise HTTPException(status_code=r.status if r else 500, detail=error_detail)
+    finally:
+        if not streaming and session:
+            if r:
+                r.close()
+            await session.close()
+
+
+@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
+async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
+    idx = 0
+
+    body = await request.body()
 
     url = app.state.config.OPENAI_API_BASE_URLS[idx]
     key = app.state.config.OPENAI_API_KEYS[idx]
@@ -466,7 +513,7 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
         r = await session.request(
             method=request.method,
             url=target_url,
-            data=payload if payload else body,
+            data=body,
             headers=headers,
         )
 

+ 12 - 0
backend/apps/rag/main.py

@@ -9,6 +9,7 @@ from fastapi import (
 )
 from fastapi.middleware.cors import CORSMiddleware
 import os, shutil, logging, re
+from datetime import datetime
 
 from pathlib import Path
 from typing import List, Union, Sequence
@@ -30,6 +31,7 @@ from langchain_community.document_loaders import (
     UnstructuredExcelLoader,
     UnstructuredPowerPointLoader,
     YoutubeLoader,
+    OutlookMessageLoader,
 )
 from langchain.text_splitter import RecursiveCharacterTextSplitter
 
@@ -879,6 +881,13 @@ def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> b
     texts = [doc.page_content for doc in docs]
     metadatas = [doc.metadata for doc in docs]
 
+    # ChromaDB does not like datetime formats
+    # for meta-data so convert them to string.
+    for metadata in metadatas:
+        for key, value in metadata.items():
+            if isinstance(value, datetime):
+                metadata[key] = str(value)
+
     try:
         if overwrite:
             for collection in CHROMA_CLIENT.list_collections():
@@ -965,6 +974,7 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
         "swift",
         "vue",
         "svelte",
+        "msg",
     ]
 
     if file_ext == "pdf":
@@ -999,6 +1009,8 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
         "application/vnd.openxmlformats-officedocument.presentationml.presentation",
     ] or file_ext in ["ppt", "pptx"]:
         loader = UnstructuredPowerPointLoader(file_path)
+    elif file_ext == "msg":
+        loader = OutlookMessageLoader(file_path)
     elif file_ext in known_source_ext or (
         file_content_type and file_content_type.find("text/") >= 0
     ):

+ 3 - 44
backend/apps/rag/utils.py

@@ -20,7 +20,7 @@ from langchain.retrievers import (
 
 from typing import Optional
 
-
+from utils.misc import get_last_user_message, add_or_update_system_message
 from config import SRC_LOG_LEVELS, CHROMA_CLIENT
 
 log = logging.getLogger(__name__)
@@ -247,31 +247,7 @@ def rag_messages(
     hybrid_search,
 ):
     log.debug(f"docs: {docs} {messages} {embedding_function} {reranking_function}")
-
-    last_user_message_idx = None
-    for i in range(len(messages) - 1, -1, -1):
-        if messages[i]["role"] == "user":
-            last_user_message_idx = i
-            break
-
-    user_message = messages[last_user_message_idx]
-
-    if isinstance(user_message["content"], list):
-        # Handle list content input
-        content_type = "list"
-        query = ""
-        for content_item in user_message["content"]:
-            if content_item["type"] == "text":
-                query = content_item["text"]
-                break
-    elif isinstance(user_message["content"], str):
-        # Handle text content input
-        content_type = "text"
-        query = user_message["content"]
-    else:
-        # Fallback in case the input does not match expected types
-        content_type = None
-        query = ""
+    query = get_last_user_message(messages)
 
     extracted_collections = []
     relevant_contexts = []
@@ -349,24 +325,7 @@ def rag_messages(
     )
 
     log.debug(f"ra_content: {ra_content}")
-
-    if content_type == "list":
-        new_content = []
-        for content_item in user_message["content"]:
-            if content_item["type"] == "text":
-                # Update the text item's content with ra_content
-                new_content.append({"type": "text", "text": ra_content})
-            else:
-                # Keep other types of content as they are
-                new_content.append(content_item)
-        new_user_message = {**user_message, "content": new_content}
-    else:
-        new_user_message = {
-            **user_message,
-            "content": ra_content,
-        }
-
-    messages[last_user_message_idx] = new_user_message
+    messages = add_or_update_system_message(ra_content, messages)
 
     return messages, citations
 

+ 25 - 6
backend/apps/socket/main.py

@@ -10,7 +10,7 @@ app = socketio.ASGIApp(sio, socketio_path="/ws/socket.io")
 
 # Dictionary to maintain the user pool
 
-
+SESSION_POOL = {}
 USER_POOL = {}
 USAGE_POOL = {}
 # Timeout duration in seconds
@@ -29,7 +29,12 @@ async def connect(sid, environ, auth):
             user = Users.get_user_by_id(data["id"])
 
         if user:
-            USER_POOL[sid] = user.id
+            SESSION_POOL[sid] = user.id
+            if user.id in USER_POOL:
+                USER_POOL[user.id].append(sid)
+            else:
+                USER_POOL[user.id] = [sid]
+
             print(f"user {user.name}({user.id}) connected with session ID {sid}")
 
             print(len(set(USER_POOL)))
@@ -50,7 +55,13 @@ async def user_join(sid, data):
             user = Users.get_user_by_id(data["id"])
 
         if user:
-            USER_POOL[sid] = user.id
+
+            SESSION_POOL[sid] = user.id
+            if user.id in USER_POOL:
+                USER_POOL[user.id].append(sid)
+            else:
+                USER_POOL[user.id] = [sid]
+
             print(f"user {user.name}({user.id}) connected with session ID {sid}")
 
             print(len(set(USER_POOL)))
@@ -123,9 +134,17 @@ async def remove_after_timeout(sid, model_id):
 
 @sio.event
 async def disconnect(sid):
-    if sid in USER_POOL:
-        disconnected_user = USER_POOL.pop(sid)
-        print(f"user {disconnected_user} disconnected with session ID {sid}")
+    if sid in SESSION_POOL:
+        user_id = SESSION_POOL[sid]
+        del SESSION_POOL[sid]
+
+        USER_POOL[user_id].remove(sid)
+
+        if len(USER_POOL[user_id]) == 0:
+            del USER_POOL[user_id]
+
+        print(f"user {user_id} disconnected with session ID {sid}")
+        print(USER_POOL)
 
         await sio.emit("user-count", {"count": len(USER_POOL)})
     else:

+ 114 - 17
backend/config.py

@@ -306,7 +306,10 @@ STATIC_DIR = Path(os.getenv("STATIC_DIR", BACKEND_DIR / "static")).resolve()
 
 frontend_favicon = FRONTEND_BUILD_DIR / "favicon.png"
 if frontend_favicon.exists():
-    shutil.copyfile(frontend_favicon, STATIC_DIR / "favicon.png")
+    try:
+        shutil.copyfile(frontend_favicon, STATIC_DIR / "favicon.png")
+    except PermissionError:
+        logging.error(f"No write permission to {STATIC_DIR / 'favicon.png'}")
 else:
     logging.warning(f"Frontend favicon not found at {frontend_favicon}")
 
@@ -615,6 +618,66 @@ ADMIN_EMAIL = PersistentConfig(
 )
 
 
+####################################
+# TASKS
+####################################
+
+
+TASK_MODEL = PersistentConfig(
+    "TASK_MODEL",
+    "task.model.default",
+    os.environ.get("TASK_MODEL", ""),
+)
+
+TASK_MODEL_EXTERNAL = PersistentConfig(
+    "TASK_MODEL_EXTERNAL",
+    "task.model.external",
+    os.environ.get("TASK_MODEL_EXTERNAL", ""),
+)
+
+TITLE_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
+    "TITLE_GENERATION_PROMPT_TEMPLATE",
+    "task.title.prompt_template",
+    os.environ.get(
+        "TITLE_GENERATION_PROMPT_TEMPLATE",
+        """Here is the query:
+{{prompt:middletruncate:8000}}
+
+Create a concise, 3-5 word phrase with an emoji as a title for the previous query. Suitable Emojis for the summary can be used to enhance understanding but avoid quotation marks or special formatting. RESPOND ONLY WITH THE TITLE TEXT.
+
+Examples of titles:
+📉 Stock Market Trends
+🍪 Perfect Chocolate Chip Recipe
+Evolution of Music Streaming
+Remote Work Productivity Tips
+Artificial Intelligence in Healthcare
+🎮 Video Game Development Insights""",
+    ),
+)
+
+
+SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
+    "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE",
+    "task.search.prompt_template",
+    os.environ.get(
+        "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE",
+        """You are tasked with generating web search queries. Give me an appropriate query to answer my question for google search. Answer with only the query. Today is {{CURRENT_DATE}}.
+        
+Question:
+{{prompt:end:4000}}""",
+    ),
+)
+
+
+SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD = PersistentConfig(
+    "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD",
+    "task.search.prompt_length_threshold",
+    os.environ.get(
+        "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD",
+        100,
+    ),
+)
+
 ####################################
 # WEBUI_SECRET_KEY
 ####################################
@@ -933,25 +996,59 @@ IMAGE_GENERATION_MODEL = PersistentConfig(
 # Audio
 ####################################
 
-AUDIO_OPENAI_API_BASE_URL = PersistentConfig(
-    "AUDIO_OPENAI_API_BASE_URL",
-    "audio.openai.api_base_url",
-    os.getenv("AUDIO_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
+AUDIO_STT_OPENAI_API_BASE_URL = PersistentConfig(
+    "AUDIO_STT_OPENAI_API_BASE_URL",
+    "audio.stt.openai.api_base_url",
+    os.getenv("AUDIO_STT_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
+)
+
+AUDIO_STT_OPENAI_API_KEY = PersistentConfig(
+    "AUDIO_STT_OPENAI_API_KEY",
+    "audio.stt.openai.api_key",
+    os.getenv("AUDIO_STT_OPENAI_API_KEY", OPENAI_API_KEY),
+)
+
+AUDIO_STT_ENGINE = PersistentConfig(
+    "AUDIO_STT_ENGINE",
+    "audio.stt.engine",
+    os.getenv("AUDIO_STT_ENGINE", ""),
+)
+
+AUDIO_STT_MODEL = PersistentConfig(
+    "AUDIO_STT_MODEL",
+    "audio.stt.model",
+    os.getenv("AUDIO_STT_MODEL", "whisper-1"),
+)
+
+AUDIO_TTS_OPENAI_API_BASE_URL = PersistentConfig(
+    "AUDIO_TTS_OPENAI_API_BASE_URL",
+    "audio.tts.openai.api_base_url",
+    os.getenv("AUDIO_TTS_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
 )
-AUDIO_OPENAI_API_KEY = PersistentConfig(
-    "AUDIO_OPENAI_API_KEY",
-    "audio.openai.api_key",
-    os.getenv("AUDIO_OPENAI_API_KEY", OPENAI_API_KEY),
+AUDIO_TTS_OPENAI_API_KEY = PersistentConfig(
+    "AUDIO_TTS_OPENAI_API_KEY",
+    "audio.tts.openai.api_key",
+    os.getenv("AUDIO_TTS_OPENAI_API_KEY", OPENAI_API_KEY),
 )
-AUDIO_OPENAI_API_MODEL = PersistentConfig(
-    "AUDIO_OPENAI_API_MODEL",
-    "audio.openai.api_model",
-    os.getenv("AUDIO_OPENAI_API_MODEL", "tts-1"),
+
+
+AUDIO_TTS_ENGINE = PersistentConfig(
+    "AUDIO_TTS_ENGINE",
+    "audio.tts.engine",
+    os.getenv("AUDIO_TTS_ENGINE", ""),
 )
-AUDIO_OPENAI_API_VOICE = PersistentConfig(
-    "AUDIO_OPENAI_API_VOICE",
-    "audio.openai.api_voice",
-    os.getenv("AUDIO_OPENAI_API_VOICE", "alloy"),
+
+
+AUDIO_TTS_MODEL = PersistentConfig(
+    "AUDIO_TTS_MODEL",
+    "audio.tts.model",
+    os.getenv("AUDIO_TTS_MODEL", "tts-1"),
+)
+
+AUDIO_TTS_VOICE = PersistentConfig(
+    "AUDIO_TTS_VOICE",
+    "audio.tts.voice",
+    os.getenv("AUDIO_TTS_VOICE", "alloy"),
 )
 
 

+ 349 - 86
backend/main.py

@@ -9,8 +9,11 @@ import logging
 import aiohttp
 import requests
 import mimetypes
+import shutil
+import os
+import asyncio
 
-from fastapi import FastAPI, Request, Depends, status
+from fastapi import FastAPI, Request, Depends, status, UploadFile, File, Form
 from fastapi.staticfiles import StaticFiles
 from fastapi.responses import JSONResponse
 from fastapi import HTTPException
@@ -22,15 +25,24 @@ from starlette.responses import StreamingResponse, Response
 
 
 from apps.socket.main import app as socket_app
-from apps.ollama.main import app as ollama_app, get_all_models as get_ollama_models
-from apps.openai.main import app as openai_app, get_all_models as get_openai_models
+from apps.ollama.main import (
+    app as ollama_app,
+    OpenAIChatCompletionForm,
+    get_all_models as get_ollama_models,
+    generate_openai_chat_completion as generate_ollama_chat_completion,
+)
+from apps.openai.main import (
+    app as openai_app,
+    get_all_models as get_openai_models,
+    generate_chat_completion as generate_openai_chat_completion,
+)
 
 from apps.audio.main import app as audio_app
 from apps.images.main import app as images_app
 from apps.rag.main import app as rag_app
 from apps.webui.main import app as webui_app
 
-import asyncio
+
 from pydantic import BaseModel
 from typing import List, Optional
 
@@ -41,6 +53,8 @@ from utils.utils import (
     get_current_user,
     get_http_authorization_cred,
 )
+from utils.task import title_generation_template, search_query_generation_template
+
 from apps.rag.utils import rag_messages
 
 from config import (
@@ -62,8 +76,13 @@ from config import (
     SRC_LOG_LEVELS,
     WEBHOOK_URL,
     ENABLE_ADMIN_EXPORT,
-    AppConfig,
     WEBUI_BUILD_HASH,
+    TASK_MODEL,
+    TASK_MODEL_EXTERNAL,
+    TITLE_GENERATION_PROMPT_TEMPLATE,
+    SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
+    SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
+    AppConfig,
 )
 from constants import ERROR_MESSAGES
 
@@ -117,10 +136,19 @@ app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API
 app.state.config.ENABLE_MODEL_FILTER = ENABLE_MODEL_FILTER
 app.state.config.MODEL_FILTER_LIST = MODEL_FILTER_LIST
 
-
 app.state.config.WEBHOOK_URL = WEBHOOK_URL
 
 
+app.state.config.TASK_MODEL = TASK_MODEL
+app.state.config.TASK_MODEL_EXTERNAL = TASK_MODEL_EXTERNAL
+app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = TITLE_GENERATION_PROMPT_TEMPLATE
+app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE = (
+    SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE
+)
+app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD = (
+    SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD
+)
+
 app.state.MODELS = {}
 
 origins = ["*"]
@@ -228,6 +256,78 @@ class RAGMiddleware(BaseHTTPMiddleware):
 app.add_middleware(RAGMiddleware)
 
 
+def filter_pipeline(payload, user):
+    user = {"id": user.id, "name": user.name, "role": user.role}
+    model_id = payload["model"]
+    filters = [
+        model
+        for model in app.state.MODELS.values()
+        if "pipeline" in model
+        and "type" in model["pipeline"]
+        and model["pipeline"]["type"] == "filter"
+        and (
+            model["pipeline"]["pipelines"] == ["*"]
+            or any(
+                model_id == target_model_id
+                for target_model_id in model["pipeline"]["pipelines"]
+            )
+        )
+    ]
+    sorted_filters = sorted(filters, key=lambda x: x["pipeline"]["priority"])
+
+    model = app.state.MODELS[model_id]
+
+    if "pipeline" in model:
+        sorted_filters.append(model)
+
+    for filter in sorted_filters:
+        r = None
+        try:
+            urlIdx = filter["urlIdx"]
+
+            url = openai_app.state.config.OPENAI_API_BASE_URLS[urlIdx]
+            key = openai_app.state.config.OPENAI_API_KEYS[urlIdx]
+
+            if key != "":
+                headers = {"Authorization": f"Bearer {key}"}
+                r = requests.post(
+                    f"{url}/{filter['id']}/filter/inlet",
+                    headers=headers,
+                    json={
+                        "user": user,
+                        "body": payload,
+                    },
+                )
+
+                r.raise_for_status()
+                payload = r.json()
+        except Exception as e:
+            # Handle connection error here
+            print(f"Connection error: {e}")
+
+            if r is not None:
+                try:
+                    res = r.json()
+                    if "detail" in res:
+                        return JSONResponse(
+                            status_code=r.status_code,
+                            content=res,
+                        )
+                except:
+                    pass
+
+            else:
+                pass
+
+    if "pipeline" not in app.state.MODELS[model_id]:
+        if "chat_id" in payload:
+            del payload["chat_id"]
+
+        if "title" in payload:
+            del payload["title"]
+    return payload
+
+
 class PipelineMiddleware(BaseHTTPMiddleware):
     async def dispatch(self, request: Request, call_next):
         if request.method == "POST" and (
@@ -243,85 +343,10 @@ class PipelineMiddleware(BaseHTTPMiddleware):
             # Parse string to JSON
             data = json.loads(body_str) if body_str else {}
 
-            model_id = data["model"]
-            filters = [
-                model
-                for model in app.state.MODELS.values()
-                if "pipeline" in model
-                and "type" in model["pipeline"]
-                and model["pipeline"]["type"] == "filter"
-                and (
-                    model["pipeline"]["pipelines"] == ["*"]
-                    or any(
-                        model_id == target_model_id
-                        for target_model_id in model["pipeline"]["pipelines"]
-                    )
-                )
-            ]
-            sorted_filters = sorted(filters, key=lambda x: x["pipeline"]["priority"])
-
-            user = None
-            if len(sorted_filters) > 0:
-                try:
-                    user = get_current_user(
-                        get_http_authorization_cred(
-                            request.headers.get("Authorization")
-                        )
-                    )
-                    user = {"id": user.id, "name": user.name, "role": user.role}
-                except:
-                    pass
-
-            model = app.state.MODELS[model_id]
-
-            if "pipeline" in model:
-                sorted_filters.append(model)
-
-            for filter in sorted_filters:
-                r = None
-                try:
-                    urlIdx = filter["urlIdx"]
-
-                    url = openai_app.state.config.OPENAI_API_BASE_URLS[urlIdx]
-                    key = openai_app.state.config.OPENAI_API_KEYS[urlIdx]
-
-                    if key != "":
-                        headers = {"Authorization": f"Bearer {key}"}
-                        r = requests.post(
-                            f"{url}/{filter['id']}/filter/inlet",
-                            headers=headers,
-                            json={
-                                "user": user,
-                                "body": data,
-                            },
-                        )
-
-                        r.raise_for_status()
-                        data = r.json()
-                except Exception as e:
-                    # Handle connection error here
-                    print(f"Connection error: {e}")
-
-                    if r is not None:
-                        try:
-                            res = r.json()
-                            if "detail" in res:
-                                return JSONResponse(
-                                    status_code=r.status_code,
-                                    content=res,
-                                )
-                        except:
-                            pass
-
-                    else:
-                        pass
-
-            if "pipeline" not in app.state.MODELS[model_id]:
-                if "chat_id" in data:
-                    del data["chat_id"]
-
-                if "title" in data:
-                    del data["title"]
+            user = get_current_user(
+                get_http_authorization_cred(request.headers.get("Authorization"))
+            )
+            data = filter_pipeline(data, user)
 
             modified_body_bytes = json.dumps(data).encode("utf-8")
             # Replace the request body with the modified one
@@ -482,6 +507,178 @@ async def get_models(user=Depends(get_verified_user)):
     return {"data": models}
 
 
+@app.get("/api/task/config")
+async def get_task_config(user=Depends(get_verified_user)):
+    return {
+        "TASK_MODEL": app.state.config.TASK_MODEL,
+        "TASK_MODEL_EXTERNAL": app.state.config.TASK_MODEL_EXTERNAL,
+        "TITLE_GENERATION_PROMPT_TEMPLATE": app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE,
+        "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE": app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
+        "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD": app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
+    }
+
+
+class TaskConfigForm(BaseModel):
+    TASK_MODEL: Optional[str]
+    TASK_MODEL_EXTERNAL: Optional[str]
+    TITLE_GENERATION_PROMPT_TEMPLATE: str
+    SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE: str
+    SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD: int
+
+
+@app.post("/api/task/config/update")
+async def update_task_config(form_data: TaskConfigForm, user=Depends(get_admin_user)):
+    app.state.config.TASK_MODEL = form_data.TASK_MODEL
+    app.state.config.TASK_MODEL_EXTERNAL = form_data.TASK_MODEL_EXTERNAL
+    app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = (
+        form_data.TITLE_GENERATION_PROMPT_TEMPLATE
+    )
+    app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE = (
+        form_data.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE
+    )
+    app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD = (
+        form_data.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD
+    )
+
+    return {
+        "TASK_MODEL": app.state.config.TASK_MODEL,
+        "TASK_MODEL_EXTERNAL": app.state.config.TASK_MODEL_EXTERNAL,
+        "TITLE_GENERATION_PROMPT_TEMPLATE": app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE,
+        "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE": app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
+        "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD": app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
+    }
+
+
+@app.post("/api/task/title/completions")
+async def generate_title(form_data: dict, user=Depends(get_verified_user)):
+    print("generate_title")
+
+    model_id = form_data["model"]
+    if model_id not in app.state.MODELS:
+        raise HTTPException(
+            status_code=status.HTTP_404_NOT_FOUND,
+            detail="Model not found",
+        )
+
+    # Check if the user has a custom task model
+    # If the user has a custom task model, use that model
+    if app.state.MODELS[model_id]["owned_by"] == "ollama":
+        if app.state.config.TASK_MODEL:
+            task_model_id = app.state.config.TASK_MODEL
+            if task_model_id in app.state.MODELS:
+                model_id = task_model_id
+    else:
+        if app.state.config.TASK_MODEL_EXTERNAL:
+            task_model_id = app.state.config.TASK_MODEL_EXTERNAL
+            if task_model_id in app.state.MODELS:
+                model_id = task_model_id
+
+    print(model_id)
+    model = app.state.MODELS[model_id]
+
+    template = app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE
+
+    content = title_generation_template(
+        template, form_data["prompt"], user.model_dump()
+    )
+
+    payload = {
+        "model": model_id,
+        "messages": [{"role": "user", "content": content}],
+        "stream": False,
+        "max_tokens": 50,
+        "chat_id": form_data.get("chat_id", None),
+        "title": True,
+    }
+
+    print(payload)
+    payload = filter_pipeline(payload, user)
+
+    if model["owned_by"] == "ollama":
+        return await generate_ollama_chat_completion(
+            OpenAIChatCompletionForm(**payload), user=user
+        )
+    else:
+        return await generate_openai_chat_completion(payload, user=user)
+
+
+@app.post("/api/task/query/completions")
+async def generate_search_query(form_data: dict, user=Depends(get_verified_user)):
+    print("generate_search_query")
+
+    if len(form_data["prompt"]) < app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD:
+        raise HTTPException(
+            status_code=status.HTTP_400_BAD_REQUEST,
+            detail=f"Skip search query generation for short prompts (< {app.state.config.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD} characters)",
+        )
+
+    model_id = form_data["model"]
+    if model_id not in app.state.MODELS:
+        raise HTTPException(
+            status_code=status.HTTP_404_NOT_FOUND,
+            detail="Model not found",
+        )
+
+    # Check if the user has a custom task model
+    # If the user has a custom task model, use that model
+    if app.state.MODELS[model_id]["owned_by"] == "ollama":
+        if app.state.config.TASK_MODEL:
+            task_model_id = app.state.config.TASK_MODEL
+            if task_model_id in app.state.MODELS:
+                model_id = task_model_id
+    else:
+        if app.state.config.TASK_MODEL_EXTERNAL:
+            task_model_id = app.state.config.TASK_MODEL_EXTERNAL
+            if task_model_id in app.state.MODELS:
+                model_id = task_model_id
+
+    print(model_id)
+    model = app.state.MODELS[model_id]
+
+    template = app.state.config.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE
+
+    content = search_query_generation_template(
+        template, form_data["prompt"], user.model_dump()
+    )
+
+    payload = {
+        "model": model_id,
+        "messages": [{"role": "user", "content": content}],
+        "stream": False,
+        "max_tokens": 30,
+    }
+
+    print(payload)
+    payload = filter_pipeline(payload, user)
+
+    if model["owned_by"] == "ollama":
+        return await generate_ollama_chat_completion(
+            OpenAIChatCompletionForm(**payload), user=user
+        )
+    else:
+        return await generate_openai_chat_completion(payload, user=user)
+
+
+@app.post("/api/chat/completions")
+async def generate_chat_completions(form_data: dict, user=Depends(get_verified_user)):
+    model_id = form_data["model"]
+    if model_id not in app.state.MODELS:
+        raise HTTPException(
+            status_code=status.HTTP_404_NOT_FOUND,
+            detail="Model not found",
+        )
+
+    model = app.state.MODELS[model_id]
+    print(model)
+
+    if model["owned_by"] == "ollama":
+        return await generate_ollama_chat_completion(
+            OpenAIChatCompletionForm(**form_data), user=user
+        )
+    else:
+        return await generate_openai_chat_completion(form_data, user=user)
+
+
 @app.post("/api/chat/completed")
 async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
     data = form_data
@@ -574,6 +771,63 @@ async def get_pipelines_list(user=Depends(get_admin_user)):
     }
 
 
+@app.post("/api/pipelines/upload")
+async def upload_pipeline(
+    urlIdx: int = Form(...), file: UploadFile = File(...), user=Depends(get_admin_user)
+):
+    print("upload_pipeline", urlIdx, file.filename)
+    # Check if the uploaded file is a python file
+    if not file.filename.endswith(".py"):
+        raise HTTPException(
+            status_code=status.HTTP_400_BAD_REQUEST,
+            detail="Only Python (.py) files are allowed.",
+        )
+
+    upload_folder = f"{CACHE_DIR}/pipelines"
+    os.makedirs(upload_folder, exist_ok=True)
+    file_path = os.path.join(upload_folder, file.filename)
+
+    try:
+        # Save the uploaded file
+        with open(file_path, "wb") as buffer:
+            shutil.copyfileobj(file.file, buffer)
+
+        url = openai_app.state.config.OPENAI_API_BASE_URLS[urlIdx]
+        key = openai_app.state.config.OPENAI_API_KEYS[urlIdx]
+
+        headers = {"Authorization": f"Bearer {key}"}
+
+        with open(file_path, "rb") as f:
+            files = {"file": f}
+            r = requests.post(f"{url}/pipelines/upload", headers=headers, files=files)
+
+        r.raise_for_status()
+        data = r.json()
+
+        return {**data}
+    except Exception as e:
+        # Handle connection error here
+        print(f"Connection error: {e}")
+
+        detail = "Pipeline not found"
+        if r is not None:
+            try:
+                res = r.json()
+                if "detail" in res:
+                    detail = res["detail"]
+            except:
+                pass
+
+        raise HTTPException(
+            status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND),
+            detail=detail,
+        )
+    finally:
+        # Ensure the file is deleted after the upload is completed or on failure
+        if os.path.exists(file_path):
+            os.remove(file_path)
+
+
 class AddPipelineForm(BaseModel):
     url: str
     urlIdx: int
@@ -840,6 +1094,15 @@ async def get_app_config():
             "enable_community_sharing": webui_app.state.config.ENABLE_COMMUNITY_SHARING,
             "enable_admin_export": ENABLE_ADMIN_EXPORT,
         },
+        "audio": {
+            "tts": {
+                "engine": audio_app.state.config.TTS_ENGINE,
+                "voice": audio_app.state.config.TTS_VOICE,
+            },
+            "stt": {
+                "engine": audio_app.state.config.STT_ENGINE,
+            },
+        },
     }
 
 
@@ -902,7 +1165,7 @@ async def get_app_changelog():
 @app.get("/api/version/updates")
 async def get_app_latest_release_version():
     try:
-        async with aiohttp.ClientSession() as session:
+        async with aiohttp.ClientSession(trust_env=True) as session:
             async with session.get(
                 "https://api.github.com/repos/open-webui/open-webui/releases/latest"
             ) as response:

+ 4 - 1
backend/requirements.txt

@@ -56,4 +56,7 @@ PyJWT[crypto]==2.8.0
 black==24.4.2
 langfuse==2.33.0
 youtube-transcript-api==0.6.2
-pytube==15.0.0
+pytube==15.0.0
+
+extract_msg
+pydub

+ 2 - 2
backend/start.sh

@@ -20,12 +20,12 @@ if test "$WEBUI_SECRET_KEY $WEBUI_JWT_SECRET_KEY" = " "; then
   WEBUI_SECRET_KEY=$(cat "$KEY_FILE")
 fi
 
-if [ "$USE_OLLAMA_DOCKER" = "true" ]; then
+if [[ "${USE_OLLAMA_DOCKER,,}" == "true" ]]; then
     echo "USE_OLLAMA is set to true, starting ollama serve."
     ollama serve &
 fi
 
-if [ "$USE_CUDA_DOCKER" = "true" ]; then
+if [[ "${USE_CUDA_DOCKER,,}" == "true" ]]; then
   echo "CUDA is enabled, appending LD_LIBRARY_PATH to include torch/cudnn & cublas libraries."
   export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/python3.11/site-packages/torch/lib:/usr/local/lib/python3.11/site-packages/nvidia/cudnn/lib"
 fi

+ 48 - 1
backend/utils/misc.py

@@ -3,7 +3,48 @@ import hashlib
 import json
 import re
 from datetime import timedelta
-from typing import Optional
+from typing import Optional, List
+
+
+def get_last_user_message(messages: List[dict]) -> str:
+    for message in reversed(messages):
+        if message["role"] == "user":
+            if isinstance(message["content"], list):
+                for item in message["content"]:
+                    if item["type"] == "text":
+                        return item["text"]
+            return message["content"]
+    return None
+
+
+def get_last_assistant_message(messages: List[dict]) -> str:
+    for message in reversed(messages):
+        if message["role"] == "assistant":
+            if isinstance(message["content"], list):
+                for item in message["content"]:
+                    if item["type"] == "text":
+                        return item["text"]
+            return message["content"]
+    return None
+
+
+def add_or_update_system_message(content: str, messages: List[dict]):
+    """
+    Adds a new system message at the beginning of the messages list
+    or updates the existing system message at the beginning.
+
+    :param msg: The message to be added or appended.
+    :param messages: The list of message dictionaries.
+    :return: The updated list of message dictionaries.
+    """
+
+    if messages and messages[0].get("role") == "system":
+        messages[0]["content"] += f"{content}\n{messages[0]['content']}"
+    else:
+        # Insert at the beginning
+        messages.insert(0, {"role": "system", "content": content})
+
+    return messages
 
 
 def get_gravatar_url(email):
@@ -193,8 +234,14 @@ def parse_ollama_modelfile(model_text):
     system_desc_match = re.search(
         r'SYSTEM\s+"""(.+?)"""', model_text, re.DOTALL | re.IGNORECASE
     )
+    system_desc_match_single = re.search(
+        r"SYSTEM\s+([^\n]+)", model_text, re.IGNORECASE
+    )
+
     if system_desc_match:
         data["params"]["system"] = system_desc_match.group(1).strip()
+    elif system_desc_match_single:
+        data["params"]["system"] = system_desc_match_single.group(1).strip()
 
     # Parse messages
     messages = []

+ 0 - 10
backend/utils/models.py

@@ -1,10 +0,0 @@
-from apps.webui.models.models import Models, ModelModel, ModelForm, ModelResponse
-
-
-def get_model_id_from_custom_model_id(id: str):
-    model = Models.get_model_by_id(id)
-
-    if model:
-        return model.id
-    else:
-        return id

+ 112 - 0
backend/utils/task.py

@@ -0,0 +1,112 @@
+import re
+import math
+
+from datetime import datetime
+from typing import Optional
+
+
+def prompt_template(
+    template: str, user_name: str = None, current_location: str = None
+) -> str:
+    # Get the current date
+    current_date = datetime.now()
+
+    # Format the date to YYYY-MM-DD
+    formatted_date = current_date.strftime("%Y-%m-%d")
+
+    # Replace {{CURRENT_DATE}} in the template with the formatted date
+    template = template.replace("{{CURRENT_DATE}}", formatted_date)
+
+    if user_name:
+        # Replace {{USER_NAME}} in the template with the user's name
+        template = template.replace("{{USER_NAME}}", user_name)
+
+    if current_location:
+        # Replace {{CURRENT_LOCATION}} in the template with the current location
+        template = template.replace("{{CURRENT_LOCATION}}", current_location)
+
+    return template
+
+
+def title_generation_template(
+    template: str, prompt: str, user: Optional[dict] = None
+) -> str:
+    def replacement_function(match):
+        full_match = match.group(0)
+        start_length = match.group(1)
+        end_length = match.group(2)
+        middle_length = match.group(3)
+
+        if full_match == "{{prompt}}":
+            return prompt
+        elif start_length is not None:
+            return prompt[: int(start_length)]
+        elif end_length is not None:
+            return prompt[-int(end_length) :]
+        elif middle_length is not None:
+            middle_length = int(middle_length)
+            if len(prompt) <= middle_length:
+                return prompt
+            start = prompt[: math.ceil(middle_length / 2)]
+            end = prompt[-math.floor(middle_length / 2) :]
+            return f"{start}...{end}"
+        return ""
+
+    template = re.sub(
+        r"{{prompt}}|{{prompt:start:(\d+)}}|{{prompt:end:(\d+)}}|{{prompt:middletruncate:(\d+)}}",
+        replacement_function,
+        template,
+    )
+
+    template = prompt_template(
+        template,
+        **(
+            {"user_name": user.get("name"), "current_location": user.get("location")}
+            if user
+            else {}
+        ),
+    )
+
+    return template
+
+
+def search_query_generation_template(
+    template: str, prompt: str, user: Optional[dict] = None
+) -> str:
+
+    def replacement_function(match):
+        full_match = match.group(0)
+        start_length = match.group(1)
+        end_length = match.group(2)
+        middle_length = match.group(3)
+
+        if full_match == "{{prompt}}":
+            return prompt
+        elif start_length is not None:
+            return prompt[: int(start_length)]
+        elif end_length is not None:
+            return prompt[-int(end_length) :]
+        elif middle_length is not None:
+            middle_length = int(middle_length)
+            if len(prompt) <= middle_length:
+                return prompt
+            start = prompt[: math.ceil(middle_length / 2)]
+            end = prompt[-math.floor(middle_length / 2) :]
+            return f"{start}...{end}"
+        return ""
+
+    template = re.sub(
+        r"{{prompt}}|{{prompt:start:(\d+)}}|{{prompt:end:(\d+)}}|{{prompt:middletruncate:(\d+)}}",
+        replacement_function,
+        template,
+    )
+
+    template = prompt_template(
+        template,
+        **(
+            {"user_name": user.get("name"), "current_location": user.get("location")}
+            if user
+            else {}
+        ),
+    )
+    return template

+ 1 - 1
docs/CONTRIBUTING.md

@@ -41,7 +41,7 @@ Looking to contribute? Great! Here's how you can help:
 
 We welcome pull requests. Before submitting one, please:
 
-1. Discuss your idea or issue in the [issues section](https://github.com/open-webui/open-webui/issues).
+1. Open a discussion regarding your ideas [here](https://github.com/open-webui/open-webui/discussions/new/choose).
 2. Follow the project's coding standards and include tests for new features.
 3. Update documentation as necessary.
 4. Write clear, descriptive commit messages.

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
 	"name": "open-webui",
-	"version": "0.2.5",
+	"version": "0.3.0",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "open-webui",
-			"version": "0.2.5",
+			"version": "0.3.0",
 			"dependencies": {
 				"@pyscript/core": "^0.4.32",
 				"@sveltejs/adapter-node": "^1.3.1",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "open-webui",
-	"version": "0.2.5",
+	"version": "0.3.0",
 	"private": true,
 	"scripts": {
 		"dev": "npm run pyodide:fetch && vite dev --host",

+ 18 - 9
src/app.html

@@ -59,15 +59,7 @@
 
 		<div
 			id="splash-screen"
-			style="
-				position: fixed;
-				z-index: 100;
-				background: #fff;
-				top: 0;
-				left: 0;
-				width: 100%;
-				height: 100%;
-			"
+			style="position: fixed; z-index: 100; top: 0; left: 0; width: 100%; height: 100%"
 		>
 			<style type="text/css" nonce="">
 				html {
@@ -93,3 +85,20 @@
 		</div>
 	</body>
 </html>
+
+<style type="text/css" nonce="">
+	html {
+		overflow-y: hidden !important;
+	}
+
+	#splash-screen {
+		background: #fff;
+	}
+	html.dark #splash-screen {
+		background: #000;
+	}
+
+	html.dark #splash-screen img {
+		filter: invert(1);
+	}
+</style>

+ 3 - 3
src/lib/apis/audio/index.ts

@@ -98,7 +98,7 @@ export const synthesizeOpenAISpeech = async (
 	token: string = '',
 	speaker: string = 'alloy',
 	text: string = '',
-	model: string = 'tts-1'
+	model?: string
 ) => {
 	let error = null;
 
@@ -109,9 +109,9 @@ export const synthesizeOpenAISpeech = async (
 			'Content-Type': 'application/json'
 		},
 		body: JSON.stringify({
-			model: model,
 			input: text,
-			voice: speaker
+			voice: speaker,
+			...(model && { model })
 		})
 	})
 		.then(async (res) => {

+ 178 - 0
src/lib/apis/index.ts

@@ -104,6 +104,147 @@ export const chatCompleted = async (token: string, body: ChatCompletedForm) => {
 	return res;
 };
 
+export const getTaskConfig = async (token: string = '') => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/task/config`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { authorization: `Bearer ${token}` })
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			error = err;
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const updateTaskConfig = async (token: string, config: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/task/config/update`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { 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);
+			if ('detail' in err) {
+				error = err.detail;
+			} else {
+				error = err;
+			}
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const generateTitle = async (
+	token: string = '',
+	model: string,
+	prompt: string,
+	chat_id?: string
+) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/task/title/completions`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			Authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			model: model,
+			prompt: prompt,
+			...(chat_id && { chat_id: chat_id })
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			if ('detail' in err) {
+				error = err.detail;
+			}
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? 'New Chat';
+};
+
+export const generateSearchQuery = async (
+	token: string = '',
+	model: string,
+	messages: object[],
+	prompt: string
+) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/task/query/completions`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			Authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			model: model,
+			messages: messages,
+			prompt: prompt
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			if ('detail' in err) {
+				error = err.detail;
+			}
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? prompt;
+};
+
 export const getPipelinesList = async (token: string = '') => {
 	let error = null;
 
@@ -133,6 +274,43 @@ export const getPipelinesList = async (token: string = '') => {
 	return pipelines;
 };
 
+export const uploadPipeline = async (token: string, file: File, urlIdx: string) => {
+	let error = null;
+
+	// Create a new FormData object to handle the file upload
+	const formData = new FormData();
+	formData.append('file', file);
+	formData.append('urlIdx', urlIdx);
+
+	const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/upload`, {
+		method: 'POST',
+		headers: {
+			...(token && { authorization: `Bearer ${token}` })
+			// 'Content-Type': 'multipart/form-data' is not needed as Fetch API will set it automatically
+		},
+		body: formData
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.catch((err) => {
+			console.log(err);
+			if ('detail' in err) {
+				error = err.detail;
+			} else {
+				error = err;
+			}
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
 export const downloadPipeline = async (token: string, url: string, urlIdx: string) => {
 	let error = null;
 

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

@@ -0,0 +1,390 @@
+<script>
+	import { getContext, tick } from 'svelte';
+	import { toast } from 'svelte-sonner';
+
+	import Database from './Settings/Database.svelte';
+
+	import General from './Settings/General.svelte';
+	import Users from './Settings/Users.svelte';
+
+	import Pipelines from './Settings/Pipelines.svelte';
+	import Audio from './Settings/Audio.svelte';
+	import Images from './Settings/Images.svelte';
+	import Interface from './Settings/Interface.svelte';
+	import Models from './Settings/Models.svelte';
+	import Connections from './Settings/Connections.svelte';
+	import Documents from './Settings/Documents.svelte';
+	import WebSearch from './Settings/WebSearch.svelte';
+	import { config } from '$lib/stores';
+	import { getBackendConfig } from '$lib/apis';
+
+	const i18n = getContext('i18n');
+
+	let selectedTab = 'general';
+</script>
+
+<div class="flex flex-col lg:flex-row w-full h-full py-2 lg:space-x-4">
+	<div
+		class="tabs flex flex-row overflow-x-auto space-x-1 max-w-full lg:space-x-0 lg:space-y-1 lg:flex-col lg:flex-none lg:w-44 dark:text-gray-200 text-xs text-left scrollbar-none"
+	>
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 lg:flex-none flex text-right transition {selectedTab ===
+			'general'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'general';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						fill-rule="evenodd"
+						d="M6.955 1.45A.5.5 0 0 1 7.452 1h1.096a.5.5 0 0 1 .497.45l.17 1.699c.484.12.94.312 1.356.562l1.321-1.081a.5.5 0 0 1 .67.033l.774.775a.5.5 0 0 1 .034.67l-1.08 1.32c.25.417.44.873.561 1.357l1.699.17a.5.5 0 0 1 .45.497v1.096a.5.5 0 0 1-.45.497l-1.699.17c-.12.484-.312.94-.562 1.356l1.082 1.322a.5.5 0 0 1-.034.67l-.774.774a.5.5 0 0 1-.67.033l-1.322-1.08c-.416.25-.872.44-1.356.561l-.17 1.699a.5.5 0 0 1-.497.45H7.452a.5.5 0 0 1-.497-.45l-.17-1.699a4.973 4.973 0 0 1-1.356-.562L4.108 13.37a.5.5 0 0 1-.67-.033l-.774-.775a.5.5 0 0 1-.034-.67l1.08-1.32a4.971 4.971 0 0 1-.561-1.357l-1.699-.17A.5.5 0 0 1 1 8.548V7.452a.5.5 0 0 1 .45-.497l1.699-.17c.12-.484.312-.94.562-1.356L2.629 4.107a.5.5 0 0 1 .034-.67l.774-.774a.5.5 0 0 1 .67-.033L5.43 3.71a4.97 4.97 0 0 1 1.356-.561l.17-1.699ZM6 8c0 .538.212 1.026.558 1.385l.057.057a2 2 0 0 0 2.828-2.828l-.058-.056A2 2 0 0 0 6 8Z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('General')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'users'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'users';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						d="M8 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM3.156 11.763c.16-.629.44-1.21.813-1.72a2.5 2.5 0 0 0-2.725 1.377c-.136.287.102.58.418.58h1.449c.01-.077.025-.156.045-.237ZM12.847 11.763c.02.08.036.16.046.237h1.446c.316 0 .554-.293.417-.579a2.5 2.5 0 0 0-2.722-1.378c.374.51.653 1.09.813 1.72ZM14 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM5 13c-.552 0-1.013-.455-.876-.99a4.002 4.002 0 0 1 7.753 0c.136.535-.324.99-.877.99H5Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Users')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'connections'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'connections';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						d="M1 9.5A3.5 3.5 0 0 0 4.5 13H12a3 3 0 0 0 .917-5.857 2.503 2.503 0 0 0-3.198-3.019 3.5 3.5 0 0 0-6.628 2.171A3.5 3.5 0 0 0 1 9.5Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Connections')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'models'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'models';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 20 20"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						fill-rule="evenodd"
+						d="M10 1c3.866 0 7 1.79 7 4s-3.134 4-7 4-7-1.79-7-4 3.134-4 7-4zm5.694 8.13c.464-.264.91-.583 1.306-.952V10c0 2.21-3.134 4-7 4s-7-1.79-7-4V8.178c.396.37.842.688 1.306.953C5.838 10.006 7.854 10.5 10 10.5s4.162-.494 5.694-1.37zM3 13.179V15c0 2.21 3.134 4 7 4s7-1.79 7-4v-1.822c-.396.37-.842.688-1.306.953-1.532.875-3.548 1.369-5.694 1.369s-4.162-.494-5.694-1.37A7.009 7.009 0 013 13.179z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Models')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'documents'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'documents';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 24 24"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path d="M11.625 16.5a1.875 1.875 0 1 0 0-3.75 1.875 1.875 0 0 0 0 3.75Z" />
+					<path
+						fill-rule="evenodd"
+						d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm6 16.5c.66 0 1.277-.19 1.797-.518l1.048 1.048a.75.75 0 0 0 1.06-1.06l-1.047-1.048A3.375 3.375 0 1 0 11.625 18Z"
+						clip-rule="evenodd"
+					/>
+					<path
+						d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Documents')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'web'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'web';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 24 24"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Web Search')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'interface'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'interface';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						fill-rule="evenodd"
+						d="M2 4.25A2.25 2.25 0 0 1 4.25 2h7.5A2.25 2.25 0 0 1 14 4.25v5.5A2.25 2.25 0 0 1 11.75 12h-1.312c.1.128.21.248.328.36a.75.75 0 0 1 .234.545v.345a.75.75 0 0 1-.75.75h-4.5a.75.75 0 0 1-.75-.75v-.345a.75.75 0 0 1 .234-.545c.118-.111.228-.232.328-.36H4.25A2.25 2.25 0 0 1 2 9.75v-5.5Zm2.25-.75a.75.75 0 0 0-.75.75v4.5c0 .414.336.75.75.75h7.5a.75.75 0 0 0 .75-.75v-4.5a.75.75 0 0 0-.75-.75h-7.5Z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Interface')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'audio'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'audio';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						d="M7.557 2.066A.75.75 0 0 1 8 2.75v10.5a.75.75 0 0 1-1.248.56L3.59 11H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h1.59l3.162-2.81a.75.75 0 0 1 .805-.124ZM12.95 3.05a.75.75 0 1 0-1.06 1.06 5.5 5.5 0 0 1 0 7.78.75.75 0 1 0 1.06 1.06 7 7 0 0 0 0-9.9Z"
+					/>
+					<path
+						d="M10.828 5.172a.75.75 0 1 0-1.06 1.06 2.5 2.5 0 0 1 0 3.536.75.75 0 1 0 1.06 1.06 4 4 0 0 0 0-5.656Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Audio')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'images'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'images';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-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-2V4Zm10.5 5.707a.5.5 0 0 0-.146-.353l-1-1a.5.5 0 0 0-.708 0L9.354 9.646a.5.5 0 0 1-.708 0L6.354 7.354a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0-.146.353V12a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5V9.707ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Images')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'pipelines'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'pipelines';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 24 24"
+					fill="currentColor"
+					class="size-4"
+				>
+					<path
+						d="M11.644 1.59a.75.75 0 0 1 .712 0l9.75 5.25a.75.75 0 0 1 0 1.32l-9.75 5.25a.75.75 0 0 1-.712 0l-9.75-5.25a.75.75 0 0 1 0-1.32l9.75-5.25Z"
+					/>
+					<path
+						d="m3.265 10.602 7.668 4.129a2.25 2.25 0 0 0 2.134 0l7.668-4.13 1.37.739a.75.75 0 0 1 0 1.32l-9.75 5.25a.75.75 0 0 1-.71 0l-9.75-5.25a.75.75 0 0 1 0-1.32l1.37-.738Z"
+					/>
+					<path
+						d="m10.933 19.231-7.668-4.13-1.37.739a.75.75 0 0 0 0 1.32l9.75 5.25c.221.12.489.12.71 0l9.75-5.25a.75.75 0 0 0 0-1.32l-1.37-.738-7.668 4.13a2.25 2.25 0 0 1-2.134-.001Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Pipelines')}</div>
+		</button>
+
+		<button
+			class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+			'db'
+				? 'bg-gray-200 dark:bg-gray-800'
+				: ' hover:bg-gray-300 dark:hover:bg-gray-850'}"
+			on:click={() => {
+				selectedTab = 'db';
+			}}
+		>
+			<div class=" self-center mr-2">
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 16 16"
+					fill="currentColor"
+					class="w-4 h-4"
+				>
+					<path d="M8 7c3.314 0 6-1.343 6-3s-2.686-3-6-3-6 1.343-6 3 2.686 3 6 3Z" />
+					<path
+						d="M8 8.5c1.84 0 3.579-.37 4.914-1.037A6.33 6.33 0 0 0 14 6.78V8c0 1.657-2.686 3-6 3S2 9.657 2 8V6.78c.346.273.72.5 1.087.683C4.42 8.131 6.16 8.5 8 8.5Z"
+					/>
+					<path
+						d="M8 12.5c1.84 0 3.579-.37 4.914-1.037.366-.183.74-.41 1.086-.684V12c0 1.657-2.686 3-6 3s-6-1.343-6-3v-1.22c.346.273.72.5 1.087.683C4.42 12.131 6.16 12.5 8 12.5Z"
+					/>
+				</svg>
+			</div>
+			<div class=" self-center">{$i18n.t('Database')}</div>
+		</button>
+	</div>
+
+	<div class="flex-1 mt-3 lg:mt-0 overflow-y-scroll">
+		{#if selectedTab === 'general'}
+			<General
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'users'}
+			<Users
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'connections'}
+			<Connections
+				on:save={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'models'}
+			<Models />
+		{:else if selectedTab === 'documents'}
+			<Documents
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'web'}
+			<WebSearch
+				saveHandler={async () => {
+					toast.success($i18n.t('Settings saved successfully!'));
+
+					await tick();
+					await config.set(await getBackendConfig());
+				}}
+			/>
+		{:else if selectedTab === 'interface'}
+			<Interface
+				on:save={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'audio'}
+			<Audio
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'images'}
+			<Images
+				on:save={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'db'}
+			<Database
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{:else if selectedTab === 'pipelines'}
+			<Pipelines
+				saveHandler={() => {
+					toast.success($i18n.t('Settings saved successfully!'));
+				}}
+			/>
+		{/if}
+	</div>
+</div>

+ 302 - 0
src/lib/components/admin/Settings/Audio.svelte

@@ -0,0 +1,302 @@
+<script lang="ts">
+	import { getAudioConfig, updateAudioConfig } from '$lib/apis/audio';
+	import { user, settings, config } from '$lib/stores';
+	import { createEventDispatcher, onMount, getContext } from 'svelte';
+	import { toast } from 'svelte-sonner';
+	import Switch from '$lib/components/common/Switch.svelte';
+	import { getBackendConfig } from '$lib/apis';
+	const dispatch = createEventDispatcher();
+
+	const i18n = getContext('i18n');
+
+	export let saveHandler: Function;
+
+	// Audio
+
+	let TTS_OPENAI_API_BASE_URL = '';
+	let TTS_OPENAI_API_KEY = '';
+	let TTS_ENGINE = '';
+	let TTS_MODEL = '';
+	let TTS_VOICE = '';
+
+	let STT_OPENAI_API_BASE_URL = '';
+	let STT_OPENAI_API_KEY = '';
+	let STT_ENGINE = '';
+	let STT_MODEL = '';
+
+	let voices = [];
+	let models = [];
+	let nonLocalVoices = false;
+
+	const getOpenAIVoices = () => {
+		voices = [
+			{ name: 'alloy' },
+			{ name: 'echo' },
+			{ name: 'fable' },
+			{ name: 'onyx' },
+			{ name: 'nova' },
+			{ name: 'shimmer' }
+		];
+	};
+
+	const getOpenAIModels = () => {
+		models = [{ name: 'tts-1' }, { name: 'tts-1-hd' }];
+	};
+
+	const getWebAPIVoices = () => {
+		const getVoicesLoop = setInterval(async () => {
+			voices = await speechSynthesis.getVoices();
+
+			// do your loop
+			if (voices.length > 0) {
+				clearInterval(getVoicesLoop);
+			}
+		}, 100);
+	};
+
+	const updateConfigHandler = async () => {
+		const res = await updateAudioConfig(localStorage.token, {
+			tts: {
+				OPENAI_API_BASE_URL: TTS_OPENAI_API_BASE_URL,
+				OPENAI_API_KEY: TTS_OPENAI_API_KEY,
+				ENGINE: TTS_ENGINE,
+				MODEL: TTS_MODEL,
+				VOICE: TTS_VOICE
+			},
+			stt: {
+				OPENAI_API_BASE_URL: STT_OPENAI_API_BASE_URL,
+				OPENAI_API_KEY: STT_OPENAI_API_KEY,
+				ENGINE: STT_ENGINE,
+				MODEL: STT_MODEL
+			}
+		});
+
+		if (res) {
+			toast.success('Audio settings updated successfully');
+
+			config.set(await getBackendConfig());
+		}
+	};
+
+	onMount(async () => {
+		const res = await getAudioConfig(localStorage.token);
+
+		if (res) {
+			console.log(res);
+			TTS_OPENAI_API_BASE_URL = res.tts.OPENAI_API_BASE_URL;
+			TTS_OPENAI_API_KEY = res.tts.OPENAI_API_KEY;
+
+			TTS_ENGINE = res.tts.ENGINE;
+			TTS_MODEL = res.tts.MODEL;
+			TTS_VOICE = res.tts.VOICE;
+
+			STT_OPENAI_API_BASE_URL = res.stt.OPENAI_API_BASE_URL;
+			STT_OPENAI_API_KEY = res.stt.OPENAI_API_KEY;
+
+			STT_ENGINE = res.stt.ENGINE;
+			STT_MODEL = res.stt.MODEL;
+		}
+
+		if (TTS_ENGINE === 'openai') {
+			getOpenAIVoices();
+			getOpenAIModels();
+		} else {
+			getWebAPIVoices();
+		}
+	});
+</script>
+
+<form
+	class="flex flex-col h-full justify-between space-y-3 text-sm"
+	on:submit|preventDefault={async () => {
+		await updateConfigHandler();
+		dispatch('save');
+	}}
+>
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
+		<div class="flex flex-col gap-3">
+			<div>
+				<div class=" mb-1 text-sm font-medium">{$i18n.t('STT Settings')}</div>
+
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs font-medium">{$i18n.t('Speech-to-Text 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={STT_ENGINE}
+							placeholder="Select an engine"
+						>
+							<option value="">{$i18n.t('Whisper (Local)')}</option>
+							<option value="openai">OpenAI</option>
+							<option value="web">{$i18n.t('Web API')}</option>
+						</select>
+					</div>
+				</div>
+
+				{#if STT_ENGINE === 'openai'}
+					<div>
+						<div class="mt-1 flex gap-2 mb-1">
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('API Base URL')}
+								bind:value={STT_OPENAI_API_BASE_URL}
+								required
+							/>
+
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('API Key')}
+								bind:value={STT_OPENAI_API_KEY}
+								required
+							/>
+						</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
+									list="model-list"
+									class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+									bind:value={STT_MODEL}
+									placeholder="Select a model"
+								/>
+
+								<datalist id="model-list">
+									<option value="whisper-1" />
+								</datalist>
+							</div>
+						</div>
+					</div>
+				{/if}
+			</div>
+
+			<hr class=" dark:border-gray-800" />
+
+			<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={TTS_ENGINE}
+							placeholder="Select a mode"
+							on:change={(e) => {
+								if (e.target.value === 'openai') {
+									getOpenAIVoices();
+									TTS_VOICE = 'alloy';
+									TTS_MODEL = 'tts-1';
+								} else {
+									getWebAPIVoices();
+									TTS_VOICE = '';
+								}
+							}}
+						>
+							<option value="">{$i18n.t('Web API')}</option>
+							<option value="openai">{$i18n.t('Open AI')}</option>
+						</select>
+					</div>
+				</div>
+
+				{#if TTS_ENGINE === 'openai'}
+					<div>
+						<div class="mt-1 flex gap-2 mb-1">
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('API Base URL')}
+								bind:value={TTS_OPENAI_API_BASE_URL}
+								required
+							/>
+
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('API Key')}
+								bind:value={TTS_OPENAI_API_KEY}
+								required
+							/>
+						</div>
+					</div>
+				{/if}
+
+				<hr class=" dark:border-gray-850 my-2" />
+
+				{#if TTS_ENGINE === ''}
+					<div>
+						<div class=" mb-1.5 text-sm font-medium">{$i18n.t('TTS Voice')}</div>
+						<div class="flex w-full">
+							<div class="flex-1">
+								<select
+									class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+									bind:value={TTS_VOICE}
+								>
+									<option value="" selected={TTS_VOICE !== ''}>{$i18n.t('Default')}</option>
+									{#each voices as voice}
+										<option
+											value={voice.voiceURI}
+											class="bg-gray-100 dark:bg-gray-700"
+											selected={TTS_VOICE === voice.voiceURI}>{voice.name}</option
+										>
+									{/each}
+								</select>
+							</div>
+						</div>
+					</div>
+				{:else if TTS_ENGINE === 'openai'}
+					<div class=" flex gap-2">
+						<div class="w-full">
+							<div class=" mb-1.5 text-sm font-medium">{$i18n.t('TTS 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={TTS_VOICE}
+										placeholder="Select a voice"
+									/>
+
+									<datalist id="voice-list">
+										{#each voices as voice}
+											<option value={voice.name} />
+										{/each}
+									</datalist>
+								</div>
+							</div>
+						</div>
+						<div class="w-full">
+							<div class=" mb-1.5 text-sm font-medium">{$i18n.t('TTS Model')}</div>
+							<div class="flex w-full">
+								<div class="flex-1">
+									<input
+										list="model-list"
+										class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+										bind:value={TTS_MODEL}
+										placeholder="Select a model"
+									/>
+
+									<datalist id="model-list">
+										{#each models as model}
+											<option value={model.name} />
+										{/each}
+									</datalist>
+								</div>
+							</div>
+						</div>
+					</div>
+				{/if}
+			</div>
+		</div>
+	</div>
+	<div class="flex justify-end text-sm font-medium">
+		<button
+			class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
+			type="submit"
+		>
+			{$i18n.t('Save')}
+		</button>
+	</div>
+</form>

+ 0 - 137
src/lib/components/admin/Settings/Banners.svelte

@@ -1,137 +0,0 @@
-<script lang="ts">
-	import { v4 as uuidv4 } from 'uuid';
-
-	import { getContext, onMount } from 'svelte';
-	import { banners as _banners } from '$lib/stores';
-	import type { Banner } from '$lib/types';
-
-	import { getBanners, setBanners } from '$lib/apis/configs';
-
-	import type { Writable } from 'svelte/store';
-	import type { i18n as i18nType } from 'i18next';
-	import Tooltip from '$lib/components/common/Tooltip.svelte';
-	import Switch from '$lib/components/common/Switch.svelte';
-	const i18n: Writable<i18nType> = getContext('i18n');
-
-	export let saveHandler: Function;
-
-	let banners: Banner[] = [];
-
-	onMount(async () => {
-		banners = await getBanners(localStorage.token);
-	});
-
-	const updateBanners = async () => {
-		_banners.set(await setBanners(localStorage.token, banners));
-	};
-</script>
-
-<form
-	class="flex flex-col h-full justify-between space-y-3 text-sm"
-	on:submit|preventDefault={async () => {
-		updateBanners();
-		saveHandler();
-	}}
->
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80 h-full">
-		<div class=" space-y-3 pr-1.5">
-			<div class="flex w-full justify-between mb-2">
-				<div class=" self-center text-sm font-semibold">
-					{$i18n.t('Banners')}
-				</div>
-
-				<button
-					class="p-1 px-3 text-xs flex rounded transition"
-					type="button"
-					on:click={() => {
-						if (banners.length === 0 || banners.at(-1).content !== '') {
-							banners = [
-								...banners,
-								{
-									id: uuidv4(),
-									type: '',
-									title: '',
-									content: '',
-									dismissible: true,
-									timestamp: Math.floor(Date.now() / 1000)
-								}
-							];
-						}
-					}}
-				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						viewBox="0 0 20 20"
-						fill="currentColor"
-						class="w-4 h-4"
-					>
-						<path
-							d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
-						/>
-					</svg>
-				</button>
-			</div>
-			<div class="flex flex-col space-y-1">
-				{#each banners as banner, bannerIdx}
-					<div class=" flex justify-between">
-						<div class="flex flex-row flex-1 border rounded-xl dark:border-gray-800">
-							<select
-								class="w-fit capitalize rounded-xl py-2 px-4 text-xs bg-transparent outline-none"
-								bind:value={banner.type}
-							>
-								{#if banner.type == ''}
-									<option value="" selected disabled class="text-gray-900">{$i18n.t('Type')}</option
-									>
-								{/if}
-								<option value="info" class="text-gray-900">{$i18n.t('Info')}</option>
-								<option value="warning" class="text-gray-900">{$i18n.t('Warning')}</option>
-								<option value="error" class="text-gray-900">{$i18n.t('Error')}</option>
-								<option value="success" class="text-gray-900">{$i18n.t('Success')}</option>
-							</select>
-
-							<input
-								class="pr-5 py-1.5 text-xs w-full bg-transparent outline-none"
-								placeholder={$i18n.t('Content')}
-								bind:value={banner.content}
-							/>
-
-							<div class="relative top-1.5 -left-2">
-								<Tooltip content="Dismissible" className="flex h-fit items-center">
-									<Switch bind:state={banner.dismissible} />
-								</Tooltip>
-							</div>
-						</div>
-
-						<button
-							class="px-2"
-							type="button"
-							on:click={() => {
-								banners.splice(bannerIdx, 1);
-								banners = banners;
-							}}
-						>
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 20 20"
-								fill="currentColor"
-								class="w-4 h-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"
-								/>
-							</svg>
-						</button>
-					</div>
-				{/each}
-			</div>
-		</div>
-	</div>
-	<div class="flex justify-end pt-3 text-sm font-medium">
-		<button
-			class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
-			type="submit"
-		>
-			Save
-		</button>
-	</div>
-</form>

+ 7 - 3
src/lib/components/chat/Settings/Connections.svelte → src/lib/components/admin/Settings/Connections.svelte

@@ -23,10 +23,14 @@
 	import Switch from '$lib/components/common/Switch.svelte';
 	import Spinner from '$lib/components/common/Spinner.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import { getModels as _getModels } from '$lib/apis';
 
 	const i18n = getContext('i18n');
 
-	export let getModels: Function;
+	const getModels = async () => {
+		const models = await _getModels(localStorage.token);
+		return models;
+	};
 
 	// External
 	let OLLAMA_BASE_URLS = [''];
@@ -158,7 +162,7 @@
 		dispatch('save');
 	}}
 >
-	<div class="space-y-3 pr-1.5 overflow-y-scroll h-[24rem] max-h-[25rem]">
+	<div class="space-y-3 overflow-y-scroll scrollbar-hidden h-full">
 		{#if ENABLE_OPENAI_API !== null && ENABLE_OLLAMA_API !== null}
 			<div class=" space-y-3">
 				<div class="mt-2 space-y-2 pr-1.5">
@@ -300,7 +304,7 @@
 				</div>
 			</div>
 
-			<hr class=" dark:border-gray-700" />
+			<hr class=" dark:border-gray-850" />
 
 			<div class="pr-1.5 space-y-2">
 				<div class="flex justify-between items-center text-sm">

+ 1 - 1
src/lib/components/admin/Settings/Database.svelte

@@ -30,7 +30,7 @@
 		saveHandler();
 	}}
 >
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
 		<div>
 			<div class=" mb-2 text-sm font-medium">{$i18n.t('Database')}</div>
 

+ 144 - 7
src/lib/components/documents/Settings/General.svelte → src/lib/components/admin/Settings/Documents.svelte

@@ -9,7 +9,9 @@
 		updateEmbeddingConfig,
 		getRerankingConfig,
 		updateRerankingConfig,
-		resetUploadDir
+		resetUploadDir,
+		getRAGConfig,
+		updateRAGConfig
 	} from '$lib/apis/rag';
 
 	import { documents, models } from '$lib/stores';
@@ -31,6 +33,10 @@
 	let embeddingModel = '';
 	let rerankingModel = '';
 
+	let chunkSize = 0;
+	let chunkOverlap = 0;
+	let pdfExtractImages = true;
+
 	let OpenAIKey = '';
 	let OpenAIUrl = '';
 	let OpenAIBatchSize = 1;
@@ -152,6 +158,14 @@
 		if (querySettings.hybrid) {
 			rerankingModelUpdateHandler();
 		}
+
+		const res = await updateRAGConfig(localStorage.token, {
+			pdf_extract_images: pdfExtractImages,
+			chunk: {
+				chunk_overlap: chunkOverlap,
+				chunk_size: chunkSize
+			}
+		});
 	};
 
 	const setEmbeddingConfig = async () => {
@@ -185,6 +199,15 @@
 		await setRerankingConfig();
 
 		querySettings = await getQuerySettings(localStorage.token);
+
+		const res = await getRAGConfig(localStorage.token);
+
+		if (res) {
+			pdfExtractImages = res.pdf_extract_images;
+
+			chunkSize = res.chunk.chunk_size;
+			chunkOverlap = res.chunk.chunk_overlap;
+		}
 	});
 </script>
 
@@ -195,7 +218,7 @@
 		saveHandler();
 	}}
 >
-	<div class=" space-y-2.5 pr-1.5 overflow-y-scroll max-h-[28rem]">
+	<div class=" space-y-2.5 overflow-y-scroll scrollbar-hidden h-full">
 		<div class="flex flex-col gap-0.5">
 			<div class=" mb-0.5 text-sm font-medium">{$i18n.t('General Settings')}</div>
 
@@ -332,7 +355,7 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700 my-1" />
+		<hr class=" dark:border-gray-850 my-1" />
 
 		<div class="space-y-2" />
 		<div>
@@ -350,10 +373,8 @@
 							{#if !embeddingModel}
 								<option value="" disabled selected>{$i18n.t('Select a model')}</option>
 							{/if}
-							{#each $models.filter((m) => m.id && !m.external) as model}
-								<option value={model.name} class="bg-gray-100 dark:bg-gray-700"
-									>{model.name + ' (' + (model.size / 1024 ** 3).toFixed(1) + ' GB)'}</option
-								>
+							{#each $models.filter((m) => m.id && m.ollama && !(m?.preset ?? false)) as model}
+								<option value={model.id} class="bg-gray-100 dark:bg-gray-700">{model.name}</option>
 							{/each}
 						</select>
 					</div>
@@ -500,6 +521,122 @@
 
 		<hr class=" dark:border-gray-850" />
 
+		<div class=" ">
+			<div class=" text-sm font-medium">{$i18n.t('Query Params')}</div>
+
+			<div class=" flex">
+				<div class="  flex w-full justify-between">
+					<div class="self-center text-xs font-medium min-w-fit">{$i18n.t('Top K')}</div>
+
+					<div class="self-center p-3">
+						<input
+							class=" w-full rounded-lg py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+							type="number"
+							placeholder={$i18n.t('Enter Top K')}
+							bind:value={querySettings.k}
+							autocomplete="off"
+							min="0"
+						/>
+					</div>
+				</div>
+
+				{#if querySettings.hybrid === true}
+					<div class="flex w-full">
+						<div class=" self-center text-xs font-medium min-w-fit">
+							{$i18n.t('Minimum Score')}
+						</div>
+
+						<div class="self-center p-3">
+							<input
+								class=" w-full rounded-lg py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								type="number"
+								step="0.01"
+								placeholder={$i18n.t('Enter Score')}
+								bind:value={querySettings.r}
+								autocomplete="off"
+								min="0.0"
+								title={$i18n.t('The score should be a value between 0.0 (0%) and 1.0 (100%).')}
+							/>
+						</div>
+					</div>
+				{/if}
+			</div>
+
+			{#if querySettings.hybrid === true}
+				<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
+					{$i18n.t(
+						'Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.'
+					)}
+				</div>
+
+				<hr class=" dark:border-gray-850 my-3" />
+			{/if}
+
+			<div>
+				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('RAG Template')}</div>
+				<textarea
+					bind:value={querySettings.template}
+					class="w-full rounded-lg px-4 py-3 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
+					rows="4"
+				/>
+			</div>
+		</div>
+
+		<hr class=" dark:border-gray-850" />
+
+		<div class=" ">
+			<div class=" text-sm font-medium">{$i18n.t('Chunk Params')}</div>
+
+			<div class=" my-2 flex gap-1.5">
+				<div class="  w-full justify-between">
+					<div class="self-center text-xs font-medium min-w-fit mb-1">{$i18n.t('Chunk Size')}</div>
+					<div class="self-center">
+						<input
+							class=" w-full rounded-lg py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+							type="number"
+							placeholder={$i18n.t('Enter Chunk Size')}
+							bind:value={chunkSize}
+							autocomplete="off"
+							min="0"
+						/>
+					</div>
+				</div>
+
+				<div class="w-full">
+					<div class=" self-center text-xs font-medium min-w-fit mb-1">
+						{$i18n.t('Chunk Overlap')}
+					</div>
+
+					<div class="self-center">
+						<input
+							class="w-full rounded-lg py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+							type="number"
+							placeholder={$i18n.t('Enter Chunk Overlap')}
+							bind:value={chunkOverlap}
+							autocomplete="off"
+							min="0"
+						/>
+					</div>
+				</div>
+			</div>
+
+			<div class="my-3">
+				<div class="flex justify-between items-center text-xs">
+					<div class=" text-xs font-medium">{$i18n.t('PDF Extract Images (OCR)')}</div>
+
+					<button
+						class=" text-xs font-medium text-gray-500"
+						type="button"
+						on:click={() => {
+							pdfExtractImages = !pdfExtractImages;
+						}}>{pdfExtractImages ? $i18n.t('On') : $i18n.t('Off')}</button
+					>
+				</div>
+			</div>
+		</div>
+
+		<hr class=" dark:border-gray-850" />
+
 		<div>
 			{#if showResetUploadDirConfirm}
 				<div class="flex justify-between rounded-md items-center py-2 px-3.5 w-full transition">

+ 1 - 1
src/lib/components/admin/Settings/General.svelte

@@ -56,7 +56,7 @@
 		saveHandler();
 	}}
 >
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-[22rem]">
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
 		{#if adminConfig !== null}
 			<div>
 				<div class=" mb-3 text-sm font-medium">{$i18n.t('General Settings')}</div>

+ 3 - 5
src/lib/components/chat/Settings/Images.svelte → src/lib/components/admin/Settings/Images.svelte

@@ -23,8 +23,6 @@
 
 	const i18n = getContext('i18n');
 
-	export let saveSettings: Function;
-
 	let loading = false;
 
 	let imageGenerationEngine = '';
@@ -171,7 +169,7 @@
 		loading = false;
 	}}
 >
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-[24rem]">
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden">
 		<div>
 			<div class=" mb-1 text-sm font-medium">{$i18n.t('Image Settings')}</div>
 
@@ -228,7 +226,7 @@
 				</div>
 			</div>
 		</div>
-		<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-850" />
 
 		{#if imageGenerationEngine === ''}
 			<div class=" mb-2.5 text-sm font-medium">{$i18n.t('AUTOMATIC1111 Base URL')}</div>
@@ -326,7 +324,7 @@
 		{/if}
 
 		{#if enableImageGeneration}
-			<hr class=" dark:border-gray-700" />
+			<hr class=" dark:border-gray-850" />
 
 			<div>
 				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Default Model')}</div>

+ 339 - 0
src/lib/components/admin/Settings/Interface.svelte

@@ -0,0 +1,339 @@
+<script lang="ts">
+	import { v4 as uuidv4 } from 'uuid';
+	import { toast } from 'svelte-sonner';
+
+	import { getBackendConfig, getTaskConfig, updateTaskConfig } from '$lib/apis';
+	import { setDefaultPromptSuggestions } from '$lib/apis/configs';
+	import { config, models, settings, user } from '$lib/stores';
+	import { createEventDispatcher, onMount, getContext } from 'svelte';
+
+	import { banners as _banners } from '$lib/stores';
+	import type { Banner } from '$lib/types';
+
+	import { getBanners, setBanners } from '$lib/apis/configs';
+
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Switch from '$lib/components/common/Switch.svelte';
+
+	const dispatch = createEventDispatcher();
+
+	const i18n = getContext('i18n');
+
+	let taskConfig = {
+		TASK_MODEL: '',
+		TASK_MODEL_EXTERNAL: '',
+		TITLE_GENERATION_PROMPT_TEMPLATE: '',
+		SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE: '',
+		SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD: 0
+	};
+
+	let promptSuggestions = [];
+	let banners: Banner[] = [];
+
+	const updateInterfaceHandler = async () => {
+		taskConfig = await updateTaskConfig(localStorage.token, taskConfig);
+
+		promptSuggestions = await setDefaultPromptSuggestions(localStorage.token, promptSuggestions);
+		await updateBanners();
+
+		await config.set(await getBackendConfig());
+	};
+
+	onMount(async () => {
+		taskConfig = await getTaskConfig(localStorage.token);
+
+		promptSuggestions = $config?.default_prompt_suggestions;
+
+		banners = await getBanners(localStorage.token);
+	});
+
+	const updateBanners = async () => {
+		_banners.set(await setBanners(localStorage.token, banners));
+	};
+</script>
+
+<form
+	class="flex flex-col h-full justify-between space-y-3 text-sm"
+	on:submit|preventDefault={() => {
+		updateInterfaceHandler();
+		dispatch('save');
+	}}
+>
+	<div class="  overflow-y-scroll scrollbar-hidden h-full pr-1.5">
+		<div>
+			<div class=" mb-2.5 text-sm font-medium flex">
+				<div class=" mr-1">{$i18n.t('Set Task Model')}</div>
+				<Tooltip
+					content={$i18n.t(
+						'A task model is used when performing tasks such as generating titles for chats and web search queries'
+					)}
+				>
+					<svg
+						xmlns="http://www.w3.org/2000/svg"
+						fill="none"
+						viewBox="0 0 24 24"
+						stroke-width="1.5"
+						stroke="currentColor"
+						class="w-5 h-5"
+					>
+						<path
+							stroke-linecap="round"
+							stroke-linejoin="round"
+							d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
+						/>
+					</svg>
+				</Tooltip>
+			</div>
+			<div class="flex w-full gap-2">
+				<div class="flex-1">
+					<div class=" text-xs mb-1">{$i18n.t('Local Models')}</div>
+					<select
+						class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+						bind:value={taskConfig.TASK_MODEL}
+						placeholder={$i18n.t('Select a model')}
+					>
+						<option value="" selected>{$i18n.t('Current Model')}</option>
+						{#each $models.filter((m) => m.owned_by === 'ollama') as model}
+							<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
+								{model.name}
+							</option>
+						{/each}
+					</select>
+				</div>
+
+				<div class="flex-1">
+					<div class=" text-xs mb-1">{$i18n.t('External Models')}</div>
+					<select
+						class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+						bind:value={taskConfig.TASK_MODEL_EXTERNAL}
+						placeholder={$i18n.t('Select a model')}
+					>
+						<option value="" selected>{$i18n.t('Current Model')}</option>
+						{#each $models as model}
+							<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
+								{model.name}
+							</option>
+						{/each}
+					</select>
+				</div>
+			</div>
+
+			<div class="mt-3">
+				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Title Generation Prompt')}</div>
+				<textarea
+					bind:value={taskConfig.TITLE_GENERATION_PROMPT_TEMPLATE}
+					class="w-full rounded-lg py-3 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
+					rows="6"
+				/>
+			</div>
+
+			<div class="mt-3">
+				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Search Query Generation Prompt')}</div>
+				<textarea
+					bind:value={taskConfig.SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE}
+					class="w-full rounded-lg py-3 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
+					rows="6"
+				/>
+			</div>
+
+			<div class="mt-3">
+				<div class=" mb-2.5 text-sm font-medium">
+					{$i18n.t('Search Query Generation Prompt Length Threshold')}
+				</div>
+				<input
+					bind:value={taskConfig.SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD}
+					class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
+					type="number"
+				/>
+			</div>
+		</div>
+
+		<hr class=" dark:border-gray-850 my-3" />
+
+		<div class=" space-y-3 {banners.length > 0 ? ' mb-3' : ''}">
+			<div class="flex w-full justify-between">
+				<div class=" self-center text-sm font-semibold">
+					{$i18n.t('Banners')}
+				</div>
+
+				<button
+					class="p-1 px-3 text-xs flex rounded transition"
+					type="button"
+					on:click={() => {
+						if (banners.length === 0 || banners.at(-1).content !== '') {
+							banners = [
+								...banners,
+								{
+									id: uuidv4(),
+									type: '',
+									title: '',
+									content: '',
+									dismissible: true,
+									timestamp: Math.floor(Date.now() / 1000)
+								}
+							];
+						}
+					}}
+				>
+					<svg
+						xmlns="http://www.w3.org/2000/svg"
+						viewBox="0 0 20 20"
+						fill="currentColor"
+						class="w-4 h-4"
+					>
+						<path
+							d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
+						/>
+					</svg>
+				</button>
+			</div>
+			<div class="flex flex-col space-y-1">
+				{#each banners as banner, bannerIdx}
+					<div class=" flex justify-between">
+						<div class="flex flex-row flex-1 border rounded-xl dark:border-gray-800">
+							<select
+								class="w-fit capitalize rounded-xl py-2 px-4 text-xs bg-transparent outline-none"
+								bind:value={banner.type}
+								required
+							>
+								{#if banner.type == ''}
+									<option value="" selected disabled class="text-gray-900">{$i18n.t('Type')}</option
+									>
+								{/if}
+								<option value="info" class="text-gray-900">{$i18n.t('Info')}</option>
+								<option value="warning" class="text-gray-900">{$i18n.t('Warning')}</option>
+								<option value="error" class="text-gray-900">{$i18n.t('Error')}</option>
+								<option value="success" class="text-gray-900">{$i18n.t('Success')}</option>
+							</select>
+
+							<input
+								class="pr-5 py-1.5 text-xs w-full bg-transparent outline-none"
+								placeholder={$i18n.t('Content')}
+								bind:value={banner.content}
+							/>
+
+							<div class="relative top-1.5 -left-2">
+								<Tooltip content={$i18n.t('Dismissible')} className="flex h-fit items-center">
+									<Switch bind:state={banner.dismissible} />
+								</Tooltip>
+							</div>
+						</div>
+
+						<button
+							class="px-2"
+							type="button"
+							on:click={() => {
+								banners.splice(bannerIdx, 1);
+								banners = banners;
+							}}
+						>
+							<svg
+								xmlns="http://www.w3.org/2000/svg"
+								viewBox="0 0 20 20"
+								fill="currentColor"
+								class="w-4 h-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"
+								/>
+							</svg>
+						</button>
+					</div>
+				{/each}
+			</div>
+		</div>
+
+		{#if $user.role === 'admin'}
+			<div class=" space-y-3">
+				<div class="flex w-full justify-between mb-2">
+					<div class=" self-center text-sm font-semibold">
+						{$i18n.t('Default Prompt Suggestions')}
+					</div>
+
+					<button
+						class="p-1 px-3 text-xs flex rounded transition"
+						type="button"
+						on:click={() => {
+							if (promptSuggestions.length === 0 || promptSuggestions.at(-1).content !== '') {
+								promptSuggestions = [...promptSuggestions, { content: '', title: ['', ''] }];
+							}
+						}}
+					>
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							viewBox="0 0 20 20"
+							fill="currentColor"
+							class="w-4 h-4"
+						>
+							<path
+								d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
+							/>
+						</svg>
+					</button>
+				</div>
+				<div class="grid lg:grid-cols-2 flex-col gap-1.5">
+					{#each promptSuggestions as prompt, promptIdx}
+						<div class=" flex dark:bg-gray-850 rounded-xl py-1.5">
+							<div class="flex flex-col flex-1 pl-1">
+								<div class="flex border-b dark:border-gray-800 w-full">
+									<input
+										class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-800"
+										placeholder={$i18n.t('Title (e.g. Tell me a fun fact)')}
+										bind:value={prompt.title[0]}
+									/>
+
+									<input
+										class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-800"
+										placeholder={$i18n.t('Subtitle (e.g. about the Roman Empire)')}
+										bind:value={prompt.title[1]}
+									/>
+								</div>
+
+								<input
+									class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-800"
+									placeholder={$i18n.t('Prompt (e.g. Tell me a fun fact about the Roman Empire)')}
+									bind:value={prompt.content}
+								/>
+							</div>
+
+							<button
+								class="px-3"
+								type="button"
+								on:click={() => {
+									promptSuggestions.splice(promptIdx, 1);
+									promptSuggestions = promptSuggestions;
+								}}
+							>
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 20 20"
+									fill="currentColor"
+									class="w-4 h-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"
+									/>
+								</svg>
+							</button>
+						</div>
+					{/each}
+				</div>
+
+				{#if promptSuggestions.length > 0}
+					<div class="text-xs text-left w-full mt-2">
+						{$i18n.t('Adjusting these settings will apply changes universally to all users.')}
+					</div>
+				{/if}
+			</div>
+		{/if}
+	</div>
+
+	<div class="flex justify-end text-sm font-medium">
+		<button
+			class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
+			type="submit"
+		>
+			{$i18n.t('Save')}
+		</button>
+	</div>
+</form>

+ 1078 - 0
src/lib/components/admin/Settings/Models.svelte

@@ -0,0 +1,1078 @@
+<script lang="ts">
+	import { toast } from 'svelte-sonner';
+
+	import {
+		createModel,
+		deleteModel,
+		downloadModel,
+		getOllamaUrls,
+		getOllamaVersion,
+		pullModel,
+		uploadModel,
+		getOllamaConfig
+	} from '$lib/apis/ollama';
+
+	import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
+	import { WEBUI_NAME, models, MODEL_DOWNLOAD_POOL, user, config } from '$lib/stores';
+	import { splitStream } from '$lib/utils';
+	import { onMount, getContext } from 'svelte';
+
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Spinner from '$lib/components/common/Spinner.svelte';
+	import { getModels as _getModels } from '$lib/apis';
+
+	const i18n = getContext('i18n');
+
+	const getModels = async () => {
+		return await _getModels(localStorage.token);
+	};
+
+	let modelUploadInputElement: HTMLInputElement;
+
+	// Models
+
+	let ollamaEnabled = null;
+
+	let OLLAMA_URLS = [];
+	let selectedOllamaUrlIdx: string | null = null;
+
+	let updateModelId = null;
+	let updateProgress = null;
+
+	let showExperimentalOllama = false;
+
+	let ollamaVersion = null;
+	const MAX_PARALLEL_DOWNLOADS = 3;
+
+	let modelTransferring = false;
+	let modelTag = '';
+
+	let createModelLoading = false;
+	let createModelTag = '';
+	let createModelContent = '';
+	let createModelDigest = '';
+	let createModelPullProgress = null;
+
+	let digest = '';
+	let pullProgress = null;
+
+	let modelUploadMode = 'file';
+	let modelInputFile: File[] | null = null;
+	let modelFileUrl = '';
+	let modelFileContent = `TEMPLATE """{{ .System }}\nUSER: {{ .Prompt }}\nASSISTANT: """\nPARAMETER num_ctx 4096\nPARAMETER stop "</s>"\nPARAMETER stop "USER:"\nPARAMETER stop "ASSISTANT:"`;
+	let modelFileDigest = '';
+
+	let uploadProgress = null;
+	let uploadMessage = '';
+
+	let deleteModelTag = '';
+
+	const updateModelsHandler = async () => {
+		for (const model of $models.filter(
+			(m) =>
+				!(m?.preset ?? false) &&
+				m.owned_by === 'ollama' &&
+				(selectedOllamaUrlIdx === null
+					? true
+					: (m?.ollama?.urls ?? []).includes(selectedOllamaUrlIdx))
+		)) {
+			console.log(model);
+
+			updateModelId = model.id;
+			const [res, controller] = await pullModel(
+				localStorage.token,
+				model.id,
+				selectedOllamaUrlIdx
+			).catch((error) => {
+				toast.error(error);
+				return null;
+			});
+
+			if (res) {
+				const reader = res.body
+					.pipeThrough(new TextDecoderStream())
+					.pipeThrough(splitStream('\n'))
+					.getReader();
+
+				while (true) {
+					try {
+						const { value, done } = await reader.read();
+						if (done) break;
+
+						let lines = value.split('\n');
+
+						for (const line of lines) {
+							if (line !== '') {
+								let data = JSON.parse(line);
+
+								console.log(data);
+								if (data.error) {
+									throw data.error;
+								}
+								if (data.detail) {
+									throw data.detail;
+								}
+								if (data.status) {
+									if (data.digest) {
+										updateProgress = 0;
+										if (data.completed) {
+											updateProgress = Math.round((data.completed / data.total) * 1000) / 10;
+										} else {
+											updateProgress = 100;
+										}
+									} else {
+										toast.success(data.status);
+									}
+								}
+							}
+						}
+					} catch (error) {
+						console.log(error);
+					}
+				}
+			}
+		}
+
+		updateModelId = null;
+		updateProgress = null;
+	};
+
+	const pullModelHandler = async () => {
+		const sanitizedModelTag = modelTag.trim().replace(/^ollama\s+(run|pull)\s+/, '');
+		console.log($MODEL_DOWNLOAD_POOL);
+		if ($MODEL_DOWNLOAD_POOL[sanitizedModelTag]) {
+			toast.error(
+				$i18n.t(`Model '{{modelTag}}' is already in queue for downloading.`, {
+					modelTag: sanitizedModelTag
+				})
+			);
+			return;
+		}
+		if (Object.keys($MODEL_DOWNLOAD_POOL).length === MAX_PARALLEL_DOWNLOADS) {
+			toast.error(
+				$i18n.t('Maximum of 3 models can be downloaded simultaneously. Please try again later.')
+			);
+			return;
+		}
+
+		const [res, controller] = await pullModel(localStorage.token, sanitizedModelTag, '0').catch(
+			(error) => {
+				toast.error(error);
+				return null;
+			}
+		);
+
+		if (res) {
+			const reader = res.body
+				.pipeThrough(new TextDecoderStream())
+				.pipeThrough(splitStream('\n'))
+				.getReader();
+
+			MODEL_DOWNLOAD_POOL.set({
+				...$MODEL_DOWNLOAD_POOL,
+				[sanitizedModelTag]: {
+					...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
+					abortController: controller,
+					reader,
+					done: false
+				}
+			});
+
+			while (true) {
+				try {
+					const { value, done } = await reader.read();
+					if (done) break;
+
+					let lines = value.split('\n');
+
+					for (const line of lines) {
+						if (line !== '') {
+							let data = JSON.parse(line);
+							console.log(data);
+							if (data.error) {
+								throw data.error;
+							}
+							if (data.detail) {
+								throw data.detail;
+							}
+
+							if (data.status) {
+								if (data.digest) {
+									let downloadProgress = 0;
+									if (data.completed) {
+										downloadProgress = Math.round((data.completed / data.total) * 1000) / 10;
+									} else {
+										downloadProgress = 100;
+									}
+
+									MODEL_DOWNLOAD_POOL.set({
+										...$MODEL_DOWNLOAD_POOL,
+										[sanitizedModelTag]: {
+											...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
+											pullProgress: downloadProgress,
+											digest: data.digest
+										}
+									});
+								} else {
+									toast.success(data.status);
+
+									MODEL_DOWNLOAD_POOL.set({
+										...$MODEL_DOWNLOAD_POOL,
+										[sanitizedModelTag]: {
+											...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
+											done: data.status === 'success'
+										}
+									});
+								}
+							}
+						}
+					}
+				} catch (error) {
+					console.log(error);
+					if (typeof error !== 'string') {
+						error = error.message;
+					}
+
+					toast.error(error);
+					// opts.callback({ success: false, error, modelName: opts.modelName });
+				}
+			}
+
+			console.log($MODEL_DOWNLOAD_POOL[sanitizedModelTag]);
+
+			if ($MODEL_DOWNLOAD_POOL[sanitizedModelTag].done) {
+				toast.success(
+					$i18n.t(`Model '{{modelName}}' has been successfully downloaded.`, {
+						modelName: sanitizedModelTag
+					})
+				);
+
+				models.set(await getModels());
+			} else {
+				toast.error($i18n.t('Download canceled'));
+			}
+
+			delete $MODEL_DOWNLOAD_POOL[sanitizedModelTag];
+
+			MODEL_DOWNLOAD_POOL.set({
+				...$MODEL_DOWNLOAD_POOL
+			});
+		}
+
+		modelTag = '';
+		modelTransferring = false;
+	};
+
+	const uploadModelHandler = async () => {
+		modelTransferring = true;
+
+		let uploaded = false;
+		let fileResponse = null;
+		let name = '';
+
+		if (modelUploadMode === 'file') {
+			const file = modelInputFile ? modelInputFile[0] : null;
+
+			if (file) {
+				uploadMessage = 'Uploading...';
+
+				fileResponse = await uploadModel(localStorage.token, file, selectedOllamaUrlIdx).catch(
+					(error) => {
+						toast.error(error);
+						return null;
+					}
+				);
+			}
+		} else {
+			uploadProgress = 0;
+			fileResponse = await downloadModel(
+				localStorage.token,
+				modelFileUrl,
+				selectedOllamaUrlIdx
+			).catch((error) => {
+				toast.error(error);
+				return null;
+			});
+		}
+
+		if (fileResponse && fileResponse.ok) {
+			const reader = fileResponse.body
+				.pipeThrough(new TextDecoderStream())
+				.pipeThrough(splitStream('\n'))
+				.getReader();
+
+			while (true) {
+				const { value, done } = await reader.read();
+				if (done) break;
+
+				try {
+					let lines = value.split('\n');
+
+					for (const line of lines) {
+						if (line !== '') {
+							let data = JSON.parse(line.replace(/^data: /, ''));
+
+							if (data.progress) {
+								if (uploadMessage) {
+									uploadMessage = '';
+								}
+								uploadProgress = data.progress;
+							}
+
+							if (data.error) {
+								throw data.error;
+							}
+
+							if (data.done) {
+								modelFileDigest = data.blob;
+								name = data.name;
+								uploaded = true;
+							}
+						}
+					}
+				} catch (error) {
+					console.log(error);
+				}
+			}
+		} else {
+			const error = await fileResponse?.json();
+			toast.error(error?.detail ?? error);
+		}
+
+		if (uploaded) {
+			const res = await createModel(
+				localStorage.token,
+				`${name}:latest`,
+				`FROM @${modelFileDigest}\n${modelFileContent}`
+			);
+
+			if (res && res.ok) {
+				const reader = res.body
+					.pipeThrough(new TextDecoderStream())
+					.pipeThrough(splitStream('\n'))
+					.getReader();
+
+				while (true) {
+					const { value, done } = await reader.read();
+					if (done) break;
+
+					try {
+						let lines = value.split('\n');
+
+						for (const line of lines) {
+							if (line !== '') {
+								console.log(line);
+								let data = JSON.parse(line);
+								console.log(data);
+
+								if (data.error) {
+									throw data.error;
+								}
+								if (data.detail) {
+									throw data.detail;
+								}
+
+								if (data.status) {
+									if (
+										!data.digest &&
+										!data.status.includes('writing') &&
+										!data.status.includes('sha256')
+									) {
+										toast.success(data.status);
+									} else {
+										if (data.digest) {
+											digest = data.digest;
+
+											if (data.completed) {
+												pullProgress = Math.round((data.completed / data.total) * 1000) / 10;
+											} else {
+												pullProgress = 100;
+											}
+										}
+									}
+								}
+							}
+						}
+					} catch (error) {
+						console.log(error);
+						toast.error(error);
+					}
+				}
+			}
+		}
+
+		modelFileUrl = '';
+
+		if (modelUploadInputElement) {
+			modelUploadInputElement.value = '';
+		}
+		modelInputFile = null;
+		modelTransferring = false;
+		uploadProgress = null;
+
+		models.set(await getModels());
+	};
+
+	const deleteModelHandler = async () => {
+		const res = await deleteModel(localStorage.token, deleteModelTag, selectedOllamaUrlIdx).catch(
+			(error) => {
+				toast.error(error);
+			}
+		);
+
+		if (res) {
+			toast.success($i18n.t(`Deleted {{deleteModelTag}}`, { deleteModelTag }));
+		}
+
+		deleteModelTag = '';
+		models.set(await getModels());
+	};
+
+	const cancelModelPullHandler = async (model: string) => {
+		const { reader, abortController } = $MODEL_DOWNLOAD_POOL[model];
+		if (abortController) {
+			abortController.abort();
+		}
+		if (reader) {
+			await reader.cancel();
+			delete $MODEL_DOWNLOAD_POOL[model];
+			MODEL_DOWNLOAD_POOL.set({
+				...$MODEL_DOWNLOAD_POOL
+			});
+			await deleteModel(localStorage.token, model);
+			toast.success(`${model} download has been canceled`);
+		}
+	};
+
+	const createModelHandler = async () => {
+		createModelLoading = true;
+		const res = await createModel(
+			localStorage.token,
+			createModelTag,
+			createModelContent,
+			selectedOllamaUrlIdx
+		).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res && res.ok) {
+			const reader = res.body
+				.pipeThrough(new TextDecoderStream())
+				.pipeThrough(splitStream('\n'))
+				.getReader();
+
+			while (true) {
+				const { value, done } = await reader.read();
+				if (done) break;
+
+				try {
+					let lines = value.split('\n');
+
+					for (const line of lines) {
+						if (line !== '') {
+							console.log(line);
+							let data = JSON.parse(line);
+							console.log(data);
+
+							if (data.error) {
+								throw data.error;
+							}
+							if (data.detail) {
+								throw data.detail;
+							}
+
+							if (data.status) {
+								if (
+									!data.digest &&
+									!data.status.includes('writing') &&
+									!data.status.includes('sha256')
+								) {
+									toast.success(data.status);
+								} else {
+									if (data.digest) {
+										createModelDigest = data.digest;
+
+										if (data.completed) {
+											createModelPullProgress =
+												Math.round((data.completed / data.total) * 1000) / 10;
+										} else {
+											createModelPullProgress = 100;
+										}
+									}
+								}
+							}
+						}
+					}
+				} catch (error) {
+					console.log(error);
+					toast.error(error);
+				}
+			}
+		}
+
+		models.set(await getModels());
+
+		createModelLoading = false;
+
+		createModelTag = '';
+		createModelContent = '';
+		createModelDigest = '';
+		createModelPullProgress = null;
+	};
+
+	onMount(async () => {
+		const ollamaConfig = await getOllamaConfig(localStorage.token);
+
+		if (ollamaConfig.ENABLE_OLLAMA_API) {
+			ollamaEnabled = true;
+
+			await Promise.all([
+				(async () => {
+					OLLAMA_URLS = await getOllamaUrls(localStorage.token).catch((error) => {
+						toast.error(error);
+						return [];
+					});
+
+					if (OLLAMA_URLS.length > 0) {
+						selectedOllamaUrlIdx = 0;
+					}
+				})(),
+				(async () => {
+					ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
+				})()
+			]);
+		} else {
+			ollamaEnabled = false;
+			toast.error($i18n.t('Ollama API is disabled'));
+		}
+	});
+</script>
+
+<div class="flex flex-col h-full justify-between text-sm">
+	<div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
+		{#if ollamaEnabled}
+			{#if ollamaVersion !== null}
+				<div class="space-y-2 pr-1.5">
+					<div class="text-sm font-medium">{$i18n.t('Manage Ollama Models')}</div>
+
+					{#if OLLAMA_URLS.length > 0}
+						<div class="flex gap-2">
+							<div class="flex-1 pb-1">
+								<select
+									class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+									bind:value={selectedOllamaUrlIdx}
+									placeholder={$i18n.t('Select an Ollama instance')}
+								>
+									{#each OLLAMA_URLS as url, idx}
+										<option value={idx} class="bg-gray-100 dark:bg-gray-700">{url}</option>
+									{/each}
+								</select>
+							</div>
+
+							<div>
+								<div class="flex w-full justify-end">
+									<Tooltip content="Update All Models" placement="top">
+										<button
+											class="p-2.5 flex gap-2 items-center bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg transition"
+											on:click={() => {
+												updateModelsHandler();
+											}}
+										>
+											<svg
+												xmlns="http://www.w3.org/2000/svg"
+												viewBox="0 0 16 16"
+												fill="currentColor"
+												class="w-4 h-4"
+											>
+												<path
+													d="M7 1a.75.75 0 0 1 .75.75V6h-1.5V1.75A.75.75 0 0 1 7 1ZM6.25 6v2.94L5.03 7.72a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l2.5-2.5a.75.75 0 1 0-1.06-1.06L7.75 8.94V6H10a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.25Z"
+												/>
+												<path
+													d="M4.268 14A2 2 0 0 0 6 15h6a2 2 0 0 0 2-2v-3a2 2 0 0 0-1-1.732V11a3 3 0 0 1-3 3H4.268Z"
+												/>
+											</svg>
+										</button>
+									</Tooltip>
+								</div>
+							</div>
+						</div>
+
+						{#if updateModelId}
+							Updating "{updateModelId}" {updateProgress ? `(${updateProgress}%)` : ''}
+						{/if}
+					{/if}
+
+					<div class="space-y-2">
+						<div>
+							<div class=" mb-2 text-sm font-medium">{$i18n.t('Pull a model from Ollama.com')}</div>
+							<div class="flex w-full">
+								<div class="flex-1 mr-2">
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+										placeholder={$i18n.t('Enter model tag (e.g. {{modelTag}})', {
+											modelTag: 'mistral:7b'
+										})}
+										bind:value={modelTag}
+									/>
+								</div>
+								<button
+									class="px-2.5 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg transition"
+									on:click={() => {
+										pullModelHandler();
+									}}
+									disabled={modelTransferring}
+								>
+									{#if modelTransferring}
+										<div class="self-center">
+											<svg
+												class=" w-4 h-4"
+												viewBox="0 0 24 24"
+												fill="currentColor"
+												xmlns="http://www.w3.org/2000/svg"
+											>
+												<style>
+													.spinner_ajPY {
+														transform-origin: center;
+														animation: spinner_AtaB 0.75s infinite linear;
+													}
+
+													@keyframes spinner_AtaB {
+														100% {
+															transform: rotate(360deg);
+														}
+													}
+												</style>
+												<path
+													d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
+													opacity=".25"
+												/>
+												<path
+													d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
+													class="spinner_ajPY"
+												/>
+											</svg>
+										</div>
+									{:else}
+										<svg
+											xmlns="http://www.w3.org/2000/svg"
+											viewBox="0 0 16 16"
+											fill="currentColor"
+											class="w-4 h-4"
+										>
+											<path
+												d="M8.75 2.75a.75.75 0 0 0-1.5 0v5.69L5.03 6.22a.75.75 0 0 0-1.06 1.06l3.5 3.5a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0-1.06-1.06L8.75 8.44V2.75Z"
+											/>
+											<path
+												d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+											/>
+										</svg>
+									{/if}
+								</button>
+							</div>
+
+							<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
+								{$i18n.t('To access the available model names for downloading,')}
+								<a
+									class=" text-gray-500 dark:text-gray-300 font-medium underline"
+									href="https://ollama.com/library"
+									target="_blank">{$i18n.t('click here.')}</a
+								>
+							</div>
+
+							{#if Object.keys($MODEL_DOWNLOAD_POOL).length > 0}
+								{#each Object.keys($MODEL_DOWNLOAD_POOL) as model}
+									{#if 'pullProgress' in $MODEL_DOWNLOAD_POOL[model]}
+										<div class="flex flex-col">
+											<div class="font-medium mb-1">{model}</div>
+											<div class="">
+												<div class="flex flex-row justify-between space-x-4 pr-2">
+													<div class=" flex-1">
+														<div
+															class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+															style="width: {Math.max(
+																15,
+																$MODEL_DOWNLOAD_POOL[model].pullProgress ?? 0
+															)}%"
+														>
+															{$MODEL_DOWNLOAD_POOL[model].pullProgress ?? 0}%
+														</div>
+													</div>
+
+													<Tooltip content={$i18n.t('Cancel')}>
+														<button
+															class="text-gray-800 dark:text-gray-100"
+															on:click={() => {
+																cancelModelPullHandler(model);
+															}}
+														>
+															<svg
+																class="w-4 h-4 text-gray-800 dark:text-white"
+																aria-hidden="true"
+																xmlns="http://www.w3.org/2000/svg"
+																width="24"
+																height="24"
+																fill="currentColor"
+																viewBox="0 0 24 24"
+															>
+																<path
+																	stroke="currentColor"
+																	stroke-linecap="round"
+																	stroke-linejoin="round"
+																	stroke-width="2"
+																	d="M6 18 17.94 6M18 18 6.06 6"
+																/>
+															</svg>
+														</button>
+													</Tooltip>
+												</div>
+												{#if 'digest' in $MODEL_DOWNLOAD_POOL[model]}
+													<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+														{$MODEL_DOWNLOAD_POOL[model].digest}
+													</div>
+												{/if}
+											</div>
+										</div>
+									{/if}
+								{/each}
+							{/if}
+						</div>
+
+						<div>
+							<div class=" mb-2 text-sm font-medium">{$i18n.t('Delete a model')}</div>
+							<div class="flex w-full">
+								<div class="flex-1 mr-2">
+									<select
+										class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+										bind:value={deleteModelTag}
+										placeholder={$i18n.t('Select a model')}
+									>
+										{#if !deleteModelTag}
+											<option value="" disabled selected>{$i18n.t('Select a model')}</option>
+										{/if}
+										{#each $models.filter((m) => !(m?.preset ?? false) && m.owned_by === 'ollama' && (selectedOllamaUrlIdx === null ? true : (m?.ollama?.urls ?? []).includes(selectedOllamaUrlIdx))) as model}
+											<option value={model.name} class="bg-gray-100 dark:bg-gray-700"
+												>{model.name +
+													' (' +
+													(model.ollama.size / 1024 ** 3).toFixed(1) +
+													' GB)'}</option
+											>
+										{/each}
+									</select>
+								</div>
+								<button
+									class="px-2.5 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg transition"
+									on:click={() => {
+										deleteModelHandler();
+									}}
+								>
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 16 16"
+										fill="currentColor"
+										class="w-4 h-4"
+									>
+										<path
+											fill-rule="evenodd"
+											d="M5 3.25V4H2.75a.75.75 0 0 0 0 1.5h.3l.815 8.15A1.5 1.5 0 0 0 5.357 15h5.285a1.5 1.5 0 0 0 1.493-1.35l.815-8.15h.3a.75.75 0 0 0 0-1.5H11v-.75A2.25 2.25 0 0 0 8.75 1h-1.5A2.25 2.25 0 0 0 5 3.25Zm2.25-.75a.75.75 0 0 0-.75.75V4h3v-.75a.75.75 0 0 0-.75-.75h-1.5ZM6.05 6a.75.75 0 0 1 .787.713l.275 5.5a.75.75 0 0 1-1.498.075l-.275-5.5A.75.75 0 0 1 6.05 6Zm3.9 0a.75.75 0 0 1 .712.787l-.275 5.5a.75.75 0 0 1-1.498-.075l.275-5.5a.75.75 0 0 1 .786-.711Z"
+											clip-rule="evenodd"
+										/>
+									</svg>
+								</button>
+							</div>
+						</div>
+
+						<div>
+							<div class=" mb-2 text-sm font-medium">{$i18n.t('Create a model')}</div>
+							<div class="flex w-full">
+								<div class="flex-1 mr-2 flex flex-col gap-2">
+									<input
+										class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+										placeholder={$i18n.t('Enter model tag (e.g. {{modelTag}})', {
+											modelTag: 'my-modelfile'
+										})}
+										bind:value={createModelTag}
+										disabled={createModelLoading}
+									/>
+
+									<textarea
+										bind:value={createModelContent}
+										class="w-full rounded-lg py-2 px-4 text-sm bg-gray-100 dark:text-gray-100 dark:bg-gray-850 outline-none resize-none scrollbar-hidden"
+										rows="6"
+										placeholder={`TEMPLATE """{{ .System }}\nUSER: {{ .Prompt }}\nASSISTANT: """\nPARAMETER num_ctx 4096\nPARAMETER stop "</s>"\nPARAMETER stop "USER:"\nPARAMETER stop "ASSISTANT:"`}
+										disabled={createModelLoading}
+									/>
+								</div>
+
+								<div class="flex self-start">
+									<button
+										class="px-2.5 py-2.5 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg transition disabled:cursor-not-allowed"
+										on:click={() => {
+											createModelHandler();
+										}}
+										disabled={createModelLoading}
+									>
+										<svg
+											xmlns="http://www.w3.org/2000/svg"
+											viewBox="0 0 16 16"
+											fill="currentColor"
+											class="size-4"
+										>
+											<path
+												d="M7.25 10.25a.75.75 0 0 0 1.5 0V4.56l2.22 2.22a.75.75 0 1 0 1.06-1.06l-3.5-3.5a.75.75 0 0 0-1.06 0l-3.5 3.5a.75.75 0 0 0 1.06 1.06l2.22-2.22v5.69Z"
+											/>
+											<path
+												d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+											/>
+										</svg>
+									</button>
+								</div>
+							</div>
+
+							{#if createModelDigest !== ''}
+								<div class="flex flex-col mt-1">
+									<div class="font-medium mb-1">{createModelTag}</div>
+									<div class="">
+										<div class="flex flex-row justify-between space-x-4 pr-2">
+											<div class=" flex-1">
+												<div
+													class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+													style="width: {Math.max(15, createModelPullProgress ?? 0)}%"
+												>
+													{createModelPullProgress ?? 0}%
+												</div>
+											</div>
+										</div>
+										{#if createModelDigest}
+											<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+												{createModelDigest}
+											</div>
+										{/if}
+									</div>
+								</div>
+							{/if}
+						</div>
+
+						<div class="pt-1">
+							<div class="flex justify-between items-center text-xs">
+								<div class=" text-sm font-medium">{$i18n.t('Experimental')}</div>
+								<button
+									class=" text-xs font-medium text-gray-500"
+									type="button"
+									on:click={() => {
+										showExperimentalOllama = !showExperimentalOllama;
+									}}>{showExperimentalOllama ? $i18n.t('Hide') : $i18n.t('Show')}</button
+								>
+							</div>
+						</div>
+
+						{#if showExperimentalOllama}
+							<form
+								on:submit|preventDefault={() => {
+									uploadModelHandler();
+								}}
+							>
+								<div class=" mb-2 flex w-full justify-between">
+									<div class="  text-sm font-medium">{$i18n.t('Upload a GGUF model')}</div>
+
+									<button
+										class="p-1 px-3 text-xs flex rounded transition"
+										on:click={() => {
+											if (modelUploadMode === 'file') {
+												modelUploadMode = 'url';
+											} else {
+												modelUploadMode = 'file';
+											}
+										}}
+										type="button"
+									>
+										{#if modelUploadMode === 'file'}
+											<span class="ml-2 self-center">{$i18n.t('File Mode')}</span>
+										{:else}
+											<span class="ml-2 self-center">{$i18n.t('URL Mode')}</span>
+										{/if}
+									</button>
+								</div>
+
+								<div class="flex w-full mb-1.5">
+									<div class="flex flex-col w-full">
+										{#if modelUploadMode === 'file'}
+											<div
+												class="flex-1 {modelInputFile && modelInputFile.length > 0 ? 'mr-2' : ''}"
+											>
+												<input
+													id="model-upload-input"
+													bind:this={modelUploadInputElement}
+													type="file"
+													bind:files={modelInputFile}
+													on:change={() => {
+														console.log(modelInputFile);
+													}}
+													accept=".gguf,.safetensors"
+													required
+													hidden
+												/>
+
+												<button
+													type="button"
+													class="w-full rounded-lg text-left py-2 px-4 bg-white dark:text-gray-300 dark:bg-gray-850"
+													on:click={() => {
+														modelUploadInputElement.click();
+													}}
+												>
+													{#if modelInputFile && modelInputFile.length > 0}
+														{modelInputFile[0].name}
+													{:else}
+														{$i18n.t('Click here to select')}
+													{/if}
+												</button>
+											</div>
+										{:else}
+											<div class="flex-1 {modelFileUrl !== '' ? 'mr-2' : ''}">
+												<input
+													class="w-full rounded-lg text-left py-2 px-4 bg-white dark:text-gray-300 dark:bg-gray-850 outline-none {modelFileUrl !==
+													''
+														? 'mr-2'
+														: ''}"
+													type="url"
+													required
+													bind:value={modelFileUrl}
+													placeholder={$i18n.t('Type Hugging Face Resolve (Download) URL')}
+												/>
+											</div>
+										{/if}
+									</div>
+
+									{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
+										<button
+											class="px-2.5 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg disabled:cursor-not-allowed transition"
+											type="submit"
+											disabled={modelTransferring}
+										>
+											{#if modelTransferring}
+												<div class="self-center">
+													<svg
+														class=" w-4 h-4"
+														viewBox="0 0 24 24"
+														fill="currentColor"
+														xmlns="http://www.w3.org/2000/svg"
+													>
+														<style>
+															.spinner_ajPY {
+																transform-origin: center;
+																animation: spinner_AtaB 0.75s infinite linear;
+															}
+
+															@keyframes spinner_AtaB {
+																100% {
+																	transform: rotate(360deg);
+																}
+															}
+														</style>
+														<path
+															d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
+															opacity=".25"
+														/>
+														<path
+															d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
+															class="spinner_ajPY"
+														/>
+													</svg>
+												</div>
+											{:else}
+												<svg
+													xmlns="http://www.w3.org/2000/svg"
+													viewBox="0 0 16 16"
+													fill="currentColor"
+													class="w-4 h-4"
+												>
+													<path
+														d="M7.25 10.25a.75.75 0 0 0 1.5 0V4.56l2.22 2.22a.75.75 0 1 0 1.06-1.06l-3.5-3.5a.75.75 0 0 0-1.06 0l-3.5 3.5a.75.75 0 0 0 1.06 1.06l2.22-2.22v5.69Z"
+													/>
+													<path
+														d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+													/>
+												</svg>
+											{/if}
+										</button>
+									{/if}
+								</div>
+
+								{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
+									<div>
+										<div>
+											<div class=" my-2.5 text-sm font-medium">{$i18n.t('Modelfile Content')}</div>
+											<textarea
+												bind:value={modelFileContent}
+												class="w-full rounded-lg py-2 px-4 text-sm bg-gray-100 dark:text-gray-100 dark:bg-gray-850 outline-none resize-none"
+												rows="6"
+											/>
+										</div>
+									</div>
+								{/if}
+								<div class=" mt-1 text-xs text-gray-400 dark:text-gray-500">
+									{$i18n.t('To access the GGUF models available for downloading,')}
+									<a
+										class=" text-gray-500 dark:text-gray-300 font-medium underline"
+										href="https://huggingface.co/models?search=gguf"
+										target="_blank">{$i18n.t('click here.')}</a
+									>
+								</div>
+
+								{#if uploadMessage}
+									<div class="mt-2">
+										<div class=" mb-2 text-xs">{$i18n.t('Upload Progress')}</div>
+
+										<div class="w-full rounded-full dark:bg-gray-800">
+											<div
+												class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+												style="width: 100%"
+											>
+												{uploadMessage}
+											</div>
+										</div>
+										<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+											{modelFileDigest}
+										</div>
+									</div>
+								{:else if uploadProgress !== null}
+									<div class="mt-2">
+										<div class=" mb-2 text-xs">{$i18n.t('Upload Progress')}</div>
+
+										<div class="w-full rounded-full dark:bg-gray-800">
+											<div
+												class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
+												style="width: {Math.max(15, uploadProgress ?? 0)}%"
+											>
+												{uploadProgress ?? 0}%
+											</div>
+										</div>
+										<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
+											{modelFileDigest}
+										</div>
+									</div>
+								{/if}
+							</form>
+						{/if}
+					</div>
+				</div>
+			{:else if ollamaVersion === false}
+				<div>Ollama Not Detected</div>
+			{:else}
+				<div class="flex h-full justify-center">
+					<div class="my-auto">
+						<Spinner className="size-6" />
+					</div>
+				</div>
+			{/if}
+		{:else if ollamaEnabled === false}
+			<div>{$i18n.t('Ollama API is disabled')}</div>
+		{:else}
+			<div class="flex h-full justify-center">
+				<div class="my-auto">
+					<Spinner className="size-6" />
+				</div>
+			</div>
+		{/if}
+	</div>
+</div>

+ 128 - 2
src/lib/components/admin/Settings/Pipelines.svelte

@@ -14,7 +14,8 @@
 		getModels,
 		getPipelinesList,
 		downloadPipeline,
-		deletePipeline
+		deletePipeline,
+		uploadPipeline
 	} from '$lib/apis';
 
 	import Spinner from '$lib/components/common/Spinner.svelte';
@@ -24,6 +25,9 @@
 	export let saveHandler: Function;
 
 	let downloading = false;
+	let uploading = false;
+
+	let pipelineFiles;
 
 	let PIPELINES_LIST = null;
 	let selectedPipelinesUrlIdx = '';
@@ -126,6 +130,41 @@
 		downloading = false;
 	};
 
+	const uploadPipelineHandler = async () => {
+		uploading = true;
+
+		if (pipelineFiles && pipelineFiles.length !== 0) {
+			const file = pipelineFiles[0];
+
+			console.log(file);
+
+			const res = await uploadPipeline(localStorage.token, file, selectedPipelinesUrlIdx).catch(
+				(error) => {
+					console.log(error);
+					toast.error('Something went wrong :/');
+					return null;
+				}
+			);
+
+			if (res) {
+				toast.success('Pipeline downloaded successfully');
+				setPipelines();
+				models.set(await getModels(localStorage.token));
+			}
+		} else {
+			toast.error('No file selected');
+		}
+
+		pipelineFiles = null;
+		const pipelineUploadInputElement = document.getElementById('pipeline-upload-input');
+
+		if (pipelineUploadInputElement) {
+			pipelineUploadInputElement.value = null;
+		}
+
+		uploading = false;
+	};
+
 	const deletePipelineHandler = async () => {
 		const res = await deletePipeline(
 			localStorage.token,
@@ -161,7 +200,7 @@
 		updateHandler();
 	}}
 >
-	<div class="  pr-1.5 overflow-y-scroll max-h-80 h-full">
+	<div class="overflow-y-scroll scrollbar-hidden h-full">
 		{#if PIPELINES_LIST !== null}
 			<div class="flex w-full justify-between mb-2">
 				<div class=" self-center text-sm font-semibold">
@@ -196,6 +235,91 @@
 					</div>
 				</div>
 
+				<div class=" my-2">
+					<div class=" mb-2 text-sm font-medium">
+						{$i18n.t('Upload Pipeline')}
+					</div>
+					<div class="flex w-full">
+						<div class="flex-1 mr-2">
+							<input
+								id="pipelines-upload-input"
+								bind:files={pipelineFiles}
+								type="file"
+								accept=".py"
+								hidden
+							/>
+
+							<button
+								class="w-full text-sm font-medium py-2 bg-transparent hover:bg-gray-100 border border-dashed dark:border-gray-800 dark:hover:bg-gray-850 text-center rounded-xl"
+								type="button"
+								on:click={() => {
+									document.getElementById('pipelines-upload-input')?.click();
+								}}
+							>
+								{#if pipelineFiles}
+									{pipelineFiles.length > 0 ? `${pipelineFiles.length}` : ''} pipeline(s) selected.
+								{:else}
+									{$i18n.t('Click here to select a py file.')}
+								{/if}
+							</button>
+						</div>
+						<button
+							class="px-2.5 bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-100 rounded-lg transition"
+							on:click={() => {
+								uploadPipelineHandler();
+							}}
+							disabled={uploading}
+							type="button"
+						>
+							{#if uploading}
+								<div class="self-center">
+									<svg
+										class=" w-4 h-4"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										xmlns="http://www.w3.org/2000/svg"
+									>
+										<style>
+											.spinner_ajPY {
+												transform-origin: center;
+												animation: spinner_AtaB 0.75s infinite linear;
+											}
+
+											@keyframes spinner_AtaB {
+												100% {
+													transform: rotate(360deg);
+												}
+											}
+										</style>
+										<path
+											d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
+											opacity=".25"
+										/>
+										<path
+											d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
+											class="spinner_ajPY"
+										/>
+									</svg>
+								</div>
+							{:else}
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 16 16"
+									fill="currentColor"
+									class="size-4"
+								>
+									<path
+										d="M7.25 10.25a.75.75 0 0 0 1.5 0V4.56l2.22 2.22a.75.75 0 1 0 1.06-1.06l-3.5-3.5a.75.75 0 0 0-1.06 0l-3.5 3.5a.75.75 0 0 0 1.06 1.06l2.22-2.22v5.69Z"
+									/>
+									<path
+										d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
+									/>
+								</svg>
+							{/if}
+						</button>
+					</div>
+				</div>
+
 				<div class=" my-2">
 					<div class=" mb-2 text-sm font-medium">
 						{$i18n.t('Install from Github URL')}
@@ -384,6 +508,8 @@
 						</div>
 					</div>
 				{/if}
+			{:else}
+				<div>Pipelines Not Detected</div>
 			{/if}
 		{:else}
 			<div class="flex justify-center h-full">

+ 2 - 2
src/lib/components/admin/Settings/Users.svelte

@@ -48,7 +48,7 @@
 		await config.set(await getBackendConfig());
 	}}
 >
-	<div class=" space-y-3 pr-1.5 overflow-y-scroll max-h-80">
+	<div class=" space-y-3 overflow-y-scroll max-h-full">
 		<div>
 			<div class=" mb-2 text-sm font-medium">{$i18n.t('User Permissions')}</div>
 
@@ -94,7 +94,7 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700 my-2" />
+		<hr class=" dark:border-gray-850 my-2" />
 
 		<div class="mt-2 space-y-3">
 			<div>

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

@@ -0,0 +1,285 @@
+<script lang="ts">
+	import { getRAGConfig, updateRAGConfig } from '$lib/apis/rag';
+	import Switch from '$lib/components/common/Switch.svelte';
+
+	import { documents, models } from '$lib/stores';
+	import { onMount, getContext } from 'svelte';
+	import { toast } from 'svelte-sonner';
+
+	const i18n = getContext('i18n');
+
+	export let saveHandler: Function;
+
+	let webConfig = null;
+	let webSearchEngines = ['searxng', 'google_pse', 'brave', 'serpstack', 'serper'];
+
+	let youtubeLanguage = 'en';
+	let youtubeTranslation = null;
+
+	const submitHandler = async () => {
+		const res = await updateRAGConfig(localStorage.token, {
+			web: webConfig,
+			youtube: {
+				language: youtubeLanguage.split(',').map((lang) => lang.trim()),
+				translation: youtubeTranslation
+			}
+		});
+	};
+
+	onMount(async () => {
+		const res = await getRAGConfig(localStorage.token);
+
+		if (res) {
+			webConfig = res.web;
+
+			youtubeLanguage = res.youtube.language.join(',');
+			youtubeTranslation = res.youtube.translation;
+		}
+	});
+</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 webConfig}
+			<div>
+				<div class=" mb-1 text-sm font-medium">
+					{$i18n.t('Web Search')}
+				</div>
+
+				<div>
+					<div class=" py-0.5 flex w-full justify-between">
+						<div class=" self-center text-xs font-medium">
+							{$i18n.t('Enable Web Search')}
+						</div>
+
+						<Switch bind:state={webConfig.search.enabled} />
+					</div>
+				</div>
+
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs font-medium">{$i18n.t('Web Search 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={webConfig.search.engine}
+							placeholder={$i18n.t('Select a engine')}
+							required
+						>
+							<option disabled selected value="">{$i18n.t('Select a engine')}</option>
+							{#each webSearchEngines as engine}
+								<option value={engine}>{engine}</option>
+							{/each}
+						</select>
+					</div>
+				</div>
+
+				{#if webConfig.search.engine !== ''}
+					<div class="mt-1.5">
+						{#if webConfig.search.engine === 'searxng'}
+							<div>
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Searxng Query URL')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Searxng Query URL')}
+											bind:value={webConfig.search.searxng_query_url}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{:else if webConfig.search.engine === 'google_pse'}
+							<div>
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Google PSE API Key')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Google PSE API Key')}
+											bind:value={webConfig.search.google_pse_api_key}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+							<div class="mt-1.5">
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Google PSE Engine Id')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Google PSE Engine Id')}
+											bind:value={webConfig.search.google_pse_engine_id}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{:else if webConfig.search.engine === 'brave'}
+							<div>
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Brave Search API Key')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Brave Search API Key')}
+											bind:value={webConfig.search.brave_search_api_key}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{:else if webConfig.search.engine === 'serpstack'}
+							<div>
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Serpstack API Key')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Serpstack API Key')}
+											bind:value={webConfig.search.serpstack_api_key}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{:else if webConfig.search.engine === 'serper'}
+							<div>
+								<div class=" self-center text-xs font-medium mb-1">
+									{$i18n.t('Serper API Key')}
+								</div>
+
+								<div class="flex w-full">
+									<div class="flex-1">
+										<input
+											class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+											type="text"
+											placeholder={$i18n.t('Enter Serper API Key')}
+											bind:value={webConfig.search.serper_api_key}
+											autocomplete="off"
+										/>
+									</div>
+								</div>
+							</div>
+						{/if}
+					</div>
+				{/if}
+
+				{#if webConfig.search.enabled}
+					<div class="mt-2 flex gap-2 mb-1">
+						<div class="w-full">
+							<div class=" self-center text-xs font-medium mb-1">
+								{$i18n.t('Search Result Count')}
+							</div>
+
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('Search Result Count')}
+								bind:value={webConfig.search.result_count}
+								required
+							/>
+						</div>
+
+						<div class="w-full">
+							<div class=" self-center text-xs font-medium mb-1">
+								{$i18n.t('Concurrent Requests')}
+							</div>
+
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								placeholder={$i18n.t('Concurrent Requests')}
+								bind:value={webConfig.search.concurrent_requests}
+								required
+							/>
+						</div>
+					</div>
+				{/if}
+			</div>
+
+			<hr class=" dark:border-gray-850 my-2" />
+
+			<div>
+				<div class=" mb-1 text-sm font-medium">
+					{$i18n.t('Web Loader Settings')}
+				</div>
+
+				<div>
+					<div class=" py-0.5 flex w-full justify-between">
+						<div class=" self-center text-xs font-medium">
+							{$i18n.t('Bypass SSL verification for Websites')}
+						</div>
+
+						<button
+							class="p-1 px-3 text-xs flex rounded transition"
+							on:click={() => {
+								webConfig.ssl_verification = !webConfig.ssl_verification;
+								submitHandler();
+							}}
+							type="button"
+						>
+							{#if webConfig.ssl_verification === true}
+								<span class="ml-2 self-center">{$i18n.t('On')}</span>
+							{:else}
+								<span class="ml-2 self-center">{$i18n.t('Off')}</span>
+							{/if}
+						</button>
+					</div>
+				</div>
+
+				<div class=" mt-2 mb-1 text-sm font-medium">
+					{$i18n.t('Youtube Loader Settings')}
+				</div>
+
+				<div>
+					<div class=" py-0.5 flex w-full justify-between">
+						<div class=" w-20 text-xs font-medium self-center">{$i18n.t('Language')}</div>
+						<div class=" flex-1 self-center">
+							<input
+								class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
+								type="text"
+								placeholder={$i18n.t('Enter language codes')}
+								bind:value={youtubeLanguage}
+								autocomplete="off"
+							/>
+						</div>
+					</div>
+				</div>
+			</div>
+		{/if}
+	</div>
+	<div class="flex justify-end pt-3 text-sm font-medium">
+		<button
+			class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
+			type="submit"
+		>
+			{$i18n.t('Save')}
+		</button>
+	</div>
+</form>

+ 0 - 176
src/lib/components/admin/SettingsModal.svelte

@@ -39,181 +39,5 @@
 				</svg>
 			</button>
 		</div>
-
-		<div class="flex flex-col md:flex-row w-full p-4 md:space-x-4">
-			<div
-				class="tabs flex flex-row overflow-x-auto space-x-1 md:space-x-0 md:space-y-1 md:flex-col flex-1 md:flex-none md:w-40 dark:text-gray-200 text-xs text-left mb-3 md:mb-0"
-			>
-				<button
-					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-					'general'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-					on:click={() => {
-						selectedTab = 'general';
-					}}
-				>
-					<div class=" self-center mr-2">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 16 16"
-							fill="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								fill-rule="evenodd"
-								d="M6.955 1.45A.5.5 0 0 1 7.452 1h1.096a.5.5 0 0 1 .497.45l.17 1.699c.484.12.94.312 1.356.562l1.321-1.081a.5.5 0 0 1 .67.033l.774.775a.5.5 0 0 1 .034.67l-1.08 1.32c.25.417.44.873.561 1.357l1.699.17a.5.5 0 0 1 .45.497v1.096a.5.5 0 0 1-.45.497l-1.699.17c-.12.484-.312.94-.562 1.356l1.082 1.322a.5.5 0 0 1-.034.67l-.774.774a.5.5 0 0 1-.67.033l-1.322-1.08c-.416.25-.872.44-1.356.561l-.17 1.699a.5.5 0 0 1-.497.45H7.452a.5.5 0 0 1-.497-.45l-.17-1.699a4.973 4.973 0 0 1-1.356-.562L4.108 13.37a.5.5 0 0 1-.67-.033l-.774-.775a.5.5 0 0 1-.034-.67l1.08-1.32a4.971 4.971 0 0 1-.561-1.357l-1.699-.17A.5.5 0 0 1 1 8.548V7.452a.5.5 0 0 1 .45-.497l1.699-.17c.12-.484.312-.94.562-1.356L2.629 4.107a.5.5 0 0 1 .034-.67l.774-.774a.5.5 0 0 1 .67-.033L5.43 3.71a4.97 4.97 0 0 1 1.356-.561l.17-1.699ZM6 8c0 .538.212 1.026.558 1.385l.057.057a2 2 0 0 0 2.828-2.828l-.058-.056A2 2 0 0 0 6 8Z"
-								clip-rule="evenodd"
-							/>
-						</svg>
-					</div>
-					<div class=" self-center">{$i18n.t('General')}</div>
-				</button>
-
-				<button
-					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-					'users'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-					on:click={() => {
-						selectedTab = 'users';
-					}}
-				>
-					<div class=" self-center mr-2">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 16 16"
-							fill="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								d="M8 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5ZM3.156 11.763c.16-.629.44-1.21.813-1.72a2.5 2.5 0 0 0-2.725 1.377c-.136.287.102.58.418.58h1.449c.01-.077.025-.156.045-.237ZM12.847 11.763c.02.08.036.16.046.237h1.446c.316 0 .554-.293.417-.579a2.5 2.5 0 0 0-2.722-1.378c.374.51.653 1.09.813 1.72ZM14 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM5 13c-.552 0-1.013-.455-.876-.99a4.002 4.002 0 0 1 7.753 0c.136.535-.324.99-.877.99H5Z"
-							/>
-						</svg>
-					</div>
-					<div class=" self-center">{$i18n.t('Users')}</div>
-				</button>
-
-				<button
-					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-					'db'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-					on:click={() => {
-						selectedTab = 'db';
-					}}
-				>
-					<div class=" self-center mr-2">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 16 16"
-							fill="currentColor"
-							class="w-4 h-4"
-						>
-							<path d="M8 7c3.314 0 6-1.343 6-3s-2.686-3-6-3-6 1.343-6 3 2.686 3 6 3Z" />
-							<path
-								d="M8 8.5c1.84 0 3.579-.37 4.914-1.037A6.33 6.33 0 0 0 14 6.78V8c0 1.657-2.686 3-6 3S2 9.657 2 8V6.78c.346.273.72.5 1.087.683C4.42 8.131 6.16 8.5 8 8.5Z"
-							/>
-							<path
-								d="M8 12.5c1.84 0 3.579-.37 4.914-1.037.366-.183.74-.41 1.086-.684V12c0 1.657-2.686 3-6 3s-6-1.343-6-3v-1.22c.346.273.72.5 1.087.683C4.42 12.131 6.16 12.5 8 12.5Z"
-							/>
-						</svg>
-					</div>
-					<div class=" self-center">{$i18n.t('Database')}</div>
-				</button>
-
-				<button
-					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-					'banners'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-					on:click={() => {
-						selectedTab = 'banners';
-					}}
-				>
-					<div class=" self-center mr-2">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 24 24"
-							fill="currentColor"
-							class="size-4"
-						>
-							<path
-								d="M5.85 3.5a.75.75 0 0 0-1.117-1 9.719 9.719 0 0 0-2.348 4.876.75.75 0 0 0 1.479.248A8.219 8.219 0 0 1 5.85 3.5ZM19.267 2.5a.75.75 0 1 0-1.118 1 8.22 8.22 0 0 1 1.987 4.124.75.75 0 0 0 1.48-.248A9.72 9.72 0 0 0 19.266 2.5Z"
-							/>
-							<path
-								fill-rule="evenodd"
-								d="M12 2.25A6.75 6.75 0 0 0 5.25 9v.75a8.217 8.217 0 0 1-2.119 5.52.75.75 0 0 0 .298 1.206c1.544.57 3.16.99 4.831 1.243a3.75 3.75 0 1 0 7.48 0 24.583 24.583 0 0 0 4.83-1.244.75.75 0 0 0 .298-1.205 8.217 8.217 0 0 1-2.118-5.52V9A6.75 6.75 0 0 0 12 2.25ZM9.75 18c0-.034 0-.067.002-.1a25.05 25.05 0 0 0 4.496 0l.002.1a2.25 2.25 0 1 1-4.5 0Z"
-								clip-rule="evenodd"
-							/>
-						</svg>
-					</div>
-					<div class=" self-center">{$i18n.t('Banners')}</div>
-				</button>
-
-				<button
-					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-					'pipelines'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-					on:click={() => {
-						selectedTab = 'pipelines';
-					}}
-				>
-					<div class=" self-center mr-2">
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 24 24"
-							fill="currentColor"
-							class="size-4"
-						>
-							<path
-								d="M11.644 1.59a.75.75 0 0 1 .712 0l9.75 5.25a.75.75 0 0 1 0 1.32l-9.75 5.25a.75.75 0 0 1-.712 0l-9.75-5.25a.75.75 0 0 1 0-1.32l9.75-5.25Z"
-							/>
-							<path
-								d="m3.265 10.602 7.668 4.129a2.25 2.25 0 0 0 2.134 0l7.668-4.13 1.37.739a.75.75 0 0 1 0 1.32l-9.75 5.25a.75.75 0 0 1-.71 0l-9.75-5.25a.75.75 0 0 1 0-1.32l1.37-.738Z"
-							/>
-							<path
-								d="m10.933 19.231-7.668-4.13-1.37.739a.75.75 0 0 0 0 1.32l9.75 5.25c.221.12.489.12.71 0l9.75-5.25a.75.75 0 0 0 0-1.32l-1.37-.738-7.668 4.13a2.25 2.25 0 0 1-2.134-.001Z"
-							/>
-						</svg>
-					</div>
-					<div class=" self-center">{$i18n.t('Pipelines')}</div>
-				</button>
-			</div>
-			<div class="flex-1 md:min-h-[380px]">
-				{#if selectedTab === 'general'}
-					<General
-						saveHandler={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
-				{:else if selectedTab === 'users'}
-					<Users
-						saveHandler={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
-				{:else if selectedTab === 'db'}
-					<Database
-						saveHandler={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
-				{:else if selectedTab === 'banners'}
-					<Banners
-						saveHandler={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
-				{:else if selectedTab === 'pipelines'}
-					<Pipelines
-						saveHandler={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
-				{/if}
-			</div>
-		</div>
 	</div>
 </Modal>

+ 114 - 124
src/lib/components/chat/Chat.svelte

@@ -7,6 +7,10 @@
 	import { goto } from '$app/navigation';
 	import { page } from '$app/stores';
 
+	import type { Writable } from 'svelte/store';
+	import type { i18n as i18nType } from 'i18next';
+	import { OLLAMA_API_BASE_URL, OPENAI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
+
 	import {
 		chatId,
 		chats,
@@ -19,7 +23,8 @@
 		WEBUI_NAME,
 		banners,
 		user,
-		socket
+		socket,
+		showCallOverlay
 	} from '$lib/stores';
 	import {
 		convertMessagesToHistory,
@@ -39,24 +44,19 @@
 		getTagsById,
 		updateChatById
 	} from '$lib/apis/chats';
-	import {
-		generateOpenAIChatCompletion,
-		generateSearchQuery,
-		generateTitle
-	} from '$lib/apis/openai';
+	import { generateOpenAIChatCompletion } from '$lib/apis/openai';
+	import { runWebSearch } from '$lib/apis/rag';
+	import { createOpenAITextStream } from '$lib/apis/streaming';
+	import { queryMemory } from '$lib/apis/memories';
+	import { getUserSettings } from '$lib/apis/users';
+	import { chatCompleted, generateTitle, generateSearchQuery } from '$lib/apis';
 
+	import Banner from '../common/Banner.svelte';
 	import MessageInput from '$lib/components/chat/MessageInput.svelte';
 	import Messages from '$lib/components/chat/Messages.svelte';
 	import Navbar from '$lib/components/layout/Navbar.svelte';
-	import { OLLAMA_API_BASE_URL, OPENAI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
-	import { createOpenAITextStream } from '$lib/apis/streaming';
-	import { queryMemory } from '$lib/apis/memories';
-	import type { Writable } from 'svelte/store';
-	import type { i18n as i18nType } from 'i18next';
-	import { runWebSearch } from '$lib/apis/rag';
-	import Banner from '../common/Banner.svelte';
-	import { getUserSettings } from '$lib/apis/users';
-	import { chatCompleted } from '$lib/apis';
+	import CallOverlay from './MessageInput/CallOverlay.svelte';
+	import { error } from '@sveltejs/kit';
 
 	const i18n: Writable<i18nType> = getContext('i18n');
 
@@ -292,10 +292,11 @@
 	};
 
 	//////////////////////////
-	// Ollama functions
+	// Chat functions
 	//////////////////////////
 
 	const submitPrompt = async (userPrompt, _user = null) => {
+		let _responses = [];
 		console.log('submitPrompt', $chatId);
 
 		selectedModels = selectedModels.map((modelId) =>
@@ -318,8 +319,15 @@
 				)
 			);
 		} else {
-			// Reset chat message textarea height
-			document.getElementById('chat-textarea').style.height = '';
+			// Reset chat input textarea
+			const chatTextAreaElement = document.getElementById('chat-textarea');
+
+			if (chatTextAreaElement) {
+				chatTextAreaElement.value = '';
+				chatTextAreaElement.style.height = '';
+			}
+
+			prompt = '';
 
 			// Create user message
 			let userMessageId = uuidv4();
@@ -371,17 +379,17 @@
 				await tick();
 			}
 
-			// Reset chat input textarea
-			prompt = '';
-			document.getElementById('chat-textarea').style.height = '';
 			files = [];
 
 			// Send prompt
-			await sendPrompt(userPrompt, userMessageId);
+			_responses = await sendPrompt(userPrompt, userMessageId);
 		}
+
+		return _responses;
 	};
 
 	const sendPrompt = async (prompt, parentId, modelId = null) => {
+		let _responses = [];
 		const _chatId = JSON.parse(JSON.stringify($chatId));
 
 		await Promise.all(
@@ -468,11 +476,14 @@
 						await getWebSearchResults(model.id, parentId, responseMessageId);
 					}
 
+					let _response = null;
+
 					if (model?.owned_by === 'openai') {
-						await sendPromptOpenAI(model, prompt, responseMessageId, _chatId);
+						_response = await sendPromptOpenAI(model, prompt, responseMessageId, _chatId);
 					} else if (model) {
-						await sendPromptOllama(model, prompt, responseMessageId, _chatId);
+						_response = await sendPromptOllama(model, prompt, responseMessageId, _chatId);
 					}
+					_responses.push(_response);
 
 					console.log('chatEventEmitter', chatEventEmitter);
 
@@ -484,6 +495,8 @@
 		);
 
 		await chats.set(await getChatList(localStorage.token));
+
+		return _responses;
 	};
 
 	const getWebSearchResults = async (model: string, parentId: string, responseId: string) => {
@@ -497,20 +510,22 @@
 		messages = messages;
 
 		const prompt = history.messages[parentId].content;
-		let searchQuery = prompt;
-		if (prompt.length > 100) {
-			searchQuery = await generateChatSearchQuery(model, prompt);
-			if (!searchQuery) {
-				toast.warning($i18n.t('No search query generated'));
-				responseMessage.status = {
-					...responseMessage.status,
-					done: true,
-					error: true,
-					description: 'No search query generated'
-				};
-				messages = messages;
-				return;
+		let searchQuery = await generateSearchQuery(localStorage.token, model, messages, prompt).catch(
+			(error) => {
+				console.log(error);
+				return prompt;
 			}
+		);
+
+		if (!searchQuery) {
+			toast.warning($i18n.t('No search query generated'));
+			responseMessage.status = {
+				...responseMessage.status,
+				done: true,
+				error: true,
+				description: 'No search query generated'
+			};
+			messages = messages;
 		}
 
 		responseMessage.status = {
@@ -558,7 +573,7 @@
 	};
 
 	const sendPromptOllama = async (model, userPrompt, responseMessageId, _chatId) => {
-		model = model.id;
+		let _response = null;
 
 		const responseMessage = history.messages[responseMessageId];
 
@@ -617,17 +632,29 @@
 			}
 		});
 
-		const docs = messages
-			.filter((message) => message?.files ?? null)
-			.map((message) =>
-				message.files.filter((item) =>
-					['doc', 'collection', 'web_search_results'].includes(item.type)
+		let docs = [];
+
+		if (model.info.meta.knowledge) {
+			docs = model.info.meta.knowledge;
+		}
+
+		docs = [
+			...docs,
+			...messages
+				.filter((message) => message?.files ?? null)
+				.map((message) =>
+					message.files.filter((item) =>
+						['doc', 'collection', 'web_search_results'].includes(item.type)
+					)
 				)
-			)
-			.flat(1);
+				.flat(1)
+		].filter(
+			(item, index, array) =>
+				array.findIndex((i) => JSON.stringify(i) === JSON.stringify(item)) === index
+		);
 
 		const [res, controller] = await generateChatCompletion(localStorage.token, {
-			model: model,
+			model: model.id,
 			messages: messagesBody,
 			options: {
 				...($settings.params ?? {}),
@@ -665,9 +692,10 @@
 						controller.abort('User: Stop Response');
 					} else {
 						const messages = createMessagesList(responseMessageId);
-						await chatCompletedHandler(model, messages);
+						await chatCompletedHandler(model.id, messages);
 					}
 
+					_response = responseMessage.content;
 					break;
 				}
 
@@ -725,7 +753,7 @@
 													selectedModelfile.title.charAt(0).toUpperCase() +
 													selectedModelfile.title.slice(1)
 											  }`
-											: `${model}`,
+											: `${model.id}`,
 										{
 											body: responseMessage.content,
 											icon: selectedModelfile?.imageUrl ?? `${WEBUI_BASE_URL}/static/favicon.png`
@@ -737,7 +765,7 @@
 									copyToClipboard(responseMessage.content);
 								}
 
-								if ($settings.responseAutoPlayback) {
+								if ($settings.responseAutoPlayback && !$showCallOverlay) {
 									await tick();
 									document.getElementById(`speak-button-${responseMessage.id}`)?.click();
 								}
@@ -804,21 +832,34 @@
 			const _title = await generateChatTitle(userPrompt);
 			await setChatTitle(_chatId, _title);
 		}
+
+		return _response;
 	};
 
 	const sendPromptOpenAI = async (model, userPrompt, responseMessageId, _chatId) => {
+		let _response = null;
 		const responseMessage = history.messages[responseMessageId];
 
-		const docs = messages
-			.filter((message) => message?.files ?? null)
-			.map((message) =>
-				message.files.filter((item) =>
-					['doc', 'collection', 'web_search_results'].includes(item.type)
-				)
-			)
-			.flat(1);
+		let docs = [];
 
-		console.log(docs);
+		if (model.info.meta.knowledge) {
+			docs = model.info.meta.knowledge;
+		}
+
+		docs = [
+			...docs,
+			...messages
+				.filter((message) => message?.files ?? null)
+				.map((message) =>
+					message.files.filter((item) =>
+						['doc', 'collection', 'web_search_results'].includes(item.type)
+					)
+				)
+				.flat(1)
+		].filter(
+			(item, index, array) =>
+				array.findIndex((i) => JSON.stringify(i) === JSON.stringify(item)) === index
+		);
 
 		scrollToBottom();
 
@@ -923,6 +964,8 @@
 							await chatCompletedHandler(model.id, messages);
 						}
 
+						_response = responseMessage.content;
+
 						break;
 					}
 
@@ -948,7 +991,7 @@
 				}
 
 				if ($settings.notificationEnabled && !document.hasFocus()) {
-					const notification = new Notification(`OpenAI ${model}`, {
+					const notification = new Notification(`${model.id}`, {
 						body: responseMessage.content,
 						icon: `${WEBUI_BASE_URL}/static/favicon.png`
 					});
@@ -958,8 +1001,9 @@
 					copyToClipboard(responseMessage.content);
 				}
 
-				if ($settings.responseAutoPlayback) {
+				if ($settings.responseAutoPlayback && !$showCallOverlay) {
 					await tick();
+
 					document.getElementById(`speak-button-${responseMessage.id}`)?.click();
 				}
 
@@ -998,6 +1042,8 @@
 			const _title = await generateChatTitle(userPrompt);
 			await setChatTitle(_chatId, _title);
 		}
+
+		return _response;
 	};
 
 	const handleOpenAIError = async (error, res: Response | null, model, responseMessage) => {
@@ -1093,28 +1139,15 @@
 
 	const generateChatTitle = async (userPrompt) => {
 		if ($settings?.title?.auto ?? true) {
-			const model = $models.find((model) => model.id === selectedModels[0]);
-
-			const titleModelId =
-				model?.owned_by === 'openai' ?? false
-					? $settings?.title?.modelExternal ?? selectedModels[0]
-					: $settings?.title?.model ?? selectedModels[0];
-			const titleModel = $models.find((model) => model.id === titleModelId);
-
-			console.log(titleModel);
 			const title = await generateTitle(
 				localStorage.token,
-				$settings?.title?.prompt ??
-					$i18n.t(
-						"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':"
-					) + ' {{prompt}}',
-				titleModelId,
+				selectedModels[0],
 				userPrompt,
-				$chatId,
-				titleModel?.owned_by === 'openai' ?? false
-					? `${OPENAI_API_BASE_URL}`
-					: `${OLLAMA_API_BASE_URL}/v1`
-			);
+				$chatId
+			).catch((error) => {
+				console.error(error);
+				return 'New Chat';
+			});
 
 			return title;
 		} else {
@@ -1122,29 +1155,6 @@
 		}
 	};
 
-	const generateChatSearchQuery = async (modelId: string, prompt: string) => {
-		const model = $models.find((model) => model.id === modelId);
-		const taskModelId =
-			model?.owned_by === 'openai' ?? false
-				? $settings?.title?.modelExternal ?? modelId
-				: $settings?.title?.model ?? modelId;
-		const taskModel = $models.find((model) => model.id === taskModelId);
-
-		const previousMessages = messages
-			.filter((message) => message.role === 'user')
-			.map((message) => message.content);
-
-		return await generateSearchQuery(
-			localStorage.token,
-			taskModelId,
-			previousMessages,
-			prompt,
-			taskModel?.owned_by === 'openai' ?? false
-				? `${OPENAI_API_BASE_URL}`
-				: `${OLLAMA_API_BASE_URL}/v1`
-		);
-	};
-
 	const setChatTitle = async (_chatId, _title) => {
 		if (_chatId === $chatId) {
 			title = _title;
@@ -1161,28 +1171,6 @@
 			return [];
 		});
 	};
-
-	const addTag = async (tagName) => {
-		const res = await addTagById(localStorage.token, $chatId, tagName);
-		tags = await getTags();
-
-		chat = await updateChatById(localStorage.token, $chatId, {
-			tags: tags
-		});
-
-		_tags.set(await getAllChatTags(localStorage.token));
-	};
-
-	const deleteTag = async (tagName) => {
-		const res = await deleteTagById(localStorage.token, $chatId, tagName);
-		tags = await getTags();
-
-		chat = await updateChatById(localStorage.token, $chatId, {
-			tags: tags
-		});
-
-		_tags.set(await getAllChatTags(localStorage.token));
-	};
 </script>
 
 <svelte:head>
@@ -1193,6 +1181,8 @@
 	</title>
 </svelte:head>
 
+<CallOverlay {submitPrompt} bind:files />
+
 {#if !chatIdProp || (loaded && chatIdProp)}
 	<div
 		class="h-screen max-h-[100dvh] {$showSidebar

File diff suppressed because it is too large
+ 394 - 542
src/lib/components/chat/MessageInput.svelte


+ 693 - 0
src/lib/components/chat/MessageInput/CallOverlay.svelte

@@ -0,0 +1,693 @@
+<script lang="ts">
+	import { config, settings, showCallOverlay } from '$lib/stores';
+	import { onMount, tick, getContext } from 'svelte';
+
+	import { blobToFile, calculateSHA256, extractSentences, findWordIndices } from '$lib/utils';
+	import { synthesizeOpenAISpeech, transcribeAudio } from '$lib/apis/audio';
+	import { toast } from 'svelte-sonner';
+
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import VideoInputMenu from './CallOverlay/VideoInputMenu.svelte';
+	import { get } from 'svelte/store';
+
+	const i18n = getContext('i18n');
+
+	export let submitPrompt: Function;
+	export let files;
+
+	let loading = false;
+	let confirmed = false;
+
+	let camera = false;
+	let cameraStream = null;
+
+	let assistantSpeaking = false;
+	let assistantAudio = {};
+	let assistantAudioIdx = null;
+
+	let rmsLevel = 0;
+	let hasStartedSpeaking = false;
+
+	let currentUtterance = null;
+
+	let mediaRecorder;
+	let audioChunks = [];
+
+	const MIN_DECIBELS = -45;
+	const VISUALIZER_BUFFER_LENGTH = 300;
+
+	// Function to calculate the RMS level from time domain data
+	const calculateRMS = (data: Uint8Array) => {
+		let sumSquares = 0;
+		for (let i = 0; i < data.length; i++) {
+			const normalizedValue = (data[i] - 128) / 128; // Normalize the data
+			sumSquares += normalizedValue * normalizedValue;
+		}
+		return Math.sqrt(sumSquares / data.length);
+	};
+
+	const normalizeRMS = (rms) => {
+		rms = rms * 10;
+		const exp = 1.5; // Adjust exponent value; values greater than 1 expand larger numbers more and compress smaller numbers more
+		const scaledRMS = Math.pow(rms, exp);
+
+		// Scale between 0.01 (1%) and 1.0 (100%)
+		return Math.min(1.0, Math.max(0.01, scaledRMS));
+	};
+
+	const analyseAudio = (stream) => {
+		const audioContext = new AudioContext();
+		const audioStreamSource = audioContext.createMediaStreamSource(stream);
+
+		const analyser = audioContext.createAnalyser();
+		analyser.minDecibels = MIN_DECIBELS;
+		audioStreamSource.connect(analyser);
+
+		const bufferLength = analyser.frequencyBinCount;
+
+		const domainData = new Uint8Array(bufferLength);
+		const timeDomainData = new Uint8Array(analyser.fftSize);
+
+		let lastSoundTime = Date.now();
+		hasStartedSpeaking = false;
+
+		const detectSound = () => {
+			const processFrame = () => {
+				if (!mediaRecorder || !$showCallOverlay) {
+					if (mediaRecorder) {
+						mediaRecorder.stop();
+					}
+
+					return;
+				}
+				analyser.getByteTimeDomainData(timeDomainData);
+				analyser.getByteFrequencyData(domainData);
+
+				// Calculate RMS level from time domain data
+				rmsLevel = calculateRMS(timeDomainData);
+
+				// Check if initial speech/noise has started
+				const hasSound = domainData.some((value) => value > 0);
+				if (hasSound) {
+					stopAllAudio();
+					hasStartedSpeaking = true;
+					lastSoundTime = Date.now();
+				}
+
+				// Start silence detection only after initial speech/noise has been detected
+				if (hasStartedSpeaking) {
+					if (Date.now() - lastSoundTime > 2000) {
+						confirmed = true;
+
+						if (mediaRecorder) {
+							mediaRecorder.stop();
+						}
+					}
+				}
+
+				window.requestAnimationFrame(processFrame);
+			};
+
+			window.requestAnimationFrame(processFrame);
+		};
+
+		detectSound();
+	};
+
+	const stopAllAudio = () => {
+		if (currentUtterance) {
+			speechSynthesis.cancel();
+			currentUtterance = null;
+		}
+		if (assistantAudio[assistantAudioIdx]) {
+			assistantAudio[assistantAudioIdx].pause();
+			assistantAudio[assistantAudioIdx].currentTime = 0;
+		}
+
+		const audioElement = document.getElementById('audioElement');
+		audioElement.pause();
+		audioElement.currentTime = 0;
+
+		assistantSpeaking = false;
+	};
+
+	const playAudio = (idx) => {
+		if ($showCallOverlay) {
+			return new Promise((res) => {
+				assistantAudioIdx = idx;
+				const audioElement = document.getElementById('audioElement');
+				const audio = assistantAudio[idx];
+
+				audioElement.src = audio.src; // Assume `assistantAudio` has objects with a `src` property
+
+				audioElement.muted = true;
+
+				audioElement
+					.play()
+					.then(() => {
+						audioElement.muted = false;
+					})
+					.catch((error) => {
+						toast.error(error);
+					});
+
+				audioElement.onended = async (e) => {
+					await new Promise((r) => setTimeout(r, 300));
+
+					if (Object.keys(assistantAudio).length - 1 === idx) {
+						assistantSpeaking = false;
+					}
+
+					res(e);
+				};
+			});
+		} else {
+			return Promise.resolve();
+		}
+	};
+
+	const getOpenAISpeech = async (text) => {
+		const res = await synthesizeOpenAISpeech(
+			localStorage.token,
+			$settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice,
+			text
+		).catch((error) => {
+			toast.error(error);
+			assistantSpeaking = false;
+			return null;
+		});
+
+		if (res) {
+			const blob = await res.blob();
+			const blobUrl = URL.createObjectURL(blob);
+			const audio = new Audio(blobUrl);
+			assistantAudio = audio;
+		}
+	};
+
+	const transcribeHandler = async (audioBlob) => {
+		// Create a blob from the audio chunks
+
+		await tick();
+		const file = blobToFile(audioBlob, 'recording.wav');
+
+		const res = await transcribeAudio(localStorage.token, file).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res) {
+			console.log(res.text);
+
+			if (res.text !== '') {
+				const _responses = await submitPrompt(res.text);
+				console.log(_responses);
+
+				if (_responses.at(0)) {
+					const content = _responses[0];
+					if (content) {
+						assistantSpeakingHandler(content);
+					}
+				}
+			}
+		}
+	};
+
+	const assistantSpeakingHandler = async (content) => {
+		assistantSpeaking = true;
+
+		if (($config.audio.tts.engine ?? '') == '') {
+			let voices = [];
+			const getVoicesLoop = setInterval(async () => {
+				voices = await 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;
+
+					currentUtterance = new SpeechSynthesisUtterance(content);
+
+					if (voice) {
+						currentUtterance.voice = voice;
+					}
+
+					speechSynthesis.speak(currentUtterance);
+				}
+			}, 100);
+		} else if ($config.audio.tts.engine === 'openai') {
+			console.log('openai');
+
+			const sentences = extractSentences(content).reduce((mergedTexts, currentText) => {
+				const lastIndex = mergedTexts.length - 1;
+				if (lastIndex >= 0) {
+					const previousText = mergedTexts[lastIndex];
+					const wordCount = previousText.split(/\s+/).length;
+					if (wordCount < 2) {
+						mergedTexts[lastIndex] = previousText + ' ' + currentText;
+					} else {
+						mergedTexts.push(currentText);
+					}
+				} else {
+					mergedTexts.push(currentText);
+				}
+				return mergedTexts;
+			}, []);
+
+			console.log(sentences);
+
+			let lastPlayedAudioPromise = Promise.resolve(); // Initialize a promise that resolves immediately
+
+			for (const [idx, sentence] of sentences.entries()) {
+				const res = await synthesizeOpenAISpeech(
+					localStorage.token,
+					$settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice,
+					sentence
+				).catch((error) => {
+					toast.error(error);
+
+					assistantSpeaking = false;
+					return null;
+				});
+
+				if (res) {
+					const blob = await res.blob();
+					const blobUrl = URL.createObjectURL(blob);
+					const audio = new Audio(blobUrl);
+					assistantAudio[idx] = audio;
+					lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
+				}
+			}
+		}
+	};
+
+	const stopRecordingCallback = async () => {
+		if ($showCallOverlay) {
+			if (confirmed) {
+				loading = true;
+
+				if (cameraStream) {
+					const imageUrl = takeScreenshot();
+
+					files = [
+						{
+							type: 'image',
+							url: imageUrl
+						}
+					];
+				}
+
+				const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
+				await transcribeHandler(audioBlob);
+
+				confirmed = false;
+				loading = false;
+			}
+			audioChunks = [];
+			mediaRecorder = false;
+
+			startRecording();
+		} else {
+			audioChunks = [];
+			mediaRecorder = false;
+		}
+	};
+
+	const startRecording = async () => {
+		const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+		mediaRecorder = new MediaRecorder(stream);
+		mediaRecorder.onstart = () => {
+			console.log('Recording started');
+			audioChunks = [];
+			analyseAudio(stream);
+		};
+		mediaRecorder.ondataavailable = (event) => {
+			if (hasStartedSpeaking) {
+				audioChunks.push(event.data);
+			}
+		};
+		mediaRecorder.onstop = async () => {
+			console.log('Recording stopped');
+
+			await stopRecordingCallback();
+		};
+		mediaRecorder.start();
+	};
+
+	let videoInputDevices = [];
+	let selectedVideoInputDeviceId = null;
+
+	const getVideoInputDevices = async () => {
+		const devices = await navigator.mediaDevices.enumerateDevices();
+		videoInputDevices = devices.filter((device) => device.kind === 'videoinput');
+
+		if (!!navigator.mediaDevices.getDisplayMedia) {
+			videoInputDevices = [
+				...videoInputDevices,
+				{
+					deviceId: 'screen',
+					label: 'Screen Share'
+				}
+			];
+		}
+
+		console.log(videoInputDevices);
+		if (selectedVideoInputDeviceId === null && videoInputDevices.length > 0) {
+			selectedVideoInputDeviceId = videoInputDevices[0].deviceId;
+		}
+	};
+
+	const startCamera = async () => {
+		await getVideoInputDevices();
+
+		if (cameraStream === null) {
+			camera = true;
+			await tick();
+			try {
+				await startVideoStream();
+			} catch (err) {
+				console.error('Error accessing webcam: ', err);
+			}
+		}
+	};
+
+	const startVideoStream = async () => {
+		const video = document.getElementById('camera-feed');
+		if (video) {
+			if (selectedVideoInputDeviceId === 'screen') {
+				cameraStream = await navigator.mediaDevices.getDisplayMedia({
+					video: {
+						cursor: 'always'
+					},
+					audio: false
+				});
+			} else {
+				cameraStream = await navigator.mediaDevices.getUserMedia({
+					video: {
+						deviceId: selectedVideoInputDeviceId ? { exact: selectedVideoInputDeviceId } : undefined
+					}
+				});
+			}
+
+			if (cameraStream) {
+				await getVideoInputDevices();
+				video.srcObject = cameraStream;
+				await video.play();
+			}
+		}
+	};
+
+	const stopVideoStream = async () => {
+		if (cameraStream) {
+			const tracks = cameraStream.getTracks();
+			tracks.forEach((track) => track.stop());
+		}
+
+		cameraStream = null;
+	};
+
+	const takeScreenshot = () => {
+		const video = document.getElementById('camera-feed');
+		const canvas = document.getElementById('camera-canvas');
+
+		if (!canvas) {
+			return;
+		}
+
+		const context = canvas.getContext('2d');
+
+		// Make the canvas match the video dimensions
+		canvas.width = video.videoWidth;
+		canvas.height = video.videoHeight;
+
+		// Draw the image from the video onto the canvas
+		context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
+
+		// Convert the canvas to a data base64 URL and console log it
+		const dataURL = canvas.toDataURL('image/png');
+		console.log(dataURL);
+
+		return dataURL;
+	};
+
+	const stopCamera = async () => {
+		await stopVideoStream();
+		camera = false;
+	};
+
+	$: if ($showCallOverlay) {
+		startRecording();
+	} else {
+		stopCamera();
+	}
+</script>
+
+{#if $showCallOverlay}
+	<audio id="audioElement" src="" style="display: none;" />
+	<div class=" absolute w-full h-screen max-h-[100dvh] flex z-[999] overflow-hidden">
+		<div
+			class="absolute w-full h-screen max-h-[100dvh] bg-white text-gray-700 dark:bg-black dark:text-gray-300 flex justify-center"
+		>
+			<div class="max-w-lg w-full h-screen max-h-[100dvh] flex flex-col justify-between p-3 md:p-6">
+				{#if camera}
+					<div class="flex justify-center items-center w-full min-h-20">
+						{#if loading}
+							<svg
+								class="size-12 text-gray-900 dark:text-gray-400"
+								viewBox="0 0 24 24"
+								fill="currentColor"
+								xmlns="http://www.w3.org/2000/svg"
+								><style>
+									.spinner_qM83 {
+										animation: spinner_8HQG 1.05s infinite;
+									}
+									.spinner_oXPr {
+										animation-delay: 0.1s;
+									}
+									.spinner_ZTLf {
+										animation-delay: 0.2s;
+									}
+									@keyframes spinner_8HQG {
+										0%,
+										57.14% {
+											animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
+											transform: translate(0);
+										}
+										28.57% {
+											animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
+											transform: translateY(-6px);
+										}
+										100% {
+											transform: translate(0);
+										}
+									}
+								</style><circle class="spinner_qM83" cx="4" cy="12" r="3" /><circle
+									class="spinner_qM83 spinner_oXPr"
+									cx="12"
+									cy="12"
+									r="3"
+								/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="3" /></svg
+							>
+						{:else}
+							<div
+								class=" {rmsLevel * 100 > 4
+									? ' size-[4.5rem]'
+									: rmsLevel * 100 > 2
+									? ' size-16'
+									: rmsLevel * 100 > 1
+									? 'size-14'
+									: 'size-12'}  transition-all bg-black dark:bg-white rounded-full"
+							/>
+						{/if}
+						<!-- navbar -->
+					</div>
+				{/if}
+
+				<div class="flex justify-center items-center flex-1 h-full w-full max-h-full">
+					{#if !camera}
+						{#if loading}
+							<svg
+								class="size-44 text-gray-900 dark:text-gray-400"
+								viewBox="0 0 24 24"
+								fill="currentColor"
+								xmlns="http://www.w3.org/2000/svg"
+								><style>
+									.spinner_qM83 {
+										animation: spinner_8HQG 1.05s infinite;
+									}
+									.spinner_oXPr {
+										animation-delay: 0.1s;
+									}
+									.spinner_ZTLf {
+										animation-delay: 0.2s;
+									}
+									@keyframes spinner_8HQG {
+										0%,
+										57.14% {
+											animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
+											transform: translate(0);
+										}
+										28.57% {
+											animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
+											transform: translateY(-6px);
+										}
+										100% {
+											transform: translate(0);
+										}
+									}
+								</style><circle class="spinner_qM83" cx="4" cy="12" r="3" /><circle
+									class="spinner_qM83 spinner_oXPr"
+									cx="12"
+									cy="12"
+									r="3"
+								/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="3" /></svg
+							>
+						{:else}
+							<div
+								class=" {rmsLevel * 100 > 4
+									? ' size-52'
+									: rmsLevel * 100 > 2
+									? 'size-48'
+									: rmsLevel * 100 > 1
+									? 'size-[11.5rem]'
+									: 'size-44'}  transition-all bg-black dark:bg-white rounded-full"
+							/>
+						{/if}
+					{:else}
+						<div
+							class="relative flex video-container w-full max-h-full pt-2 pb-4 md:py-6 px-2 h-full"
+						>
+							<video
+								id="camera-feed"
+								autoplay
+								class="rounded-2xl h-full min-w-full object-cover object-center"
+								playsinline
+							/>
+
+							<canvas id="camera-canvas" style="display:none;" />
+
+							<div class=" absolute top-4 md:top-8 left-4">
+								<button
+									type="button"
+									class="p-1.5 text-white cursor-pointer backdrop-blur-xl bg-black/10 rounded-full"
+									on:click={() => {
+										stopCamera();
+									}}
+								>
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 16 16"
+										fill="currentColor"
+										class="size-6"
+									>
+										<path
+											d="M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z"
+										/>
+									</svg>
+								</button>
+							</div>
+						</div>
+					{/if}
+				</div>
+
+				<div class="flex justify-between items-center pb-2 w-full">
+					<div>
+						{#if camera}
+							<VideoInputMenu
+								devices={videoInputDevices}
+								on:change={async (e) => {
+									console.log(e.detail);
+									selectedVideoInputDeviceId = e.detail;
+									await stopVideoStream();
+									await startVideoStream();
+								}}
+							>
+								<button class=" p-3 rounded-full bg-gray-50 dark:bg-gray-900" type="button">
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 20 20"
+										fill="currentColor"
+										class="size-5"
+									>
+										<path
+											fill-rule="evenodd"
+											d="M15.312 11.424a5.5 5.5 0 0 1-9.201 2.466l-.312-.311h2.433a.75.75 0 0 0 0-1.5H3.989a.75.75 0 0 0-.75.75v4.242a.75.75 0 0 0 1.5 0v-2.43l.31.31a7 7 0 0 0 11.712-3.138.75.75 0 0 0-1.449-.39Zm1.23-3.723a.75.75 0 0 0 .219-.53V2.929a.75.75 0 0 0-1.5 0V5.36l-.31-.31A7 7 0 0 0 3.239 8.188a.75.75 0 1 0 1.448.389A5.5 5.5 0 0 1 13.89 6.11l.311.31h-2.432a.75.75 0 0 0 0 1.5h4.243a.75.75 0 0 0 .53-.219Z"
+											clip-rule="evenodd"
+										/>
+									</svg>
+								</button>
+							</VideoInputMenu>
+						{:else}
+							<Tooltip content={$i18n.t('Camera')}>
+								<button
+									class=" p-3 rounded-full bg-gray-50 dark:bg-gray-900"
+									type="button"
+									on:click={() => {
+										startCamera();
+									}}
+								>
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										fill="none"
+										viewBox="0 0 24 24"
+										stroke-width="1.5"
+										stroke="currentColor"
+										class="size-5"
+									>
+										<path
+											stroke-linecap="round"
+											stroke-linejoin="round"
+											d="M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z"
+										/>
+										<path
+											stroke-linecap="round"
+											stroke-linejoin="round"
+											d="M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM18.75 10.5h.008v.008h-.008V10.5Z"
+										/>
+									</svg>
+								</button>
+							</Tooltip>
+						{/if}
+					</div>
+
+					<div>
+						<button type="button">
+							<div class=" line-clamp-1 text-sm font-medium">
+								{#if loading}
+									{$i18n.t('Thinking...')}
+								{:else}
+									{$i18n.t('Listening...')}
+								{/if}
+							</div>
+						</button>
+					</div>
+
+					<div>
+						<button
+							class=" p-3 rounded-full bg-gray-50 dark:bg-gray-900"
+							on:click={async () => {
+								showCallOverlay.set(false);
+							}}
+							type="button"
+						>
+							<svg
+								xmlns="http://www.w3.org/2000/svg"
+								viewBox="0 0 20 20"
+								fill="currentColor"
+								class="size-5"
+							>
+								<path
+									d="M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z"
+								/>
+							</svg>
+						</button>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+{/if}

+ 51 - 0
src/lib/components/chat/MessageInput/CallOverlay/VideoInputMenu.svelte

@@ -0,0 +1,51 @@
+<script lang="ts">
+	import { DropdownMenu } from 'bits-ui';
+	import { flyAndScale } from '$lib/utils/transitions';
+	import { getContext, createEventDispatcher } from 'svelte';
+
+	const i18n = getContext('i18n');
+	const dispatch = createEventDispatcher();
+
+	import Dropdown from '$lib/components/common/Dropdown.svelte';
+
+	export let onClose: Function = () => {};
+	export let devices: any;
+
+	let show = false;
+</script>
+
+<Dropdown
+	bind:show
+	on:change={(e) => {
+		if (e.detail === false) {
+			onClose();
+		}
+	}}
+>
+	<slot />
+
+	<div slot="content">
+		<DropdownMenu.Content
+			class="w-full max-w-[180px] rounded-lg px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-[9999] bg-white dark:bg-gray-900 dark:text-white shadow-sm"
+			sideOffset={6}
+			side="top"
+			align="start"
+			transition={flyAndScale}
+		>
+			{#each devices as device}
+				<DropdownMenu.Item
+					class="flex gap-2 items-center px-3 py-2 text-sm  cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+					on:click={() => {
+						dispatch('change', device.deviceId);
+					}}
+				>
+					<div class="flex items-center">
+						<div class=" line-clamp-1">
+							{device?.label ?? 'Camera'}
+						</div>
+					</div>
+				</DropdownMenu.Item>
+			{/each}
+		</DropdownMenu.Content>
+	</div>
+</Dropdown>

+ 1 - 1
src/lib/components/chat/MessageInput/Documents.svelte

@@ -101,7 +101,7 @@
 </script>
 
 {#if filteredItems.length > 0 || prompt.split(' ')?.at(0)?.substring(1).startsWith('http')}
-	<div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
+	<div class="pl-1 pr-12 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
 		<div class="flex w-full px-2">
 			<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-xl text-center">
 				<div class=" text-lg font-semibold mt-2">#</div>

+ 1 - 1
src/lib/components/chat/MessageInput/Models.svelte

@@ -133,7 +133,7 @@
 
 {#if prompt.charAt(0) === '@'}
 	{#if filteredModels.length > 0}
-		<div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
+		<div class="pl-1 pr-12 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
 			<div class="flex w-full px-2">
 				<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-xl text-center">
 					<div class=" text-lg font-semibold mt-2">@</div>

+ 28 - 1
src/lib/components/chat/MessageInput/PromptCommands.svelte

@@ -6,6 +6,7 @@
 
 	const i18n = getContext('i18n');
 
+	export let files;
 	export let prompt = '';
 	let selectedCommandIdx = 0;
 	let filteredPromptCommands = [];
@@ -35,6 +36,32 @@
 				return '{{CLIPBOARD}}';
 			});
 
+			console.log(clipboardText);
+
+			const clipboardItems = await navigator.clipboard.read();
+
+			let imageUrl = null;
+			for (const item of clipboardItems) {
+				// Check for known image types
+				for (const type of item.types) {
+					if (type.startsWith('image/')) {
+						const blob = await item.getType(type);
+						imageUrl = URL.createObjectURL(blob);
+						console.log(`Image URL (${type}): ${imageUrl}`);
+					}
+				}
+			}
+
+			if (imageUrl) {
+				files = [
+					...files,
+					{
+						type: 'image',
+						url: imageUrl
+					}
+				];
+			}
+
 			text = command.content.replaceAll('{{CLIPBOARD}}', clipboardText);
 		}
 
@@ -61,7 +88,7 @@
 </script>
 
 {#if filteredPromptCommands.length > 0}
-	<div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
+	<div class="pl-1 pr-12 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
 		<div class="flex w-full px-2">
 			<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-xl text-center">
 				<div class=" text-lg font-semibold mt-2">/</div>

+ 458 - 0
src/lib/components/chat/MessageInput/VoiceRecording.svelte

@@ -0,0 +1,458 @@
+<script lang="ts">
+	import { toast } from 'svelte-sonner';
+	import { createEventDispatcher, tick, getContext } from 'svelte';
+	import { config, settings } from '$lib/stores';
+	import { blobToFile, calculateSHA256, findWordIndices } from '$lib/utils';
+
+	import { transcribeAudio } from '$lib/apis/audio';
+
+	const i18n = getContext('i18n');
+
+	const dispatch = createEventDispatcher();
+
+	export let recording = false;
+
+	let loading = false;
+	let confirmed = false;
+
+	let durationSeconds = 0;
+	let durationCounter = null;
+
+	let transcription = '';
+
+	const startDurationCounter = () => {
+		durationCounter = setInterval(() => {
+			durationSeconds++;
+		}, 1000);
+	};
+
+	const stopDurationCounter = () => {
+		clearInterval(durationCounter);
+		durationSeconds = 0;
+	};
+
+	$: if (recording) {
+		startRecording();
+	} else {
+		stopRecording();
+	}
+
+	const formatSeconds = (seconds) => {
+		const minutes = Math.floor(seconds / 60);
+		const remainingSeconds = seconds % 60;
+		const formattedSeconds = remainingSeconds < 10 ? `0${remainingSeconds}` : remainingSeconds;
+		return `${minutes}:${formattedSeconds}`;
+	};
+
+	let speechRecognition;
+
+	let mediaRecorder;
+	let audioChunks = [];
+
+	const MIN_DECIBELS = -45;
+	const VISUALIZER_BUFFER_LENGTH = 300;
+
+	let visualizerData = Array(VISUALIZER_BUFFER_LENGTH).fill(0);
+
+	// Function to calculate the RMS level from time domain data
+	const calculateRMS = (data: Uint8Array) => {
+		let sumSquares = 0;
+		for (let i = 0; i < data.length; i++) {
+			const normalizedValue = (data[i] - 128) / 128; // Normalize the data
+			sumSquares += normalizedValue * normalizedValue;
+		}
+		return Math.sqrt(sumSquares / data.length);
+	};
+
+	const normalizeRMS = (rms) => {
+		rms = rms * 10;
+		const exp = 1.5; // Adjust exponent value; values greater than 1 expand larger numbers more and compress smaller numbers more
+		const scaledRMS = Math.pow(rms, exp);
+
+		// Scale between 0.01 (1%) and 1.0 (100%)
+		return Math.min(1.0, Math.max(0.01, scaledRMS));
+	};
+
+	const analyseAudio = (stream) => {
+		const audioContext = new AudioContext();
+		const audioStreamSource = audioContext.createMediaStreamSource(stream);
+
+		const analyser = audioContext.createAnalyser();
+		analyser.minDecibels = MIN_DECIBELS;
+		audioStreamSource.connect(analyser);
+
+		const bufferLength = analyser.frequencyBinCount;
+
+		const domainData = new Uint8Array(bufferLength);
+		const timeDomainData = new Uint8Array(analyser.fftSize);
+
+		let lastSoundTime = Date.now();
+
+		const detectSound = () => {
+			const processFrame = () => {
+				if (!recording || loading) return;
+
+				if (recording && !loading) {
+					analyser.getByteTimeDomainData(timeDomainData);
+					analyser.getByteFrequencyData(domainData);
+
+					// Calculate RMS level from time domain data
+					const rmsLevel = calculateRMS(timeDomainData);
+					// Push the calculated decibel level to visualizerData
+					visualizerData.push(normalizeRMS(rmsLevel));
+
+					// Ensure visualizerData array stays within the buffer length
+					if (visualizerData.length >= VISUALIZER_BUFFER_LENGTH) {
+						visualizerData.shift();
+					}
+
+					visualizerData = visualizerData;
+
+					// if (domainData.some((value) => value > 0)) {
+					// 	lastSoundTime = Date.now();
+					// }
+
+					// if (recording && Date.now() - lastSoundTime > 3000) {
+					// 	if ($settings?.speechAutoSend ?? false) {
+					// 		confirmRecording();
+					// 	}
+					// }
+				}
+
+				window.requestAnimationFrame(processFrame);
+			};
+
+			window.requestAnimationFrame(processFrame);
+		};
+
+		detectSound();
+	};
+
+	const transcribeHandler = async (audioBlob) => {
+		// Create a blob from the audio chunks
+
+		await tick();
+		const file = blobToFile(audioBlob, 'recording.wav');
+
+		const res = await transcribeAudio(localStorage.token, file).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res) {
+			console.log(res.text);
+			dispatch('confirm', res.text);
+		}
+	};
+
+	const saveRecording = (blob) => {
+		const url = URL.createObjectURL(blob);
+		const a = document.createElement('a');
+		document.body.appendChild(a);
+		a.style = 'display: none';
+		a.href = url;
+		a.download = 'recording.wav';
+		a.click();
+		window.URL.revokeObjectURL(url);
+	};
+
+	const startRecording = async () => {
+		startDurationCounter();
+
+		const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+		mediaRecorder = new MediaRecorder(stream);
+		mediaRecorder.onstart = () => {
+			console.log('Recording started');
+			audioChunks = [];
+			analyseAudio(stream);
+		};
+		mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data);
+		mediaRecorder.onstop = async () => {
+			console.log('Recording stopped');
+			if (($settings?.audio?.stt?.engine ?? '') === 'web') {
+				audioChunks = [];
+			} else {
+				if (confirmed) {
+					const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
+
+					await transcribeHandler(audioBlob);
+
+					confirmed = false;
+					loading = false;
+				}
+				audioChunks = [];
+				recording = false;
+			}
+		};
+		mediaRecorder.start();
+		if ($config.audio.stt.engine === 'web' || ($settings?.audio?.stt?.engine ?? '') === 'web') {
+			if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) {
+				// Create a SpeechRecognition object
+				speechRecognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
+
+				// Set continuous to true for continuous recognition
+				speechRecognition.continuous = true;
+
+				// Set the timeout for turning off the recognition after inactivity (in milliseconds)
+				const inactivityTimeout = 2000; // 3 seconds
+
+				let timeoutId;
+				// Start recognition
+				speechRecognition.start();
+
+				// Event triggered when speech is recognized
+				speechRecognition.onresult = async (event) => {
+					// Clear the inactivity timeout
+					clearTimeout(timeoutId);
+
+					// Handle recognized speech
+					console.log(event);
+					const transcript = event.results[Object.keys(event.results).length - 1][0].transcript;
+
+					transcription = `${transcription}${transcript}`;
+
+					await tick();
+					document.getElementById('chat-textarea')?.focus();
+
+					// Restart the inactivity timeout
+					timeoutId = setTimeout(() => {
+						console.log('Speech recognition turned off due to inactivity.');
+						speechRecognition.stop();
+					}, inactivityTimeout);
+				};
+
+				// Event triggered when recognition is ended
+				speechRecognition.onend = function () {
+					// Restart recognition after it ends
+					console.log('recognition ended');
+
+					confirmRecording();
+					dispatch('confirm', transcription);
+
+					confirmed = false;
+					loading = false;
+				};
+
+				// Event triggered when an error occurs
+				speechRecognition.onerror = function (event) {
+					console.log(event);
+					toast.error($i18n.t(`Speech recognition error: {{error}}`, { error: event.error }));
+					dispatch('cancel');
+
+					stopRecording();
+				};
+			}
+		}
+	};
+
+	const stopRecording = async () => {
+		if (recording && mediaRecorder) {
+			await mediaRecorder.stop();
+		}
+		stopDurationCounter();
+		audioChunks = [];
+	};
+
+	const confirmRecording = async () => {
+		loading = true;
+		confirmed = true;
+
+		if (recording && mediaRecorder) {
+			await mediaRecorder.stop();
+		}
+		clearInterval(durationCounter);
+	};
+</script>
+
+<div
+	class="{loading
+		? ' bg-gray-100/50 dark:bg-gray-850/50'
+		: 'bg-indigo-300/10 dark:bg-indigo-500/10 '} rounded-full flex p-2.5"
+>
+	<div class="flex items-center mr-1">
+		<button
+			type="button"
+			class="p-1.5
+
+            {loading
+				? ' bg-gray-200 dark:bg-gray-700/50'
+				: 'bg-indigo-400/20 text-indigo-600 dark:text-indigo-300 '} 
+
+
+             rounded-full"
+			on:click={async () => {
+				dispatch('cancel');
+				stopRecording();
+			}}
+		>
+			<svg
+				xmlns="http://www.w3.org/2000/svg"
+				fill="none"
+				viewBox="0 0 24 24"
+				stroke-width="3"
+				stroke="currentColor"
+				class="size-4"
+			>
+				<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
+			</svg>
+		</button>
+	</div>
+
+	<div
+		class="flex flex-1 self-center items-center justify-between ml-2 mx-1 overflow-hidden h-6"
+		dir="rtl"
+	>
+		<div class="flex-1 flex items-center gap-0.5 h-6">
+			{#each visualizerData.slice().reverse() as rms}
+				<div
+					class="w-[2px]
+                    
+                    {loading
+						? ' bg-gray-500 dark:bg-gray-400   '
+						: 'bg-indigo-500 dark:bg-indigo-400  '} 
+                    
+                    inline-block h-full"
+					style="height: {Math.min(100, Math.max(14, rms * 100))}%;"
+				/>
+			{/each}
+		</div>
+	</div>
+
+	<div class="  mx-1.5 pr-1 flex justify-center items-center">
+		<div
+			class="text-sm
+        
+        
+        {loading ? ' text-gray-500  dark:text-gray-400  ' : ' text-indigo-400 '} 
+       font-medium flex-1 mx-auto text-center"
+		>
+			{formatSeconds(durationSeconds)}
+		</div>
+	</div>
+
+	<div class="flex items-center mr-1">
+		{#if loading}
+			<div class=" text-gray-500 rounded-full cursor-not-allowed">
+				<svg
+					width="24"
+					height="24"
+					viewBox="0 0 24 24"
+					xmlns="http://www.w3.org/2000/svg"
+					fill="currentColor"
+					><style>
+						.spinner_OSmW {
+							transform-origin: center;
+							animation: spinner_T6mA 0.75s step-end infinite;
+						}
+						@keyframes spinner_T6mA {
+							8.3% {
+								transform: rotate(30deg);
+							}
+							16.6% {
+								transform: rotate(60deg);
+							}
+							25% {
+								transform: rotate(90deg);
+							}
+							33.3% {
+								transform: rotate(120deg);
+							}
+							41.6% {
+								transform: rotate(150deg);
+							}
+							50% {
+								transform: rotate(180deg);
+							}
+							58.3% {
+								transform: rotate(210deg);
+							}
+							66.6% {
+								transform: rotate(240deg);
+							}
+							75% {
+								transform: rotate(270deg);
+							}
+							83.3% {
+								transform: rotate(300deg);
+							}
+							91.6% {
+								transform: rotate(330deg);
+							}
+							100% {
+								transform: rotate(360deg);
+							}
+						}
+					</style><g class="spinner_OSmW"
+						><rect x="11" y="1" width="2" height="5" opacity=".14" /><rect
+							x="11"
+							y="1"
+							width="2"
+							height="5"
+							transform="rotate(30 12 12)"
+							opacity=".29"
+						/><rect
+							x="11"
+							y="1"
+							width="2"
+							height="5"
+							transform="rotate(60 12 12)"
+							opacity=".43"
+						/><rect
+							x="11"
+							y="1"
+							width="2"
+							height="5"
+							transform="rotate(90 12 12)"
+							opacity=".57"
+						/><rect
+							x="11"
+							y="1"
+							width="2"
+							height="5"
+							transform="rotate(120 12 12)"
+							opacity=".71"
+						/><rect
+							x="11"
+							y="1"
+							width="2"
+							height="5"
+							transform="rotate(150 12 12)"
+							opacity=".86"
+						/><rect x="11" y="1" width="2" height="5" transform="rotate(180 12 12)" /></g
+					></svg
+				>
+			</div>
+		{:else}
+			<button
+				type="button"
+				class="p-1.5 bg-indigo-500 text-white dark:bg-indigo-500 dark:text-blue-950 rounded-full"
+				on:click={async () => {
+					await confirmRecording();
+				}}
+			>
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					fill="none"
+					viewBox="0 0 24 24"
+					stroke-width="2.5"
+					stroke="currentColor"
+					class="size-4"
+				>
+					<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
+				</svg>
+			</button>
+		{/if}
+	</div>
+</div>
+
+<style>
+	.visualizer {
+		display: flex;
+		height: 100%;
+	}
+
+	.visualizer-bar {
+		width: 2px;
+		background-color: #4a5aba; /* or whatever color you need */
+	}
+</style>

+ 1 - 1
src/lib/components/chat/Messages/CompareMessages.svelte

@@ -109,7 +109,7 @@
 					class=" snap-center min-w-80 w-full max-w-full m-1 border {history.messages[
 						currentMessageId
 					].model === model
-						? 'border-gray-100 dark:border-gray-700 border-[1.5px]'
+						? 'border-gray-100 dark:border-gray-850 border-[1.5px]'
 						: 'border-gray-50 dark:border-gray-850 '} transition p-5 rounded-3xl"
 					on:click={() => {
 						currentMessageId = groupedMessages[model].messages[groupedMessagesIdx[model]].id;

+ 18 - 7
src/lib/components/chat/Messages/ResponseMessage.svelte

@@ -213,7 +213,7 @@
 		} else {
 			speaking = true;
 
-			if ($settings?.audio?.TTSEngine === 'openai') {
+			if ($config.audio.tts.engine === 'openai') {
 				loadingSpeech = true;
 
 				const sentences = extractSentences(message.content).reduce((mergedTexts, currentText) => {
@@ -244,9 +244,8 @@
 				for (const [idx, sentence] of sentences.entries()) {
 					const res = await synthesizeOpenAISpeech(
 						localStorage.token,
-						$settings?.audio?.speaker,
-						sentence,
-						$settings?.audio?.model
+						$settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice,
+						sentence
 					).catch((error) => {
 						toast.error(error);
 
@@ -273,17 +272,29 @@
 						clearInterval(getVoicesLoop);
 
 						const voice =
-							voices?.filter((v) => v.name === $settings?.audio?.speaker)?.at(0) ?? undefined;
+							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);
 
+						console.log(speak);
+
 						speak.onend = () => {
 							speaking = null;
 							if ($settings.conversationMode) {
 								document.getElementById('voice-input-button')?.click();
 							}
 						};
-						speak.voice = voice;
+
+						if (voice) {
+							speak.voice = voice;
+						}
+
 						speechSynthesis.speak(speak);
 					}
 				}, 100);
@@ -757,7 +768,7 @@
 										</Tooltip>
 
 										{#if $config?.features.enable_image_generation && !readOnly}
-											<Tooltip content="Generate Image" placement="bottom">
+											<Tooltip content={$i18n.t('Generate Image')} placement="bottom">
 												<button
 													class="{isLastMessage
 														? 'visible'

+ 2 - 2
src/lib/components/chat/ModelSelector/Selector.svelte

@@ -219,7 +219,7 @@
 	<DropdownMenu.Content
 		class=" z-40 {$mobile
 			? `w-full`
-			: `${className}`} max-w-[calc(100vw-1rem)] justify-start rounded-xl  bg-white dark:bg-gray-850 dark:text-white shadow-lg border border-gray-300/30 dark:border-gray-700/50  outline-none "
+			: `${className}`} max-w-[calc(100vw-1rem)] justify-start rounded-xl  bg-white dark:bg-gray-850 dark:text-white shadow-lg border border-gray-300/30 dark:border-gray-850/50  outline-none "
 		transition={flyAndScale}
 		side={$mobile ? 'bottom' : 'bottom-start'}
 		sideOffset={4}
@@ -265,7 +265,7 @@
 								</div>
 							{/if}
 							<div class="flex items-center gap-2">
-								<div class="flex items-center">
+								<div class="flex items-center min-w-fit">
 									<div class="line-clamp-1">
 										{item.label}
 									</div>

+ 2 - 2
src/lib/components/chat/Settings/About.svelte

@@ -92,7 +92,7 @@
 		</div>
 
 		{#if ollamaVersion}
-			<hr class=" dark:border-gray-700" />
+			<hr class=" dark:border-gray-850" />
 
 			<div>
 				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Ollama Version')}</div>
@@ -104,7 +104,7 @@
 			</div>
 		{/if}
 
-		<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-850" />
 
 		<div class="flex space-x-1">
 			<a href="https://discord.gg/5rJgQTnV4s" target="_blank">

+ 1 - 1
src/lib/components/chat/Settings/Account.svelte

@@ -234,7 +234,7 @@
 			<UpdatePassword />
 		</div>
 
-		<hr class=" dark:border-gray-700 my-4" />
+		<hr class=" dark:border-gray-850 my-4" />
 
 		<div class="flex justify-between items-center text-sm">
 			<div class="  font-medium">{$i18n.t('API keys')}</div>

+ 1 - 1
src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte

@@ -556,7 +556,7 @@
 						type="number"
 						class=" bg-transparent text-center w-14"
 						min="-1"
-						step="10"
+						step="1"
 					/>
 				</div>
 			</div>

+ 38 - 201
src/lib/components/chat/Settings/Audio.svelte

@@ -1,6 +1,5 @@
 <script lang="ts">
-	import { getAudioConfig, updateAudioConfig } from '$lib/apis/audio';
-	import { user, settings } from '$lib/stores';
+	import { user, settings, config } from '$lib/stores';
 	import { createEventDispatcher, onMount, getContext } from 'svelte';
 	import { toast } from 'svelte-sonner';
 	import Switch from '$lib/components/common/Switch.svelte';
@@ -11,26 +10,15 @@
 	export let saveSettings: Function;
 
 	// Audio
-
-	let OpenAIUrl = '';
-	let OpenAIKey = '';
-	let OpenAISpeaker = '';
-
-	let STTEngines = ['', 'openai'];
-	let STTEngine = '';
-
 	let conversationMode = false;
 	let speechAutoSend = false;
 	let responseAutoPlayback = false;
 	let nonLocalVoices = false;
 
-	let TTSEngines = ['', 'openai'];
-	let TTSEngine = '';
+	let STTEngine = '';
 
 	let voices = [];
-	let speaker = '';
-	let models = [];
-	let model = '';
+	let voice = '';
 
 	const getOpenAIVoices = () => {
 		voices = [
@@ -43,10 +31,6 @@
 		];
 	};
 
-	const getOpenAIVoicesModel = () => {
-		models = [{ name: 'tts-1' }, { name: 'tts-1-hd' }];
-	};
-
 	const getWebAPIVoices = () => {
 		const getVoicesLoop = setInterval(async () => {
 			voices = await speechSynthesis.getVoices();
@@ -58,21 +42,6 @@
 		}, 100);
 	};
 
-	const toggleConversationMode = async () => {
-		conversationMode = !conversationMode;
-
-		if (conversationMode) {
-			responseAutoPlayback = true;
-			speechAutoSend = true;
-		}
-
-		saveSettings({
-			conversationMode: conversationMode,
-			responseAutoPlayback: responseAutoPlayback,
-			speechAutoSend: speechAutoSend
-		});
-	};
-
 	const toggleResponseAutoPlayback = async () => {
 		responseAutoPlayback = !responseAutoPlayback;
 		saveSettings({ responseAutoPlayback: responseAutoPlayback });
@@ -83,76 +52,35 @@
 		saveSettings({ speechAutoSend: speechAutoSend });
 	};
 
-	const updateConfigHandler = async () => {
-		if (TTSEngine === 'openai') {
-			const res = await updateAudioConfig(localStorage.token, {
-				url: OpenAIUrl,
-				key: OpenAIKey,
-				model: model,
-				speaker: OpenAISpeaker
-			});
-
-			if (res) {
-				OpenAIUrl = res.OPENAI_API_BASE_URL;
-				OpenAIKey = res.OPENAI_API_KEY;
-				model = res.OPENAI_API_MODEL;
-				OpenAISpeaker = res.OPENAI_API_VOICE;
-			}
-		}
-	};
-
 	onMount(async () => {
 		conversationMode = $settings.conversationMode ?? false;
 		speechAutoSend = $settings.speechAutoSend ?? false;
 		responseAutoPlayback = $settings.responseAutoPlayback ?? false;
 
-		STTEngine = $settings?.audio?.STTEngine ?? '';
-		TTSEngine = $settings?.audio?.TTSEngine ?? '';
-		nonLocalVoices = $settings.audio?.nonLocalVoices ?? false;
-		speaker = $settings?.audio?.speaker ?? '';
-		model = $settings?.audio?.model ?? '';
+		STTEngine = $settings?.audio?.stt?.engine ?? '';
+		voice = $settings?.audio?.tts?.voice ?? $config.audio.tts.voice ?? '';
+		nonLocalVoices = $settings.audio?.tts?.nonLocalVoices ?? false;
 
-		if (TTSEngine === 'openai') {
+		if ($config.audio.tts.engine === 'openai') {
 			getOpenAIVoices();
-			getOpenAIVoicesModel();
 		} else {
 			getWebAPIVoices();
 		}
-
-		if ($user.role === 'admin') {
-			const res = await getAudioConfig(localStorage.token);
-
-			if (res) {
-				OpenAIUrl = res.OPENAI_API_BASE_URL;
-				OpenAIKey = res.OPENAI_API_KEY;
-				model = res.OPENAI_API_MODEL;
-				OpenAISpeaker = res.OPENAI_API_VOICE;
-				if (TTSEngine === 'openai') {
-					speaker = OpenAISpeaker;
-				}
-			}
-		}
 	});
 </script>
 
 <form
 	class="flex flex-col h-full justify-between space-y-3 text-sm"
 	on:submit|preventDefault={async () => {
-		if ($user.role === 'admin') {
-			await updateConfigHandler();
-		}
 		saveSettings({
 			audio: {
-				STTEngine: STTEngine !== '' ? STTEngine : undefined,
-				TTSEngine: TTSEngine !== '' ? TTSEngine : undefined,
-				speaker:
-					(TTSEngine === 'openai' ? OpenAISpeaker : speaker) !== ''
-						? TTSEngine === 'openai'
-							? OpenAISpeaker
-							: speaker
-						: undefined,
-				model: model !== '' ? model : undefined,
-				nonLocalVoices: nonLocalVoices
+				stt: {
+					engine: STTEngine !== '' ? STTEngine : undefined
+				},
+				tts: {
+					voice: voice !== '' ? voice : undefined,
+					nonLocalVoices: $config.audio.tts.engine === '' ? nonLocalVoices : undefined
+				}
 			}
 		});
 		dispatch('save');
@@ -162,53 +90,25 @@
 		<div>
 			<div class=" mb-1 text-sm font-medium">{$i18n.t('STT Settings')}</div>
 
-			<div class=" py-0.5 flex w-full justify-between">
-				<div class=" self-center text-xs font-medium">{$i18n.t('Speech-to-Text 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={STTEngine}
-						placeholder="Select a mode"
-						on:change={(e) => {
-							if (e.target.value !== '') {
-								navigator.mediaDevices.getUserMedia({ audio: true }).catch(function (err) {
-									toast.error(
-										$i18n.t(`Permission denied when accessing microphone: {{error}}`, {
-											error: err
-										})
-									);
-									STTEngine = '';
-								});
-							}
-						}}
-					>
-						<option value="">{$i18n.t('Default (Web API)')}</option>
-						<option value="whisper-local">{$i18n.t('Whisper (Local)')}</option>
-					</select>
+			{#if $config.audio.stt.engine !== 'web'}
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs font-medium">{$i18n.t('Speech-to-Text 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={STTEngine}
+							placeholder="Select an engine"
+						>
+							<option value="">{$i18n.t('Default')}</option>
+							<option value="web">{$i18n.t('Web API')}</option>
+						</select>
+					</div>
 				</div>
-			</div>
-
-			<div class=" py-0.5 flex w-full justify-between">
-				<div class=" self-center text-xs font-medium">{$i18n.t('Conversation Mode')}</div>
-
-				<button
-					class="p-1 px-3 text-xs flex rounded transition"
-					on:click={() => {
-						toggleConversationMode();
-					}}
-					type="button"
-				>
-					{#if conversationMode === true}
-						<span class="ml-2 self-center">{$i18n.t('On')}</span>
-					{:else}
-						<span class="ml-2 self-center">{$i18n.t('Off')}</span>
-					{/if}
-				</button>
-			</div>
+			{/if}
 
 			<div class=" py-0.5 flex w-full justify-between">
 				<div class=" self-center text-xs font-medium">
-					{$i18n.t('Auto-send input after 3 sec.')}
+					{$i18n.t('Instant Auto-Send After Voice Transcription')}
 				</div>
 
 				<button
@@ -230,50 +130,6 @@
 		<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 a mode"
-						on:change={(e) => {
-							if (e.target.value === 'openai') {
-								getOpenAIVoices();
-								OpenAISpeaker = 'alloy';
-								model = 'tts-1';
-							} else {
-								getWebAPIVoices();
-								speaker = '';
-							}
-						}}
-					>
-						<option value="">{$i18n.t('Default (Web API)')}</option>
-						<option value="openai">{$i18n.t('Open AI')}</option>
-					</select>
-				</div>
-			</div>
-
-			{#if $user.role === 'admin'}
-				{#if TTSEngine === 'openai'}
-					<div class="mt-1 flex gap-2 mb-1">
-						<input
-							class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-							placeholder={$i18n.t('API Base URL')}
-							bind:value={OpenAIUrl}
-							required
-						/>
-
-						<input
-							class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-							placeholder={$i18n.t('API Key')}
-							bind:value={OpenAIKey}
-							required
-						/>
-					</div>
-				{/if}
-			{/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>
 
@@ -293,23 +149,23 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-850" />
 
-		{#if TTSEngine === ''}
+		{#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">
 					<div class="flex-1">
 						<select
 							class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-							bind:value={speaker}
+							bind:value={voice}
 						>
-							<option value="" selected={speaker !== ''}>{$i18n.t('Default')}</option>
-							{#each voices.filter((v) => nonLocalVoices || v.localService === true) as voice}
+							<option value="" selected={voice !== ''}>{$i18n.t('Default')}</option>
+							{#each voices.filter((v) => nonLocalVoices || v.localService === true) as _voice}
 								<option
-									value={voice.name}
+									value={_voice.name}
 									class="bg-gray-100 dark:bg-gray-700"
-									selected={speaker === voice.name}>{voice.name}</option
+									selected={voice === _voice.name}>{_voice.name}</option
 								>
 							{/each}
 						</select>
@@ -325,7 +181,7 @@
 					</div>
 				</div>
 			</div>
-		{:else if TTSEngine === 'openai'}
+		{:else if $config.audio.tts.engine === 'openai'}
 			<div>
 				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Voice')}</div>
 				<div class="flex w-full">
@@ -333,7 +189,7 @@
 						<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={OpenAISpeaker}
+							bind:value={voice}
 							placeholder="Select a voice"
 						/>
 
@@ -345,25 +201,6 @@
 					</div>
 				</div>
 			</div>
-			<div>
-				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Model')}</div>
-				<div class="flex w-full">
-					<div class="flex-1">
-						<input
-							list="model-list"
-							class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-							bind:value={model}
-							placeholder="Select a model"
-						/>
-
-						<datalist id="model-list">
-							{#each models as model}
-								<option value={model.name} />
-							{/each}
-						</datalist>
-					</div>
-				</div>
-			</div>
 		{/if}
 	</div>
 

+ 2 - 2
src/lib/components/chat/Settings/Chats.svelte

@@ -161,7 +161,7 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-850" />
 
 		<div class="flex flex-col">
 			<input
@@ -218,7 +218,7 @@
 			</button>
 		</div>
 
-		<hr class=" dark:border-gray-700" />
+		<hr class=" dark:border-gray-850" />
 
 		<div class="flex flex-col">
 			{#if showArchiveConfirm}

+ 2 - 2
src/lib/components/chat/Settings/General.svelte

@@ -203,7 +203,7 @@
 			</div>
 		</div>
 
-		<hr class=" dark:border-gray-700 my-3" />
+		<hr class=" dark:border-gray-850 my-3" />
 
 		<div>
 			<div class=" my-2.5 text-sm font-medium">{$i18n.t('System Prompt')}</div>
@@ -228,7 +228,7 @@
 
 			{#if showAdvanced}
 				<AdvancedParams bind:params />
-				<hr class=" dark:border-gray-700" />
+				<hr class=" dark:border-gray-850" />
 
 				<div class=" py-1 w-full justify-between">
 					<div class="flex w-full justify-between">

+ 0 - 181
src/lib/components/chat/Settings/Interface.svelte

@@ -14,15 +14,11 @@
 	// Addons
 	let titleAutoGenerate = true;
 	let responseAutoCopy = false;
-	let titleAutoGenerateModel = '';
-	let titleAutoGenerateModelExternal = '';
 	let widescreenMode = false;
-	let titleGenerationPrompt = '';
 	let splitLargeChunks = false;
 
 	// Interface
 	let defaultModelId = '';
-	let promptSuggestions = [];
 	let showUsername = false;
 	let chatBubble = true;
 	let chatDirection: 'LTR' | 'RTL' = 'LTR';
@@ -85,34 +81,13 @@
 	};
 
 	const updateInterfaceHandler = async () => {
-		if ($user.role === 'admin') {
-			promptSuggestions = await setDefaultPromptSuggestions(localStorage.token, promptSuggestions);
-			await config.set(await getBackendConfig());
-		}
-
 		saveSettings({
-			title: {
-				...$settings.title,
-				model: titleAutoGenerateModel !== '' ? titleAutoGenerateModel : undefined,
-				modelExternal:
-					titleAutoGenerateModelExternal !== '' ? titleAutoGenerateModelExternal : undefined,
-				prompt: titleGenerationPrompt ? titleGenerationPrompt : undefined
-			},
 			models: [defaultModelId]
 		});
 	};
 
 	onMount(async () => {
-		if ($user.role === 'admin') {
-			promptSuggestions = $config?.default_prompt_suggestions;
-		}
-
 		titleAutoGenerate = $settings?.title?.auto ?? true;
-		titleAutoGenerateModel = $settings?.title?.model ?? '';
-		titleAutoGenerateModelExternal = $settings?.title?.modelExternal ?? '';
-		titleGenerationPrompt =
-			$settings?.title?.prompt ??
-			`Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title': {{prompt}}`;
 		responseAutoCopy = $settings.responseAutoCopy ?? false;
 		showUsername = $settings.showUsername ?? false;
 		chatBubble = $settings.chatBubble ?? true;
@@ -304,162 +279,6 @@
 				</select>
 			</div>
 		</div>
-
-		<hr class=" dark:border-gray-850" />
-
-		<div>
-			<div class=" mb-2.5 text-sm font-medium flex">
-				<div class=" mr-1">{$i18n.t('Set Task Model')}</div>
-				<Tooltip
-					content={$i18n.t(
-						'A task model is used when performing tasks such as generating titles for chats and web search queries'
-					)}
-				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						fill="none"
-						viewBox="0 0 24 24"
-						stroke-width="1.5"
-						stroke="currentColor"
-						class="w-5 h-5"
-					>
-						<path
-							stroke-linecap="round"
-							stroke-linejoin="round"
-							d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
-						/>
-					</svg>
-				</Tooltip>
-			</div>
-			<div class="flex w-full gap-2 pr-2">
-				<div class="flex-1">
-					<div class=" text-xs mb-1">Local Models</div>
-					<select
-						class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-						bind:value={titleAutoGenerateModel}
-						placeholder={$i18n.t('Select a model')}
-					>
-						<option value="" selected>{$i18n.t('Current Model')}</option>
-						{#each $models.filter((m) => m.owned_by === 'ollama') as model}
-							<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
-								{model.name}
-							</option>
-						{/each}
-					</select>
-				</div>
-
-				<div class="flex-1">
-					<div class=" text-xs mb-1">External Models</div>
-					<select
-						class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
-						bind:value={titleAutoGenerateModelExternal}
-						placeholder={$i18n.t('Select a model')}
-					>
-						<option value="" selected>{$i18n.t('Current Model')}</option>
-						{#each $models as model}
-							<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
-								{model.name}
-							</option>
-						{/each}
-					</select>
-				</div>
-			</div>
-
-			<div class="mt-3 mr-2">
-				<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Title Generation Prompt')}</div>
-				<textarea
-					bind:value={titleGenerationPrompt}
-					class="w-full rounded-lg p-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
-					rows="3"
-				/>
-			</div>
-		</div>
-
-		{#if $user.role === 'admin'}
-			<hr class=" dark:border-gray-700" />
-
-			<div class=" space-y-3 pr-1.5">
-				<div class="flex w-full justify-between mb-2">
-					<div class=" self-center text-sm font-semibold">
-						{$i18n.t('Default Prompt Suggestions')}
-					</div>
-
-					<button
-						class="p-1 px-3 text-xs flex rounded transition"
-						type="button"
-						on:click={() => {
-							if (promptSuggestions.length === 0 || promptSuggestions.at(-1).content !== '') {
-								promptSuggestions = [...promptSuggestions, { content: '', title: ['', ''] }];
-							}
-						}}
-					>
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							viewBox="0 0 20 20"
-							fill="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
-							/>
-						</svg>
-					</button>
-				</div>
-				<div class="flex flex-col space-y-1">
-					{#each promptSuggestions as prompt, promptIdx}
-						<div class=" flex border dark:border-gray-600 rounded-lg">
-							<div class="flex flex-col flex-1">
-								<div class="flex border-b dark:border-gray-600 w-full">
-									<input
-										class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-600"
-										placeholder={$i18n.t('Title (e.g. Tell me a fun fact)')}
-										bind:value={prompt.title[0]}
-									/>
-
-									<input
-										class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-600"
-										placeholder={$i18n.t('Subtitle (e.g. about the Roman Empire)')}
-										bind:value={prompt.title[1]}
-									/>
-								</div>
-
-								<input
-									class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r dark:border-gray-600"
-									placeholder={$i18n.t('Prompt (e.g. Tell me a fun fact about the Roman Empire)')}
-									bind:value={prompt.content}
-								/>
-							</div>
-
-							<button
-								class="px-2"
-								type="button"
-								on:click={() => {
-									promptSuggestions.splice(promptIdx, 1);
-									promptSuggestions = promptSuggestions;
-								}}
-							>
-								<svg
-									xmlns="http://www.w3.org/2000/svg"
-									viewBox="0 0 20 20"
-									fill="currentColor"
-									class="w-4 h-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"
-									/>
-								</svg>
-							</button>
-						</div>
-					{/each}
-				</div>
-
-				{#if promptSuggestions.length > 0}
-					<div class="text-xs text-left w-full mt-2">
-						{$i18n.t('Adjusting these settings will apply changes universally to all users.')}
-					</div>
-				{/if}
-			</div>
-		{/if}
 	</div>
 
 	<div class="flex justify-end text-sm font-medium">

+ 2 - 2
src/lib/components/chat/Settings/Models.svelte

@@ -541,7 +541,7 @@
 			]);
 		} else {
 			ollamaEnabled = false;
-			toast.error('Ollama API is disabled');
+			toast.error($i18n.t('Ollama API is disabled'));
 		}
 	});
 </script>
@@ -1063,7 +1063,7 @@
 				</div>
 			{/if}
 		{:else if ollamaEnabled === false}
-			<div>Ollama API is disabled</div>
+			<div>{$i18n.t('Ollama API is disabled')}</div>
 		{:else}
 			<div class="flex h-full justify-center">
 				<div class="my-auto">

+ 7 - 4
src/lib/components/chat/Settings/Personalization.svelte

@@ -35,7 +35,9 @@
 		<div>
 			<div class="flex items-center justify-between mb-1">
 				<Tooltip
-					content="This is an experimental feature, it may not function as expected and is subject to change at any time."
+					content={$i18n.t(
+						'This is an experimental feature, it may not function as expected and is subject to change at any time.'
+					)}
 				>
 					<div class="text-sm font-medium">
 						{$i18n.t('Memory')}
@@ -57,8 +59,9 @@
 
 		<div class="text-xs text-gray-600 dark:text-gray-400">
 			<div>
-				You can personalize your interactions with LLMs by adding memories through the 'Manage'
-				button below, making them more helpful and tailored to you.
+				{$i18n.t(
+					"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you."
+				)}
 			</div>
 
 			<!-- <div class="mt-3">
@@ -79,7 +82,7 @@
 					showManageModal = true;
 				}}
 			>
-				Manage
+				{$i18n.t('Manage')}
 			</button>
 		</div>
 	</div>

+ 1 - 1
src/lib/components/chat/Settings/Personalization/AddMemoryModal.svelte

@@ -75,7 +75,7 @@
 						/>
 
 						<div class="text-xs text-gray-500">
-							ⓘ Refer to yourself as "User" (e.g., "User is learning Spanish")
+							ⓘ {$i18n.t('Refer to yourself as "User" (e.g., "User is learning Spanish")')}
 						</div>
 					</div>
 

+ 2 - 2
src/lib/components/chat/Settings/Personalization/ManageModal.svelte

@@ -136,7 +136,7 @@
 					class=" px-3.5 py-1.5 font-medium hover:bg-black/5 dark:hover:bg-white/5 outline outline-1 outline-gray-300 dark:outline-gray-800 rounded-3xl"
 					on:click={() => {
 						showAddMemoryModal = true;
-					}}>Add memory</button
+					}}>{$i18n.t('Add Memory')}</button
 				>
 				<button
 					class=" px-3.5 py-1.5 font-medium text-red-500 hover:bg-black/5 dark:hover:bg-white/5 outline outline-1 outline-red-300 dark:outline-red-800 rounded-3xl"
@@ -150,7 +150,7 @@
 							toast.success('Memory cleared successfully');
 							memories = [];
 						}
-					}}>Clear memory</button
+					}}>{$i18n.t('Clear memory')}</button
 				>
 			</div>
 		</div>

+ 10 - 79
src/lib/components/chat/SettingsModal.svelte

@@ -8,16 +8,14 @@
 	import Modal from '../common/Modal.svelte';
 	import Account from './Settings/Account.svelte';
 	import About from './Settings/About.svelte';
-	import Models from './Settings/Models.svelte';
 	import General from './Settings/General.svelte';
 	import Interface from './Settings/Interface.svelte';
 	import Audio from './Settings/Audio.svelte';
 	import Chats from './Settings/Chats.svelte';
-	import Connections from './Settings/Connections.svelte';
-	import Images from './Settings/Images.svelte';
 	import User from '../icons/User.svelte';
 	import Personalization from './Settings/Personalization.svelte';
 	import { updateUserSettings } from '$lib/apis/users';
+	import { goto } from '$app/navigation';
 
 	const i18n = getContext('i18n');
 
@@ -90,55 +88,32 @@
 					<div class=" self-center">{$i18n.t('General')}</div>
 				</button>
 
-				{#if $user?.role === 'admin'}
-					<button
-						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-						'connections'
-							? 'bg-gray-200 dark:bg-gray-700'
-							: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-						on:click={() => {
-							selectedTab = 'connections';
-						}}
-					>
-						<div class=" self-center mr-2">
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 16 16"
-								fill="currentColor"
-								class="w-4 h-4"
-							>
-								<path
-									d="M1 9.5A3.5 3.5 0 0 0 4.5 13H12a3 3 0 0 0 .917-5.857 2.503 2.503 0 0 0-3.198-3.019 3.5 3.5 0 0 0-6.628 2.171A3.5 3.5 0 0 0 1 9.5Z"
-								/>
-							</svg>
-						</div>
-						<div class=" self-center">{$i18n.t('Connections')}</div>
-					</button>
-
+				{#if $user.role === 'admin'}
 					<button
 						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-						'models'
+						'admin'
 							? 'bg-gray-200 dark:bg-gray-700'
 							: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-						on:click={() => {
-							selectedTab = 'models';
+						on:click={async () => {
+							await goto('/admin/settings');
+							show = false;
 						}}
 					>
 						<div class=" self-center mr-2">
 							<svg
 								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 20 20"
+								viewBox="0 0 24 24"
 								fill="currentColor"
-								class="w-4 h-4"
+								class="size-4"
 							>
 								<path
 									fill-rule="evenodd"
-									d="M10 1c3.866 0 7 1.79 7 4s-3.134 4-7 4-7-1.79-7-4 3.134-4 7-4zm5.694 8.13c.464-.264.91-.583 1.306-.952V10c0 2.21-3.134 4-7 4s-7-1.79-7-4V8.178c.396.37.842.688 1.306.953C5.838 10.006 7.854 10.5 10 10.5s4.162-.494 5.694-1.37zM3 13.179V15c0 2.21 3.134 4 7 4s7-1.79 7-4v-1.822c-.396.37-.842.688-1.306.953-1.532.875-3.548 1.369-5.694 1.369s-4.162-.494-5.694-1.37A7.009 7.009 0 013 13.179z"
+									d="M4.5 3.75a3 3 0 0 0-3 3v10.5a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V6.75a3 3 0 0 0-3-3h-15Zm4.125 3a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Zm-3.873 8.703a4.126 4.126 0 0 1 7.746 0 .75.75 0 0 1-.351.92 7.47 7.47 0 0 1-3.522.877 7.47 7.47 0 0 1-3.522-.877.75.75 0 0 1-.351-.92ZM15 8.25a.75.75 0 0 0 0 1.5h3.75a.75.75 0 0 0 0-1.5H15ZM14.25 12a.75.75 0 0 1 .75-.75h3.75a.75.75 0 0 1 0 1.5H15a.75.75 0 0 1-.75-.75Zm.75 2.25a.75.75 0 0 0 0 1.5h3.75a.75.75 0 0 0 0-1.5H15Z"
 									clip-rule="evenodd"
 								/>
 							</svg>
 						</div>
-						<div class=" self-center">{$i18n.t('Models')}</div>
+						<div class=" self-center">{$i18n.t('Admin Settings')}</div>
 					</button>
 				{/if}
 
@@ -210,34 +185,6 @@
 					<div class=" self-center">{$i18n.t('Audio')}</div>
 				</button>
 
-				{#if $user.role === 'admin'}
-					<button
-						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
-						'images'
-							? 'bg-gray-200 dark:bg-gray-700'
-							: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
-						on:click={() => {
-							selectedTab = 'images';
-						}}
-					>
-						<div class=" self-center mr-2">
-							<svg
-								xmlns="http://www.w3.org/2000/svg"
-								viewBox="0 0 16 16"
-								fill="currentColor"
-								class="w-4 h-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-2V4Zm10.5 5.707a.5.5 0 0 0-.146-.353l-1-1a.5.5 0 0 0-.708 0L9.354 9.646a.5.5 0 0 1-.708 0L6.354 7.354a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0-.146.353V12a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5V9.707ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
-									clip-rule="evenodd"
-								/>
-							</svg>
-						</div>
-						<div class=" self-center">{$i18n.t('Images')}</div>
-					</button>
-				{/if}
-
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'chats'
@@ -325,15 +272,6 @@
 							toast.success($i18n.t('Settings saved successfully!'));
 						}}
 					/>
-				{:else if selectedTab === 'models'}
-					<Models {getModels} />
-				{:else if selectedTab === 'connections'}
-					<Connections
-						{getModels}
-						on:save={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
 				{:else if selectedTab === 'interface'}
 					<Interface
 						{saveSettings}
@@ -355,13 +293,6 @@
 							toast.success($i18n.t('Settings saved successfully!'));
 						}}
 					/>
-				{:else if selectedTab === 'images'}
-					<Images
-						{saveSettings}
-						on:save={() => {
-							toast.success($i18n.t('Settings saved successfully!'));
-						}}
-					/>
 				{:else if selectedTab === 'chats'}
 					<Chats {saveSettings} />
 				{:else if selectedTab === 'account'}

+ 1 - 1
src/lib/components/common/Selector.svelte

@@ -48,7 +48,7 @@
 		<ChevronDown className="absolute end-2 top-1/2 -translate-y-[45%] size-3.5" strokeWidth="2.5" />
 	</Select.Trigger>
 	<Select.Content
-		class="w-full rounded-lg  bg-white dark:bg-gray-900 dark:text-white shadow-lg border border-gray-300/30 dark:border-gray-700/50  outline-none"
+		class="w-full rounded-lg  bg-white dark:bg-gray-900 dark:text-white shadow-lg border border-gray-300/30 dark:border-gray-850/50  outline-none"
 		transition={flyAndScale}
 		sideOffset={4}
 	>

+ 1 - 1
src/lib/components/documents/Settings/QueryParams.svelte

@@ -95,7 +95,7 @@
 					)}
 				</div>
 
-				<hr class=" dark:border-gray-700 my-3" />
+				<hr class=" dark:border-gray-850 my-3" />
 			{/if}
 
 			<div>

+ 2 - 2
src/lib/components/documents/Settings/WebParams.svelte

@@ -68,10 +68,10 @@
 						<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={webConfig.search.engine}
-							placeholder="Select a engine"
+							placeholder={$i18n.t('Select a engine')}
 							required
 						>
-							<option disabled selected value="">Select a engine</option>
+							<option disabled selected value="">{$i18n.t('Select a engine')}</option>
 							{#each webSearchEngines as engine}
 								<option value={engine}>{engine}</option>
 							{/each}

+ 20 - 0
src/lib/components/icons/Headphone.svelte

@@ -0,0 +1,20 @@
+<script lang="ts">
+	export let className = 'w-4 h-4';
+	export let strokeWidth = '0';
+</script>
+
+<svg
+	aria-hidden="true"
+	xmlns="http://www.w3.org/2000/svg"
+	fill="currentColor"
+	viewBox="0 0 24 24"
+	stroke-width={strokeWidth}
+	stroke="currentColor"
+	class={className}
+>
+	<path
+		fill-rule="evenodd"
+		d="M12 5a7 7 0 0 0-7 7v1.17c.313-.11.65-.17 1-.17h2a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H6a3 3 0 0 1-3-3v-6a9 9 0 0 1 18 0v6a3 3 0 0 1-3 3h-2a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h2c.35 0 .687.06 1 .17V12a7 7 0 0 0-7-7Z"
+		clip-rule="evenodd"
+	/>
+</svg>

+ 7 - 4
src/lib/components/layout/Overlay/AccountPending.svelte

@@ -21,17 +21,20 @@
 		<div class="m-auto pb-10 flex flex-col justify-center">
 			<div class="max-w-md">
 				<div class="text-center dark:text-white text-2xl font-medium z-50">
-					Account Activation Pending<br /> Contact Admin for WebUI Access
+					{$i18n.t('Account Activation Pending')}<br />
+					{$i18n.t('Contact Admin for WebUI Access')}
 				</div>
 
 				<div class=" mt-4 text-center text-sm dark:text-gray-200 w-full">
-					Your account status is currently pending activation.<br /> To access the WebUI, please reach
-					out to the administrator. Admins can manage user statuses from the Admin Panel.
+					{$i18n.t('Your account status is currently pending activation.')}<br />
+					{$i18n.t(
+						'To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.'
+					)}
 				</div>
 
 				{#if adminDetails}
 					<div class="mt-4 text-sm font-medium text-center">
-						<div>Admin: {adminDetails.name} ({adminDetails.email})</div>
+						<div>{$i18n.t('Admin')}: {adminDetails.name} ({adminDetails.email})</div>
 					</div>
 				{/if}
 

+ 4 - 0
src/lib/components/layout/Sidebar.svelte

@@ -325,6 +325,10 @@
 					on:click={() => {
 						selectedChatId = null;
 						chatId.set('');
+
+						if ($mobile) {
+							showSidebar.set(false);
+						}
 					}}
 					draggable="false"
 				>

+ 1 - 1
src/lib/components/layout/Sidebar/UserMenu.svelte

@@ -145,7 +145,7 @@
 
 				<Tooltip
 					content={$USAGE_POOL && $USAGE_POOL.length > 0
-						? `Running: ${$USAGE_POOL.join(', ')} ✨`
+						? `${$i18n.t('Running')}: ${$USAGE_POOL.join(', ')} ✨`
 						: ''}
 				>
 					<div class="flex rounded-md py-1.5 px-3 text-xs gap-2.5 items-center">

+ 9 - 34
src/lib/components/workspace/Documents.svelte

@@ -4,7 +4,7 @@
 	const { saveAs } = fileSaver;
 
 	import { onMount, getContext } from 'svelte';
-	import { WEBUI_NAME, documents } from '$lib/stores';
+	import { WEBUI_NAME, documents, showSidebar } from '$lib/stores';
 	import { createNewDoc, deleteDocByName, getDocs } from '$lib/apis/documents';
 
 	import { SUPPORTED_FILE_TYPE, SUPPORTED_FILE_EXTENSIONS } from '$lib/constants';
@@ -15,7 +15,6 @@
 
 	import EditDocModal from '$lib/components/documents/EditDocModal.svelte';
 	import AddFilesPlaceholder from '$lib/components/AddFilesPlaceholder.svelte';
-	import SettingsModal from '$lib/components/documents/SettingsModal.svelte';
 	import AddDocModal from '$lib/components/documents/AddDocModal.svelte';
 
 	const i18n = getContext('i18n');
@@ -158,12 +157,14 @@
 
 {#if dragged}
 	<div
-		class="fixed w-full h-full flex z-50 touch-none pointer-events-none"
+		class="fixed {$showSidebar
+			? 'left-0 md:left-[260px] md:w-[calc(100%-260px)]'
+			: 'left-0'}  w-full h-full flex z-50 touch-none pointer-events-none"
 		id="dropzone"
 		role="region"
 		aria-label="Drag and Drop Container"
 	>
-		<div class="absolute rounded-xl w-full h-full backdrop-blur bg-gray-800/40 flex justify-center">
+		<div class="absolute w-full h-full backdrop-blur bg-gray-800/40 flex justify-center">
 			<div class="m-auto pt-64 flex flex-col justify-center">
 				<div class="max-w-md">
 					<AddFilesPlaceholder>
@@ -183,39 +184,9 @@
 
 <AddDocModal bind:show={showAddDocModal} />
 
-<SettingsModal bind:show={showSettingsModal} />
-
 <div class="mb-3">
 	<div class="flex justify-between items-center">
 		<div class=" text-lg font-semibold self-center">{$i18n.t('Documents')}</div>
-
-		<div>
-			<button
-				class="flex items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition"
-				type="button"
-				on:click={() => {
-					showSettingsModal = !showSettingsModal;
-				}}
-			>
-				<svg
-					xmlns="http://www.w3.org/2000/svg"
-					viewBox="0 0 16 16"
-					fill="currentColor"
-					class="w-4 h-4"
-				>
-					<path
-						fill-rule="evenodd"
-						d="M6.955 1.45A.5.5 0 0 1 7.452 1h1.096a.5.5 0 0 1 .497.45l.17 1.699c.484.12.94.312 1.356.562l1.321-1.081a.5.5 0 0 1 .67.033l.774.775a.5.5 0 0 1 .034.67l-1.08 1.32c.25.417.44.873.561 1.357l1.699.17a.5.5 0 0 1 .45.497v1.096a.5.5 0 0 1-.45.497l-1.699.17c-.12.484-.312.94-.562 1.356l1.082 1.322a.5.5 0 0 1-.034.67l-.774.774a.5.5 0 0 1-.67.033l-1.322-1.08c-.416.25-.872.44-1.356.561l-.17 1.699a.5.5 0 0 1-.497.45H7.452a.5.5 0 0 1-.497-.45l-.17-1.699a4.973 4.973 0 0 1-1.356-.562L4.108 13.37a.5.5 0 0 1-.67-.033l-.774-.775a.5.5 0 0 1-.034-.67l1.08-1.32a4.971 4.971 0 0 1-.561-1.357l-1.699-.17A.5.5 0 0 1 1 8.548V7.452a.5.5 0 0 1 .45-.497l1.699-.17c.12-.484.312-.94.562-1.356L2.629 4.107a.5.5 0 0 1 .034-.67l.774-.774a.5.5 0 0 1 .67-.033L5.43 3.71a4.97 4.97 0 0 1 1.356-.561l.17-1.699ZM6 8c0 .538.212 1.026.558 1.385l.057.057a2 2 0 0 0 2.828-2.828l-.058-.056A2 2 0 0 0 6 8Z"
-						clip-rule="evenodd"
-					/>
-				</svg>
-
-				<div class=" text-xs">{$i18n.t('Document Settings')}</div>
-			</button>
-		</div>
-	</div>
-	<div class=" text-gray-500 text-xs mt-1">
-		ⓘ {$i18n.t("Use '#' in the prompt input to load and select your documents.")}
 	</div>
 </div>
 
@@ -520,6 +491,10 @@
 	{/each}
 </div>
 
+<div class=" text-gray-500 text-xs mt-1">
+	ⓘ {$i18n.t("Use '#' in the prompt input to load and select your documents.")}
+</div>
+
 <div class=" flex justify-end w-full mb-2">
 	<div class="flex space-x-2">
 		<input

+ 13 - 10
src/lib/components/workspace/Models.svelte

@@ -71,16 +71,19 @@
 		const url = 'https://openwebui.com';
 
 		const tab = await window.open(`${url}/models/create`, '_blank');
-		window.addEventListener(
-			'message',
-			(event) => {
-				if (event.origin !== url) return;
-				if (event.data === 'loaded') {
-					tab.postMessage(JSON.stringify(model), '*');
-				}
-			},
-			false
-		);
+
+		// Define the event handler function
+		const messageHandler = (event) => {
+			if (event.origin !== url) return;
+			if (event.data === 'loaded') {
+				tab.postMessage(JSON.stringify(model), '*');
+
+				// Remove the event listener after handling the message
+				window.removeEventListener('message', messageHandler);
+			}
+		};
+
+		window.addEventListener('message', messageHandler, false);
 	};
 
 	const hideModelHandler = async (model) => {

+ 106 - 0
src/lib/components/workspace/Models/Knowledge.svelte

@@ -0,0 +1,106 @@
+<script lang="ts">
+	import { getContext } from 'svelte';
+	import Selector from './Knowledge/Selector.svelte';
+
+	export let knowledge = [];
+
+	const i18n = getContext('i18n');
+</script>
+
+<div>
+	<div class="flex w-full justify-between mb-1">
+		<div class=" self-center text-sm font-semibold">{$i18n.t('Knowledge')}</div>
+	</div>
+
+	<div class=" text-xs dark:text-gray-500">
+		To add documents here, upload them to the "Documents" workspace first.
+	</div>
+
+	<div class="flex flex-col">
+		{#if knowledge.length > 0}
+			<div class=" flex items-center gap-2 mt-2">
+				{#each knowledge as file, fileIdx}
+					<div class=" relative group">
+						<div
+							class="h-16 w-[15rem] flex items-center space-x-3 px-2.5 dark:bg-gray-600 rounded-xl border border-gray-200 dark:border-none"
+						>
+							<div class="p-2.5 bg-red-400 text-white rounded-lg">
+								{#if (file?.type ?? 'doc') === 'doc'}
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										class="size-6"
+									>
+										<path
+											fill-rule="evenodd"
+											d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625ZM7.5 15a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 7.5 15Zm.75 2.25a.75.75 0 0 0 0 1.5H12a.75.75 0 0 0 0-1.5H8.25Z"
+											clip-rule="evenodd"
+										/>
+										<path
+											d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z"
+										/>
+									</svg>
+								{:else if file.type === 'collection'}
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										class="size-6"
+									>
+										<path
+											d="M7.5 3.375c0-1.036.84-1.875 1.875-1.875h.375a3.75 3.75 0 0 1 3.75 3.75v1.875C13.5 8.161 14.34 9 15.375 9h1.875A3.75 3.75 0 0 1 21 12.75v3.375C21 17.16 20.16 18 19.125 18h-9.75A1.875 1.875 0 0 1 7.5 16.125V3.375Z"
+										/>
+										<path
+											d="M15 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 17.25 7.5h-1.875A.375.375 0 0 1 15 7.125V5.25ZM4.875 6H6v10.125A3.375 3.375 0 0 0 9.375 19.5H16.5v1.125c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625V7.875C3 6.839 3.84 6 4.875 6Z"
+										/>
+									</svg>
+								{/if}
+							</div>
+
+							<div class="flex flex-col justify-center -space-y-0.5">
+								<div class=" dark:text-gray-100 text-sm font-medium line-clamp-1">
+									{file?.title ?? `#${file.name}`}
+								</div>
+
+								<div class=" text-gray-500 text-sm">{$i18n.t(file?.type ?? 'Document')}</div>
+							</div>
+						</div>
+
+						<div class=" absolute -top-1 -right-1">
+							<button
+								class=" bg-gray-400 text-white border border-white rounded-full group-hover:visible invisible transition"
+								type="button"
+								on:click={() => {
+									knowledge.splice(fileIdx, 1);
+									knowledge = knowledge;
+								}}
+							>
+								<svg
+									xmlns="http://www.w3.org/2000/svg"
+									viewBox="0 0 20 20"
+									fill="currentColor"
+									class="w-4 h-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"
+									/>
+								</svg>
+							</button>
+						</div>
+					</div>
+				{/each}
+			</div>
+		{/if}
+
+		<div class="flex flex-wrap text-sm font-medium gap-1.5 mt-2">
+			<Selector bind:knowledge>
+				<button
+					class=" px-3.5 py-1.5 font-medium hover:bg-black/5 dark:hover:bg-white/5 outline outline-1 outline-gray-300 dark:outline-gray-800 rounded-3xl"
+					type="button">Select Documents</button
+				>
+			</Selector>
+		</div>
+		<!-- {knowledge} -->
+	</div>
+</div>

+ 138 - 0
src/lib/components/workspace/Models/Knowledge/Selector.svelte

@@ -0,0 +1,138 @@
+<script lang="ts">
+	import { DropdownMenu } from 'bits-ui';
+
+	import { documents } from '$lib/stores';
+	import { flyAndScale } from '$lib/utils/transitions';
+
+	import Dropdown from '$lib/components/common/Dropdown.svelte';
+	import { onMount, getContext } from 'svelte';
+
+	const i18n = getContext('i18n');
+
+	export let onClose: Function = () => {};
+
+	export let knowledge = [];
+
+	let items = [];
+
+	onMount(() => {
+		let collections = [
+			...($documents.length > 0
+				? [
+						{
+							name: 'All Documents',
+							type: 'collection',
+							title: $i18n.t('All Documents'),
+							collection_names: $documents.map((doc) => doc.collection_name)
+						}
+				  ]
+				: []),
+			...$documents
+				.reduce((a, e, i, arr) => {
+					return [...new Set([...a, ...(e?.content?.tags ?? []).map((tag) => tag.name)])];
+				}, [])
+				.map((tag) => ({
+					name: tag,
+					type: 'collection',
+					collection_names: $documents
+						.filter((doc) => (doc?.content?.tags ?? []).map((tag) => tag.name).includes(tag))
+						.map((doc) => doc.collection_name)
+				}))
+		];
+
+		items = [...collections, ...$documents];
+	});
+</script>
+
+<Dropdown
+	on:change={(e) => {
+		if (e.detail === false) {
+			onClose();
+		}
+	}}
+>
+	<slot />
+
+	<div slot="content">
+		<DropdownMenu.Content
+			class="w-full max-w-[300px]  rounded-lg px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
+			sideOffset={8}
+			side="bottom"
+			align="start"
+			transition={flyAndScale}
+		>
+			<div class="max-h-[10rem] overflow-y-scroll">
+				{#if items.length === 0}
+					<div class="text-center text-sm text-gray-500 dark:text-gray-400">
+						{$i18n.t('No documents found')}
+					</div>
+				{:else}
+					{#each items as item}
+						<DropdownMenu.Item
+							class="flex gap-2.5 items-center px-3 py-2 text-sm  cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+							on:click={() => {
+								if (!knowledge.find((k) => k.name === item.name)) {
+									knowledge = [
+										...knowledge,
+										{
+											...item,
+											type: item?.type ?? 'doc'
+										}
+									];
+								}
+							}}
+						>
+							<div class="flex self-start">
+								{#if (item?.type ?? 'doc') === 'doc'}
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										class="w-4"
+									>
+										<path
+											fill-rule="evenodd"
+											d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625ZM7.5 15a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 7.5 15Zm.75 2.25a.75.75 0 0 0 0 1.5H12a.75.75 0 0 0 0-1.5H8.25Z"
+											clip-rule="evenodd"
+										/>
+										<path
+											d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z"
+										/>
+									</svg>
+								{:else if item.type === 'collection'}
+									<svg
+										xmlns="http://www.w3.org/2000/svg"
+										viewBox="0 0 24 24"
+										fill="currentColor"
+										class="size-4"
+									>
+										<path
+											d="M7.5 3.375c0-1.036.84-1.875 1.875-1.875h.375a3.75 3.75 0 0 1 3.75 3.75v1.875C13.5 8.161 14.34 9 15.375 9h1.875A3.75 3.75 0 0 1 21 12.75v3.375C21 17.16 20.16 18 19.125 18h-9.75A1.875 1.875 0 0 1 7.5 16.125V3.375Z"
+										/>
+										<path
+											d="M15 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 17.25 7.5h-1.875A.375.375 0 0 1 15 7.125V5.25ZM4.875 6H6v10.125A3.375 3.375 0 0 0 9.375 19.5H16.5v1.125c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625V7.875C3 6.839 3.84 6 4.875 6Z"
+										/>
+									</svg>
+								{/if}
+							</div>
+
+							<div class="flex items-center">
+								<div class="flex flex-col">
+									<div
+										class=" w-fit text-xs font-black px-1 rounded uppercase line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200"
+									>
+										{item?.type ?? 'Document'}
+									</div>
+
+									<div class="line-clamp-1 font-medium pr-0.5">
+										{item.name}
+									</div>
+								</div>
+							</div>
+						</DropdownMenu.Item>
+					{/each}
+				{/if}
+			</div>
+		</DropdownMenu.Content>
+	</div>
+</Dropdown>

+ 8 - 18
src/lib/components/workspace/Playground.svelte

@@ -80,8 +80,6 @@
 					if (stopResponseFlag) {
 						controller.abort('User: Stop Response');
 					}
-
-					currentRequestId = null;
 					break;
 				}
 
@@ -97,11 +95,7 @@
 								let data = JSON.parse(line.replace(/^data: /, ''));
 								console.log(data);
 
-								if ('request_id' in data) {
-									currentRequestId = data.request_id;
-								} else {
-									text += data.choices[0].delta.content ?? '';
-								}
+								text += data.choices[0].delta.content ?? '';
 							}
 						}
 					}
@@ -178,21 +172,17 @@
 								let data = JSON.parse(line.replace(/^data: /, ''));
 								console.log(data);
 
-								if ('request_id' in data) {
-									currentRequestId = data.request_id;
+								if (responseMessage.content == '' && data.choices[0].delta.content == '\n') {
+									continue;
 								} else {
-									if (responseMessage.content == '' && data.choices[0].delta.content == '\n') {
-										continue;
-									} else {
-										textareaElement.style.height = textareaElement.scrollHeight + 'px';
+									textareaElement.style.height = textareaElement.scrollHeight + 'px';
 
-										responseMessage.content += data.choices[0].delta.content ?? '';
-										messages = messages;
+									responseMessage.content += data.choices[0].delta.content ?? '';
+									messages = messages;
 
-										textareaElement.style.height = textareaElement.scrollHeight + 'px';
+									textareaElement.style.height = textareaElement.scrollHeight + 'px';
 
-										await tick();
-									}
+									await tick();
 								}
 							}
 						}

+ 2 - 1
src/lib/constants.ts

@@ -89,7 +89,8 @@ export const SUPPORTED_FILE_EXTENSIONS = [
 	'xls',
 	'xlsx',
 	'pptx',
-	'ppt'
+	'ppt',
+	'msg'
 ];
 
 // Source: https://kit.svelte.dev/docs/modules#$env-static-public

+ 38 - 8
src/lib/i18n/locales/ar-BH/translation.json

@@ -12,6 +12,7 @@
 	"a user": "مستخدم",
 	"About": "عن",
 	"Account": "الحساب",
+	"Account Activation Pending": "",
 	"Accurate information": "معلومات دقيقة",
 	"Active Users": "",
 	"Add": "أضف",
@@ -29,6 +30,7 @@
 	"Add User": "اضافة مستخدم",
 	"Adjusting these settings will apply changes universally to all users.": "سيؤدي ضبط هذه الإعدادات إلى تطبيق التغييرات بشكل عام على كافة المستخدمين",
 	"admin": "المشرف",
+	"Admin": "",
 	"Admin Panel": "لوحة التحكم",
 	"Admin Settings": "اعدادات المشرف",
 	"Advanced Parameters": "التعليمات المتقدمة",
@@ -59,7 +61,6 @@
 	"Audio": "صوتي",
 	"August": "أغسطس",
 	"Auto-playback response": "استجابة التشغيل التلقائي",
-	"Auto-send input after 3 sec.": "إرسال تلقائي للإدخال بعد 3 ثواني.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 الرابط الرئيسي",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 الرابط مطلوب",
 	"available!": "متاح",
@@ -71,6 +72,9 @@
 	"Being lazy": "كون كسول",
 	"Brave Search API Key": "مفتاح واجهة برمجة تطبيقات البحث الشجاع",
 	"Bypass SSL verification for Websites": "تجاوز التحقق من SSL للموقع",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "اللغاء",
 	"Capabilities": "قدرات",
 	"Change Password": "تغير الباسورد",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk المتغيرات",
 	"Chunk Size": "Chunk حجم",
 	"Citation": "اقتباس",
+	"Clear memory": "",
 	"Click here for help.": "أضغط هنا للمساعدة",
 	"Click here to": "أضغط هنا الانتقال",
 	"Click here to select": "أضغط هنا للاختيار",
 	"Click here to select a csv file.": "أضغط هنا للاختيار ملف csv",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "انقر هنا لاختيار المستندات",
 	"click here.": "أضغط هنا",
 	"Click on the user role button to change a user's role.": "أضغط على أسم الصلاحيات لتغيرها للمستخدم",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "الطلبات المتزامنة",
 	"Confirm Password": "تأكيد كلمة المرور",
 	"Connections": "اتصالات",
+	"Contact Admin for WebUI Access": "",
 	"Content": "الاتصال",
 	"Context Length": "طول السياق",
 	"Continue Response": "متابعة الرد",
-	"Conversation Mode": "وضع المحادثة",
 	"Copied shared chat URL to clipboard!": "تم نسخ عنوان URL للدردشة المشتركة إلى الحافظة",
 	"Copy": "نسخ",
 	"Copy last code block": "انسخ كتلة التعليمات البرمجية الأخيرة",
 	"Copy last response": "انسخ الرد الأخير",
 	"Copy Link": "أنسخ الرابط",
 	"Copying to clipboard was successful!": "تم النسخ إلى الحافظة بنجاح",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "قم بإنشاء عبارة موجزة مكونة من 3-5 كلمات كرأس للاستعلام التالي، مع الالتزام الصارم بالحد الأقصى لعدد الكلمات الذي يتراوح بين 3-5 كلمات وتجنب استخدام الكلمة 'عنوان':",
 	"Create a model": "إنشاء نموذج",
 	"Create Account": "إنشاء حساب",
 	"Create new key": "عمل مفتاح جديد",
@@ -127,12 +132,12 @@
 	"Custom": "مخصص",
 	"Customize models for a specific purpose": "تخصيص النماذج لغرض معين",
 	"Dark": "مظلم",
+	"Dashboard": "",
 	"Database": "قاعدة البيانات",
 	"December": "ديسمبر",
 	"Default": "الإفتراضي",
 	"Default (Automatic1111)": "(Automatic1111) الإفتراضي",
 	"Default (SentenceTransformers)": "(SentenceTransformers) الإفتراضي",
-	"Default (Web API)": "(Web API) الإفتراضي",
 	"Default Model": "النموذج الافتراضي",
 	"Default model updated": "الإفتراضي تحديث الموديل",
 	"Default Prompt Suggestions": "الإفتراضي Prompt الاقتراحات",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "اكتشاف موجه",
 	"Discover, download, and explore custom prompts": "اكتشاف وتنزيل واستكشاف المطالبات المخصصة",
 	"Discover, download, and explore model presets": "اكتشاف وتنزيل واستكشاف الإعدادات المسبقة للنموذج",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "اعرض اسم المستخدم بدلاً منك في الدردشة",
 	"Document": "المستند",
 	"Document Settings": "أعدادات المستند",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "تصدير وثائق الخرائط",
 	"Export Models": "نماذج التصدير",
 	"Export Prompts": "مطالبات التصدير",
+	"External Models": "",
 	"Failed to create API Key.": "فشل في إنشاء مفتاح API.",
 	"Failed to read clipboard contents": "فشل في قراءة محتويات الحافظة",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "عقوبة التردد",
 	"General": "عام",
 	"General Settings": "الاعدادات العامة",
+	"Generate Image": "",
 	"Generating search query": "إنشاء استعلام بحث",
 	"Generation Info": "معلومات الجيل",
 	"Good Response": "استجابة جيدة",
@@ -252,6 +260,7 @@
 	"Info": "معلومات",
 	"Input commands": "إدخال الأوامر",
 	"Install from Github URL": "التثبيت من عنوان URL لجيثب",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "واجهه المستخدم",
 	"Invalid Tag": "تاق غير صالحة",
 	"January": "يناير",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT Token",
 	"Keep Alive": "Keep Alive",
 	"Keyboard shortcuts": "اختصارات لوحة المفاتيح",
+	"Knowledge": "",
 	"Language": "اللغة",
 	"Last Active": "آخر نشاط",
 	"Light": "فاتح",
-	"Listening...": "جاري الاستماع",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "يمكن أن تصدر بعض الأخطاء. لذلك يجب التحقق من المعلومات المهمة",
+	"Local Models": "",
 	"LTR": "من جهة اليسار إلى اليمين",
 	"Made by OpenWebUI Community": "OpenWebUI تم إنشاؤه بواسطة مجتمع ",
 	"Make sure to enclose them with": "تأكد من إرفاقها",
+	"Manage": "",
 	"Manage Models": "إدارة النماذج",
 	"Manage Ollama Models": "Ollama إدارة موديلات ",
 	"Manage Pipelines": "إدارة خطوط الأنابيب",
@@ -307,6 +319,7 @@
 	"Name your model": "قم بتسمية النموذج الخاص بك",
 	"New Chat": "دردشة جديدة",
 	"New Password": "كلمة المرور الجديدة",
+	"No documents found": "",
 	"No results found": "لا توجد نتايج",
 	"No search query generated": "لم يتم إنشاء استعلام بحث",
 	"No source available": "لا يوجد مصدر متاح",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "أولاما API",
 	"Ollama API disabled": "أولاما API معطلة",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama الاصدار",
 	"On": "تشغيل",
 	"Only": "فقط",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF ملف (.pdf)",
 	"PDF Extract Images (OCR)": "PDF أستخرج الصور (OCR)",
 	"pending": "قيد الانتظار",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "{{error}} تم رفض الإذن عند الوصول إلى الميكروفون ",
 	"Personalization": "التخصيص",
 	"Pipelines": "خطوط الانابيب",
@@ -367,6 +383,7 @@
 	"Read Aloud": "أقراء لي",
 	"Record voice": "سجل صوت",
 	"Redirecting you to OpenWebUI Community": "OpenWebUI إعادة توجيهك إلى مجتمع ",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "رفض عندما لا ينبغي أن يكون",
 	"Regenerate": "تجديد",
 	"Release Notes": "ملاحظات الإصدار",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "من اليمين إلى اليسار",
+	"Running": "",
 	"Save": "حفظ",
 	"Save & Create": "حفظ وإنشاء",
 	"Save & Update": "حفظ وتحديث",
@@ -398,6 +416,8 @@
 	"Search Documents": "البحث المستندات",
 	"Search Models": "نماذج البحث",
 	"Search Prompts": "أبحث حث",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "عدد نتائج البحث",
 	"Searched {{count}} sites_zero": "تم البحث في {{count}} sites_zero",
 	"Searched {{count}} sites_one": "تم البحث في {{count}} sites_one",
@@ -411,12 +431,14 @@
 	"See what's new": "ما الجديد",
 	"Seed": "Seed",
 	"Select a base model": "حدد نموذجا أساسيا",
+	"Select a engine": "",
 	"Select a mode": "أختار موديل",
 	"Select a model": "أختار الموديل",
 	"Select a pipeline": "حدد مسارا",
 	"Select a pipeline url": "حدد عنوان URL لخط الأنابيب",
 	"Select an Ollama instance": "أختار سيرفر ",
 	"Select model": " أختار موديل",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "النموذج (النماذج) المحددة لا تدعم مدخلات الصور",
 	"Send": "تم",
 	"Send a Message": "يُرجى إدخال طلبك هنا",
@@ -429,7 +451,6 @@
 	"Set Default Model": "تفعيد الموديل الافتراضي",
 	"Set embedding model (e.g. {{model}})": "ضبط نموذج المتجهات (على سبيل المثال: {{model}})",
 	"Set Image Size": "حجم الصورة",
-	"Set Model": "ضبط النموذج",
 	"Set reranking model (e.g. {{model}})": "ضبط نموذج إعادة الترتيب (على سبيل المثال: {{model}})",
 	"Set Steps": "ضبط الخطوات",
 	"Set Task Model": "تعيين نموذج المهمة",
@@ -453,8 +474,8 @@
 	"Source": "المصدر",
 	"Speech recognition error: {{error}}": "{{error}} خطأ في التعرف على الكلام",
 	"Speech-to-Text Engine": "محرك تحويل الكلام إلى نص",
-	"SpeechRecognition API is not supported in this browser.": "API SpeechRecognition غير مدعومة في هذا المتصفح.",
 	"Stop Sequence": "وقف التسلسل",
+	"STT Model": "",
 	"STT Settings": "STT اعدادات",
 	"Submit": "إرسال",
 	"Subtitle (e.g. about the Roman Empire)": "(e.g. about the Roman Empire) الترجمة",
@@ -473,7 +494,9 @@
 	"Thanks for your feedback!": "شكرا لملاحظاتك!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "يجب أن تكون النتيجة قيمة تتراوح بين 0.0 (0%) و1.0 (100%).",
 	"Theme": "الثيم",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "وهذا يضمن حفظ محادثاتك القيمة بشكل آمن في قاعدة بياناتك الخلفية. شكرًا لك!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "لا تتم مزامنة هذا الإعداد عبر المتصفحات أو الأجهزة.",
 	"Thorough explanation": "شرح شامل",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "ملاحضة: قم بتحديث عدة فتحات متغيرة على التوالي عن طريق الضغط على مفتاح tab في مدخلات الدردشة بعد كل استبدال.",
@@ -485,6 +508,7 @@
 	"to": "الى",
 	"To access the available model names for downloading,": "للوصول إلى أسماء الموديلات المتاحة للتنزيل،",
 	"To access the GGUF models available for downloading,": "للوصول إلى الموديلات GGUF المتاحة للتنزيل،",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "الى كتابة المحادثه",
 	"Today": "اليوم",
 	"Toggle settings": "فتح وأغلاق الاعدادات",
@@ -492,7 +516,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "هل تواجه مشكلة في الوصول",
+	"TTS Model": "",
 	"TTS Settings": "TTS اعدادات",
+	"TTS Voice": "",
 	"Type": "نوع",
 	"Type Hugging Face Resolve (Download) URL": "اكتب عنوان URL لحل مشكلة الوجه (تنزيل).",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "{{provider}}خطاء أوه! حدثت مشكلة في الاتصال بـ ",
@@ -501,6 +527,7 @@
 	"Update password": "تحديث كلمة المرور",
 	"Upload a GGUF model": "GGUF رفع موديل نوع",
 	"Upload Files": "تحميل الملفات",
+	"Upload Pipeline": "",
 	"Upload Progress": "جاري التحميل",
 	"URL Mode": "رابط الموديل",
 	"Use '#' in the prompt input to load and select your documents.": "أستخدم '#' في المحادثة لربطهامن المستندات",
@@ -519,6 +546,7 @@
 	"Warning": "تحذير",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "تحذير: إذا قمت بتحديث أو تغيير نموذج التضمين الخاص بك، فستحتاج إلى إعادة استيراد كافة المستندات.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web تحميل اعدادات",
 	"Web Params": "Web تحميل اعدادات",
 	"Web Search": "بحث الويب",
@@ -529,18 +557,20 @@
 	"WebUI will make requests to": "سوف يقوم WebUI بتقديم طلبات ل",
 	"What’s New in": "ما هو الجديد",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "عند إيقاف تشغيل السجل، لن تظهر الدردشات الجديدة على هذا المتصفح في سجلك على أي من أجهزتك.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "مساحة العمل",
 	"Write a prompt suggestion (e.g. Who are you?)": "اكتب اقتراحًا سريعًا (على سبيل المثال، من أنت؟)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "اكتب ملخصًا في 50 كلمة يلخص [الموضوع أو الكلمة الرئيسية]",
 	"Yesterday": "أمس",
 	"You": "انت",
+	"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 clone a base model": "لا يمكنك استنساخ نموذج أساسي",
 	"You have no archived conversations.": "لا تملك محادثات محفوظه",
 	"You have shared this chat": "تم مشاركة هذه المحادثة",
 	"You're a helpful assistant.": "مساعدك المفيد هنا",
 	"You're now logged in.": "لقد قمت الآن بتسجيل الدخول.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube تحميل اعدادات"
 }

+ 38 - 8
src/lib/i18n/locales/bg-BG/translation.json

@@ -12,6 +12,7 @@
 	"a user": "потребител",
 	"About": "Относно",
 	"Account": "Акаунт",
+	"Account Activation Pending": "",
 	"Accurate information": "Точни информация",
 	"Active Users": "",
 	"Add": "Добавяне",
@@ -29,6 +30,7 @@
 	"Add User": "Добавяне на потребител",
 	"Adjusting these settings will apply changes universally to all users.": "При промяна на тези настройки промените се прилагат за всички потребители.",
 	"admin": "админ",
+	"Admin": "",
 	"Admin Panel": "Панел на Администратор",
 	"Admin Settings": "Настройки на Администратор",
 	"Advanced Parameters": "Разширени Параметри",
@@ -59,7 +61,6 @@
 	"Audio": "Аудио",
 	"August": "Август",
 	"Auto-playback response": "Аувтоматично възпроизвеждане на Отговора",
-	"Auto-send input after 3 sec.": "Аувтоматично изпращане на входа след 3 сек.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Базов URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Базов URL е задължителен.",
 	"available!": "наличен!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Да бъдеш мързелив",
 	"Brave Search API Key": "Смел ключ за API за търсене",
 	"Bypass SSL verification for Websites": "Изключване на SSL проверката за сайтове",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Отказ",
 	"Capabilities": "Възможности",
 	"Change Password": "Промяна на Парола",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Citation": "Цитат",
+	"Clear memory": "",
 	"Click here for help.": "Натиснете тук за помощ.",
 	"Click here to": "Натиснете тук за",
 	"Click here to select": "Натиснете тук, за да изберете",
 	"Click here to select a csv file.": "Натиснете тук, за да изберете csv файл.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Натиснете тук, за да изберете документи.",
 	"click here.": "натиснете тук.",
 	"Click on the user role button to change a user's role.": "Натиснете върху бутона за промяна на ролята на потребителя.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Едновременни искания",
 	"Confirm Password": "Потвърди Парола",
 	"Connections": "Връзки",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Съдържание",
 	"Context Length": "Дължина на Контекста",
 	"Continue Response": "Продължи отговора",
-	"Conversation Mode": "Режим на Чат",
 	"Copied shared chat URL to clipboard!": "Копирана е връзката за чат!",
 	"Copy": "Копирай",
 	"Copy last code block": "Копиране на последен код блок",
 	"Copy last response": "Копиране на последен отговор",
 	"Copy Link": "Копиране на връзка",
 	"Copying to clipboard was successful!": "Копирането в клипборда беше успешно!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Създайте кратка фраза от 3-5 думи като заглавие за следващото запитване, като стриктно спазвате ограничението от 3-5 думи и избягвате използването на думата 'заглавие':",
 	"Create a model": "Създаване на модел",
 	"Create Account": "Създаване на Акаунт",
 	"Create new key": "Създаване на нов ключ",
@@ -127,12 +132,12 @@
 	"Custom": "Персонализиран",
 	"Customize models for a specific purpose": "Персонализиране на модели за конкретна цел",
 	"Dark": "Тъмен",
+	"Dashboard": "",
 	"Database": "База данни",
 	"December": "Декември",
 	"Default": "По подразбиране",
 	"Default (Automatic1111)": "По подразбиране (Automatic1111)",
 	"Default (SentenceTransformers)": "По подразбиране (SentenceTransformers)",
-	"Default (Web API)": "По подразбиране (Web API)",
 	"Default Model": "Модел по подразбиране",
 	"Default model updated": "Моделът по подразбиране е обновен",
 	"Default Prompt Suggestions": "Промпт Предложения по подразбиране",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Откриване на промпт",
 	"Discover, download, and explore custom prompts": "Откриване, сваляне и преглед на персонализирани промптове",
 	"Discover, download, and explore model presets": "Откриване, сваляне и преглед на пресетове на модели",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Показване на потребителското име вместо Вие в чата",
 	"Document": "Документ",
 	"Document Settings": "Документ Настройки",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Експортване на документен мапинг",
 	"Export Models": "Експортиране на модели",
 	"Export Prompts": "Експортване на промптове",
+	"External Models": "",
 	"Failed to create API Key.": "Неуспешно създаване на API ключ.",
 	"Failed to read clipboard contents": "Грешка при четене на съдържанието от клипборда",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Наказание за честота",
 	"General": "Основни",
 	"General Settings": "Основни Настройки",
+	"Generate Image": "",
 	"Generating search query": "Генериране на заявка за търсене",
 	"Generation Info": "Информация за Генерация",
 	"Good Response": "Добра отговор",
@@ -252,6 +260,7 @@
 	"Info": "Информация",
 	"Input commands": "Въведете команди",
 	"Install from Github URL": "Инсталиране от URL адреса на Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Интерфейс",
 	"Invalid Tag": "Невалиден тег",
 	"January": "Януари",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT Token",
 	"Keep Alive": "Keep Alive",
 	"Keyboard shortcuts": "Клавиши за бърз достъп",
+	"Knowledge": "",
 	"Language": "Език",
 	"Last Active": "Последни активни",
 	"Light": "Светъл",
-	"Listening...": "Слушам...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs могат да правят грешки. Проверете важните данни.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Направено от OpenWebUI общността",
 	"Make sure to enclose them with": "Уверете се, че са заключени с",
+	"Manage": "",
 	"Manage Models": "Управление на Моделите",
 	"Manage Ollama Models": "Управление на Ollama Моделите",
 	"Manage Pipelines": "Управление на тръбопроводи",
@@ -307,6 +319,7 @@
 	"Name your model": "Дайте име на вашия модел",
 	"New Chat": "Нов чат",
 	"New Password": "Нова парола",
+	"No documents found": "",
 	"No results found": "Няма намерени резултати",
 	"No search query generated": "Не е генерирана заявка за търсене",
 	"No source available": "Няма наличен източник",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API деактивиран",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama Версия",
 	"On": "Вкл.",
 	"Only": "Само",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF документ (.pdf)",
 	"PDF Extract Images (OCR)": "PDF Extract Images (OCR)",
 	"pending": "в очакване",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}",
 	"Personalization": "Персонализация",
 	"Pipelines": "Тръбопроводи",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Прочети на Голос",
 	"Record voice": "Записване на глас",
 	"Redirecting you to OpenWebUI Community": "Пренасочване към OpenWebUI общността",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Отказано, когато не трябва да бъде",
 	"Regenerate": "Регенериране",
 	"Release Notes": "Бележки по изданието",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Запис",
 	"Save & Create": "Запис & Създаване",
 	"Save & Update": "Запис & Актуализиране",
@@ -398,6 +416,8 @@
 	"Search Documents": "Търси Документи",
 	"Search Models": "Търсене на модели",
 	"Search Prompts": "Търси Промптове",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Брой резултати от търсенето",
 	"Searched {{count}} sites_one": "Търси се в {{count}} sites_one",
 	"Searched {{count}} sites_other": "Търси се в {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "Виж какво е новото",
 	"Seed": "Seed",
 	"Select a base model": "Изберете базов модел",
+	"Select a engine": "",
 	"Select a mode": "Изберете режим",
 	"Select a model": "Изберете модел",
 	"Select a pipeline": "Изберете тръбопровод",
 	"Select a pipeline url": "Избор на URL адрес на канал",
 	"Select an Ollama instance": "Изберете Ollama инстанция",
 	"Select model": "Изберете модел",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Избраният(те) модел(и) не поддържа въвеждане на изображения",
 	"Send": "Изпрати",
 	"Send a Message": "Изпращане на Съобщение",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Задай Модел По Подразбиране",
 	"Set embedding model (e.g. {{model}})": "Задай embedding model (e.g. {{model}})",
 	"Set Image Size": "Задай Размер на Изображението",
-	"Set Model": "Задай Модел",
 	"Set reranking model (e.g. {{model}})": "Задай reranking model (e.g. {{model}})",
 	"Set Steps": "Задай Стъпки",
 	"Set Task Model": "Задаване на модел на задача",
@@ -449,8 +470,8 @@
 	"Source": "Източник",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}}",
 	"Speech-to-Text Engine": "Speech-to-Text Engine",
-	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API is not supported in this browser.",
 	"Stop Sequence": "Stop Sequence",
+	"STT Model": "",
 	"STT Settings": "STT Настройки",
 	"Submit": "Изпращане",
 	"Subtitle (e.g. about the Roman Empire)": "Подтитул (напр. за Римска империя)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "Благодарим ви за вашия отзив!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "The score should be a value between 0.0 (0%) and 1.0 (100%).",
 	"Theme": "Тема",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Това гарантира, че ценните ви разговори се запазват сигурно във вашата бекенд база данни. Благодарим ви!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Тази настройка не се синхронизира между браузъри или устройства.",
 	"Thorough explanation": "Това е подробно описание.",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Съвет: Актуализирайте няколко слота за променливи последователно, като натискате клавиша Tab в чат входа след всяка подмяна.",
@@ -481,6 +504,7 @@
 	"to": "в",
 	"To access the available model names for downloading,": "За да получите достъп до наличните имена на модели за изтегляне,",
 	"To access the GGUF models available for downloading,": "За да получите достъп до GGUF моделите, налични за изтегляне,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "към чат входа.",
 	"Today": "днес",
 	"Toggle settings": "Toggle settings",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Проблеми с достъпът до Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS Настройки",
+	"TTS Voice": "",
 	"Type": "Вид",
 	"Type Hugging Face Resolve (Download) URL": "Въведете Hugging Face Resolve (Download) URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "О, не! Възникна проблем при свързването с {{provider}}.",
@@ -497,6 +523,7 @@
 	"Update password": "Обновяване на парола",
 	"Upload a GGUF model": "Качване на GGUF модел",
 	"Upload Files": "Качване на файлове",
+	"Upload Pipeline": "",
 	"Upload Progress": "Прогрес на качването",
 	"URL Mode": "URL Mode",
 	"Use '#' in the prompt input to load and select your documents.": "Използвайте '#' във промпта за да заредите и изберете вашите документи.",
@@ -515,6 +542,7 @@
 	"Warning": "Предупреждение",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Предупреждение: Ако актуализирате или промените вашия модел за вграждане, трябва да повторите импортирането на всички документи.",
 	"Web": "Уеб",
+	"Web API": "",
 	"Web Loader Settings": "Настройки за зареждане на уеб",
 	"Web Params": "Параметри за уеб",
 	"Web Search": "Търсене в уеб",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI ще направи заявки към",
 	"What’s New in": "Какво е новото в",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Когато историята е изключена, нови чатове в този браузър ще не се показват в историята на никои от вашия профил.",
-	"Whisper (Local)": "Whisper (Локален)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Работно пространство",
 	"Write a prompt suggestion (e.g. Who are you?)": "Напиши предложение за промпт (напр. Кой сте вие?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Напиши описание в 50 знака, което описва [тема или ключова дума].",
 	"Yesterday": "вчера",
 	"You": "вие",
+	"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 clone a base model": "Не можете да клонирате базов модел",
 	"You have no archived conversations.": "Нямате архивирани разговори.",
 	"You have shared this chat": "Вие сте споделели този чат",
 	"You're a helpful assistant.": "Вие сте полезен асистент.",
 	"You're now logged in.": "Сега, вие влязохте в системата.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube Loader Settings"
 }

+ 38 - 8
src/lib/i18n/locales/bn-BD/translation.json

@@ -12,6 +12,7 @@
 	"a user": "একজন ব্যাবহারকারী",
 	"About": "সম্পর্কে",
 	"Account": "একাউন্ট",
+	"Account Activation Pending": "",
 	"Accurate information": "সঠিক তথ্য",
 	"Active Users": "",
 	"Add": "যোগ করুন",
@@ -29,6 +30,7 @@
 	"Add User": "ইউজার যোগ করুন",
 	"Adjusting these settings will apply changes universally to all users.": "এই সেটিংগুলো পরিবর্তন করলে তা সব ইউজারের উপরেই প্রয়োগ করা হবে",
 	"admin": "এডমিন",
+	"Admin": "",
 	"Admin Panel": "এডমিন প্যানেল",
 	"Admin Settings": "এডমিন সেটিংস",
 	"Advanced Parameters": "এডভান্সড প্যারামিটার্স",
@@ -59,7 +61,6 @@
 	"Audio": "অডিও",
 	"August": "আগস্ট",
 	"Auto-playback response": "রেসপন্স অটো-প্লেব্যাক",
-	"Auto-send input after 3 sec.": "৩ সেকেন্ড পর ইনপুট সংয়ক্রিয়ভাবে পাঠান",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 বেজ ইউআরএল",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 বেজ ইউআরএল আবশ্যক",
 	"available!": "উপলব্ধ!",
@@ -71,6 +72,9 @@
 	"Being lazy": "অলস হওয়া",
 	"Brave Search API Key": "সাহসী অনুসন্ধান API কী",
 	"Bypass SSL verification for Websites": "ওয়েবসাইটের জন্য SSL যাচাই বাতিল করুন",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "বাতিল",
 	"Capabilities": "সক্ষমতা",
 	"Change Password": "পাসওয়ার্ড পরিবর্তন করুন",
@@ -88,10 +92,12 @@
 	"Chunk Params": "চাঙ্ক প্যারামিটার্স",
 	"Chunk Size": "চাঙ্ক সাইজ",
 	"Citation": "উদ্ধৃতি",
+	"Clear memory": "",
 	"Click here for help.": "সাহায্যের জন্য এখানে ক্লিক করুন",
 	"Click here to": "এখানে ক্লিক করুন",
 	"Click here to select": "নির্বাচন করার জন্য এখানে ক্লিক করুন",
 	"Click here to select a csv file.": "একটি csv ফাইল নির্বাচন করার জন্য এখানে ক্লিক করুন",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "ডকুমেন্টগুলো নির্বাচন করার জন্য এখানে ক্লিক করুন",
 	"click here.": "এখানে ক্লিক করুন",
 	"Click on the user role button to change a user's role.": "ইউজারের পদবি পরিবর্তন করার জন্য ইউজারের পদবি বাটনে ক্লিক করুন",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "সমকালীন অনুরোধ",
 	"Confirm Password": "পাসওয়ার্ড নিশ্চিত করুন",
 	"Connections": "কানেকশনগুলো",
+	"Contact Admin for WebUI Access": "",
 	"Content": "বিষয়বস্তু",
 	"Context Length": "কনটেক্সটের দৈর্ঘ্য",
 	"Continue Response": "যাচাই করুন",
-	"Conversation Mode": "কথোপকথন মোড",
 	"Copied shared chat URL to clipboard!": "শেয়ারকৃত কথা-ব্যবহারের URL ক্লিপবোর্ডে কপি করা হয়েছে!",
 	"Copy": "অনুলিপি",
 	"Copy last code block": "সর্বশেষ কোড ব্লক কপি করুন",
 	"Copy last response": "সর্বশেষ রেসপন্স কপি করুন",
 	"Copy Link": "লিংক কপি করুন",
 	"Copying to clipboard was successful!": "ক্লিপবোর্ডে কপি করা সফল হয়েছে",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "'title' শব্দটি ব্যবহার না করে নিম্মোক্ত অনুসন্ধানের জন্য সংক্ষেপে সর্বোচ্চ ৩-৫ শব্দের একটি হেডার তৈরি করুন",
 	"Create a model": "একটি মডেল তৈরি করুন",
 	"Create Account": "একাউন্ট তৈরি করুন",
 	"Create new key": "একটি নতুন কী তৈরি করুন",
@@ -127,12 +132,12 @@
 	"Custom": "কাস্টম",
 	"Customize models for a specific purpose": "একটি নির্দিষ্ট উদ্দেশ্যে মডেল কাস্টমাইজ করুন",
 	"Dark": "ডার্ক",
+	"Dashboard": "",
 	"Database": "ডেটাবেজ",
 	"December": "ডেসেম্বর",
 	"Default": "ডিফল্ট",
 	"Default (Automatic1111)": "ডিফল্ট (Automatic1111)",
 	"Default (SentenceTransformers)": "ডিফল্ট (SentenceTransformers)",
-	"Default (Web API)": "ডিফল্ট (Web API)",
 	"Default Model": "ডিফল্ট মডেল",
 	"Default model updated": "ডিফল্ট মডেল আপডেট হয়েছে",
 	"Default Prompt Suggestions": "ডিফল্ট প্রম্পট সাজেশন",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "একটি প্রম্পট খুঁজে বের করুন",
 	"Discover, download, and explore custom prompts": "কাস্টম প্রম্পটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
 	"Discover, download, and explore model presets": "মডেল প্রিসেটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "চ্যাটে 'আপনি'-র পরবর্তে ইউজারনেম দেখান",
 	"Document": "ডকুমেন্ট",
 	"Document Settings": "ডকুমেন্ট সেটিংসমূহ",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "ডকুমেন্টসমূহ ম্যাপিং এক্সপোর্ট করুন",
 	"Export Models": "রপ্তানি মডেল",
 	"Export Prompts": "প্রম্পটগুলো একপোর্ট করুন",
+	"External Models": "",
 	"Failed to create API Key.": "API Key তৈরি করা যায়নি।",
 	"Failed to read clipboard contents": "ক্লিপবোর্ডের বিষয়বস্তু পড়া সম্ভব হয়নি",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "ফ্রিকোয়েন্সি পেনাল্টি",
 	"General": "সাধারণ",
 	"General Settings": "সাধারণ সেটিংসমূহ",
+	"Generate Image": "",
 	"Generating search query": "অনুসন্ধান ক্যোয়ারী তৈরি করা হচ্ছে",
 	"Generation Info": "জেনারেশন ইনফো",
 	"Good Response": "ভালো সাড়া",
@@ -252,6 +260,7 @@
 	"Info": "তথ্য",
 	"Input commands": "ইনপুট কমান্ডস",
 	"Install from Github URL": "Github URL থেকে ইনস্টল করুন",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "ইন্টারফেস",
 	"Invalid Tag": "অবৈধ ট্যাগ",
 	"January": "জানুয়ারী",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT টোকেন",
 	"Keep Alive": "সচল রাখুন",
 	"Keyboard shortcuts": "কিবোর্ড শর্টকাটসমূহ",
+	"Knowledge": "",
 	"Language": "ভাষা",
 	"Last Active": "সর্বশেষ সক্রিয়",
 	"Light": "লাইট",
-	"Listening...": "শুনছে...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLM ভুল করতে পারে। গুরুত্বপূর্ণ তথ্য যাচাই করে নিন।",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "OpenWebUI কমিউনিটিকর্তৃক নির্মিত",
 	"Make sure to enclose them with": "এটা দিয়ে বন্ধনী দিতে ভুলবেন না",
+	"Manage": "",
 	"Manage Models": "মডেলসমূহ ব্যবস্থাপনা করুন",
 	"Manage Ollama Models": "Ollama মডেলসূহ ব্যবস্থাপনা করুন",
 	"Manage Pipelines": "পাইপলাইন পরিচালনা করুন",
@@ -307,6 +319,7 @@
 	"Name your model": "আপনার মডেলের নাম দিন",
 	"New Chat": "নতুন চ্যাট",
 	"New Password": "নতুন পাসওয়ার্ড",
+	"No documents found": "",
 	"No results found": "কোন ফলাফল পাওয়া যায়নি",
 	"No search query generated": "কোনও অনুসন্ধান ক্যোয়ারী উত্পন্ন হয়নি",
 	"No source available": "কোন উৎস পাওয়া যায়নি",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API নিষ্ক্রিয় করা হয়েছে",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama ভার্সন",
 	"On": "চালু",
 	"Only": "শুধুমাত্র",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF ডকুমেন্ট (.pdf)",
 	"PDF Extract Images (OCR)": "পিডিএফ এর ছবি থেকে লেখা বের করুন (OCR)",
 	"pending": "অপেক্ষমান",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "মাইক্রোফোন ব্যবহারের অনুমতি পাওয়া যায়নি: {{error}}",
 	"Personalization": "ডিজিটাল বাংলা",
 	"Pipelines": "পাইপলাইন",
@@ -367,6 +383,7 @@
 	"Read Aloud": "পড়াশোনা করুন",
 	"Record voice": "ভয়েস রেকর্ড করুন",
 	"Redirecting you to OpenWebUI Community": "আপনাকে OpenWebUI কমিউনিটিতে পাঠানো হচ্ছে",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "যদি উপযুক্ত নয়, তবে রেজিগেনেট করা হচ্ছে",
 	"Regenerate": "রেজিগেনেট করুন",
 	"Release Notes": "রিলিজ নোটসমূহ",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "রোজ পাইন",
 	"Rosé Pine Dawn": "ভোরের রোজ পাইন",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "সংরক্ষণ",
 	"Save & Create": "সংরক্ষণ এবং তৈরি করুন",
 	"Save & Update": "সংরক্ষণ এবং আপডেট করুন",
@@ -398,6 +416,8 @@
 	"Search Documents": "ডকুমেন্টসমূহ অনুসন্ধান করুন",
 	"Search Models": "অনুসন্ধান মডেল",
 	"Search Prompts": "প্রম্পটসমূহ অনুসন্ধান করুন",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "অনুসন্ধানের ফলাফল গণনা",
 	"Searched {{count}} sites_one": "{{কাউন্ট}} অনুসন্ধান করা হয়েছে sites_one",
 	"Searched {{count}} sites_other": "{{কাউন্ট}} অনুসন্ধান করা হয়েছে sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "নতুন কী আছে দেখুন",
 	"Seed": "সীড",
 	"Select a base model": "একটি বেস মডেল নির্বাচন করুন",
+	"Select a engine": "",
 	"Select a mode": "একটি মডেল নির্বাচন করুন",
 	"Select a model": "একটি মডেল নির্বাচন করুন",
 	"Select a pipeline": "একটি পাইপলাইন নির্বাচন করুন",
 	"Select a pipeline url": "একটি পাইপলাইন URL নির্বাচন করুন",
 	"Select an Ollama instance": "একটি Ollama ইন্সট্যান্স নির্বাচন করুন",
 	"Select model": "মডেল নির্বাচন করুন",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "নির্বাচিত মডেল(গুলি) চিত্র ইনপুট সমর্থন করে না",
 	"Send": "পাঠান",
 	"Send a Message": "একটি মেসেজ পাঠান",
@@ -425,7 +447,6 @@
 	"Set Default Model": "ডিফল্ট মডেল নির্ধারণ করুন",
 	"Set embedding model (e.g. {{model}})": "ইমেম্বিং মডেল নির্ধারণ করুন (উদাহরণ {{model}})",
 	"Set Image Size": "ছবির সাইজ নির্ধারণ করুন",
-	"Set Model": "মডেল নির্ধারণ করুন",
 	"Set reranking model (e.g. {{model}})": "রি-র্যাংকিং মডেল নির্ধারণ করুন (উদাহরণ {{model}})",
 	"Set Steps": "পরবর্তী ধাপসমূহ",
 	"Set Task Model": "টাস্ক মডেল সেট করুন",
@@ -449,8 +470,8 @@
 	"Source": "উৎস",
 	"Speech recognition error: {{error}}": "স্পিচ রিকগনিশনে সমস্যা: {{error}}",
 	"Speech-to-Text Engine": "স্পিচ-টু-টেক্সট ইঞ্জিন",
-	"SpeechRecognition API is not supported in this browser.": "এই ব্রাউজার স্পিচরিকগনিশন এপিআই সাপোর্ট করে না।",
 	"Stop Sequence": "সিকোয়েন্স থামান",
+	"STT Model": "",
 	"STT Settings": "STT সেটিংস",
 	"Submit": "সাবমিট",
 	"Subtitle (e.g. about the Roman Empire)": "সাবটাইটল (রোমান ইম্পার্টের সম্পর্কে)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "আপনার মতামত ধন্যবাদ!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "স্কোর একটি 0.0 (0%) এবং 1.0 (100%) এর মধ্যে একটি মান হওয়া উচিত।",
 	"Theme": "থিম",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "এটা নিশ্চিত করে যে, আপনার গুরুত্বপূর্ণ আলোচনা নিরাপদে আপনার ব্যাকএন্ড ডেটাবেজে সংরক্ষিত আছে। ধন্যবাদ!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "এই সেটিং অন্যন্য ব্রাউজার বা ডিভাইসের সাথে সিঙ্ক্রোনাইজ নয় না।",
 	"Thorough explanation": "পুঙ্খানুপুঙ্খ ব্যাখ্যা",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "পরামর্শ: একাধিক ভেরিয়েবল স্লট একের পর এক রিপ্লেস করার জন্য চ্যাট ইনপুটে কিবোর্ডের Tab বাটন ব্যবহার করুন।",
@@ -481,6 +504,7 @@
 	"to": "প্রতি",
 	"To access the available model names for downloading,": "ডাউনলোডের জন্য এভেইলএবল মডেলের নামগুলো এক্সেস করতে,",
 	"To access the GGUF models available for downloading,": "ডাউলোডের জন্য এভেইলএবল GGUF মডেলগুলো এক্সেস করতে,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "চ্যাট ইনপুটে",
 	"Today": "আজ",
 	"Toggle settings": "সেটিংস টোগল",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Ollama এক্সেস করতে সমস্যা হচ্ছে?",
+	"TTS Model": "",
 	"TTS Settings": "TTS সেটিংসমূহ",
+	"TTS Voice": "",
 	"Type": "টাইপ",
 	"Type Hugging Face Resolve (Download) URL": "Hugging Face থেকে ডাউনলোড করার ইউআরএল টাইপ করুন",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "ওহ-হো! {{provider}} এর সাথে কানেকশনে সমস্যা হয়েছে।",
@@ -497,6 +523,7 @@
 	"Update password": "পাসওয়ার্ড আপডেট করুন",
 	"Upload a GGUF model": "একটি GGUF মডেল আপলোড করুন",
 	"Upload Files": "ফাইল আপলোড করুন",
+	"Upload Pipeline": "",
 	"Upload Progress": "আপলোড হচ্ছে",
 	"URL Mode": "ইউআরএল মোড",
 	"Use '#' in the prompt input to load and select your documents.": "আপনার ডকুমেন্টসমূহ নির্বাচন করার জন্য আপনার প্রম্পট ইনপুটে '# ব্যবহার করুন।",
@@ -515,6 +542,7 @@
 	"Warning": "সতর্কীকরণ",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "সতর্কীকরণ: আপনি যদি আপনার এম্বেডিং মডেল আপডেট বা পরিবর্তন করেন, তাহলে আপনাকে সমস্ত নথি পুনরায় আমদানি করতে হবে।.",
 	"Web": "ওয়েব",
+	"Web API": "",
 	"Web Loader Settings": "ওয়েব লোডার সেটিংস",
 	"Web Params": "ওয়েব প্যারামিটারসমূহ",
 	"Web Search": "ওয়েব অনুসন্ধান",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI যেখানে রিকোয়েস্ট পাঠাবে",
 	"What’s New in": "এতে নতুন কী",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "যদি হিস্টোরি বন্ধ থাকে তাহলে এই ব্রাউজারের নতুন চ্যাটগুলো আপনার কোন ডিভাইসের হিস্টোরিতেই দেখা যাবে না।",
-	"Whisper (Local)": "Whisper (লোকাল)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "ওয়ার্কস্পেস",
 	"Write a prompt suggestion (e.g. Who are you?)": "একটি প্রম্পট সাজেশন লিখুন (যেমন Who are you?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "৫০ শব্দের মধ্যে [topic or keyword] এর একটি সারসংক্ষেপ লিখুন।",
 	"Yesterday": "আগামী",
 	"You": "আপনি",
+	"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 clone a base model": "আপনি একটি বেস মডেল ক্লোন করতে পারবেন না",
 	"You have no archived conversations.": "আপনার কোনও আর্কাইভ করা কথোপকথন নেই।",
 	"You have shared this chat": "আপনি এই চ্যাটটি শেয়ার করেছেন",
 	"You're a helpful assistant.": "আপনি একজন উপকারী এসিস্ট্যান্ট",
 	"You're now logged in.": "আপনি এখন লগইন করা অবস্থায় আছেন",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "YouTube",
 	"Youtube Loader Settings": "YouTube লোডার সেটিংস"
 }

+ 38 - 8
src/lib/i18n/locales/ca-ES/translation.json

@@ -12,6 +12,7 @@
 	"a user": "un usuari",
 	"About": "Sobre",
 	"Account": "Compte",
+	"Account Activation Pending": "",
 	"Accurate information": "Informació precisa",
 	"Active Users": "",
 	"Add": "Afegir",
@@ -29,6 +30,7 @@
 	"Add User": "Afegir Usuari",
 	"Adjusting these settings will apply changes universally to all users.": "Ajustar aquests paràmetres aplicarà canvis de manera universal a tots els usuaris.",
 	"admin": "administrador",
+	"Admin": "",
 	"Admin Panel": "Panell d'Administració",
 	"Admin Settings": "Configuració d'Administració",
 	"Advanced Parameters": "Paràmetres Avançats",
@@ -59,7 +61,6 @@
 	"Audio": "Àudio",
 	"August": "Agost",
 	"Auto-playback response": "Resposta de reproducció automàtica",
-	"Auto-send input after 3 sec.": "Enviar entrada automàticament després de 3 segons",
 	"AUTOMATIC1111 Base URL": "URL Base AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base AUTOMATIC1111.",
 	"available!": "disponible!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Ser l'estupidez",
 	"Brave Search API Key": "Clau API Brave Search",
 	"Bypass SSL verification for Websites": "Desactivar la verificació SSL per a l'accés a l'Internet",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Cancel·la",
 	"Capabilities": "Capacitats",
 	"Change Password": "Canvia la Contrasenya",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Paràmetres de Blocs",
 	"Chunk Size": "Mida del Bloc",
 	"Citation": "Citació",
+	"Clear memory": "",
 	"Click here for help.": "Fes clic aquí per ajuda.",
 	"Click here to": "Fes clic aquí per",
 	"Click here to select": "Fes clic aquí per seleccionar",
 	"Click here to select a csv file.": "Fes clic aquí per seleccionar un fitxer csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Fes clic aquí per seleccionar documents.",
 	"click here.": "fes clic aquí.",
 	"Click on the user role button to change a user's role.": "Fes clic al botó de rol d'usuari per canviar el rol d'un usuari.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Sol·licituds simultànies",
 	"Confirm Password": "Confirma la Contrasenya",
 	"Connections": "Connexions",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Contingut",
 	"Context Length": "Longitud del Context",
 	"Continue Response": "Continua la Resposta",
-	"Conversation Mode": "Mode de Conversa",
 	"Copied shared chat URL to clipboard!": "S'ha copiat l'URL compartida al porta-retalls!",
 	"Copy": "Copiar",
 	"Copy last code block": "Copia l'últim bloc de codi",
 	"Copy last response": "Copia l'última resposta",
 	"Copy Link": "Copiar l'enllaç",
 	"Copying to clipboard was successful!": "La còpia al porta-retalls ha estat exitosa!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crea una frase concisa de 3-5 paraules com a capçalera per a la següent consulta, seguint estrictament el límit de 3-5 paraules i evitant l'ús de la paraula 'títol':",
 	"Create a model": "Crear un model",
 	"Create Account": "Crea un Compte",
 	"Create new key": "Crea una nova clau",
@@ -127,12 +132,12 @@
 	"Custom": "Personalitzat",
 	"Customize models for a specific purpose": "Personalitzar models per a un propòsit específic",
 	"Dark": "Fosc",
+	"Dashboard": "",
 	"Database": "Base de Dades",
 	"December": "Desembre",
 	"Default": "Per defecte",
 	"Default (Automatic1111)": "Per defecte (Automatic1111)",
 	"Default (SentenceTransformers)": "Per defecte (SentenceTransformers)",
-	"Default (Web API)": "Per defecte (Web API)",
 	"Default Model": "Model per defecte",
 	"Default model updated": "Model per defecte actualitzat",
 	"Default Prompt Suggestions": "Suggeriments de Prompt Per Defecte",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Descobreix un prompt",
 	"Discover, download, and explore custom prompts": "Descobreix, descarrega i explora prompts personalitzats",
 	"Discover, download, and explore model presets": "Descobreix, descarrega i explora presets de models",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Mostra el nom d'usuari en lloc de 'Tu' al Xat",
 	"Document": "Document",
 	"Document Settings": "Configuració de Documents",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exporta el Mapatge de Documents",
 	"Export Models": "Models d'exportació",
 	"Export Prompts": "Exporta Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "No s'ha pogut crear la clau d'API.",
 	"Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Pena de freqüència",
 	"General": "General",
 	"General Settings": "Configuració General",
+	"Generate Image": "",
 	"Generating search query": "Generació de consultes de cerca",
 	"Generation Info": "Informació de Generació",
 	"Good Response": "Resposta bona",
@@ -252,6 +260,7 @@
 	"Info": "Informació",
 	"Input commands": "Entra ordres",
 	"Install from Github URL": "Instal·leu des de l'URL de Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interfície",
 	"Invalid Tag": "Etiqueta Inválida",
 	"January": "Gener",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Mantén Actiu",
 	"Keyboard shortcuts": "Dreceres de Teclat",
+	"Knowledge": "",
 	"Language": "Idioma",
 	"Last Active": "Últim Actiu",
 	"Light": "Clar",
-	"Listening...": "Escoltant...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Els LLMs poden cometre errors. Verifica la informació important.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Creat per la Comunitat OpenWebUI",
 	"Make sure to enclose them with": "Assegura't d'envoltar-los amb",
+	"Manage": "",
 	"Manage Models": "Gestiona Models",
 	"Manage Ollama Models": "Gestiona Models Ollama",
 	"Manage Pipelines": "Gestionar canonades",
@@ -307,6 +319,7 @@
 	"Name your model": "Posa un nom al model",
 	"New Chat": "Xat Nou",
 	"New Password": "Nova Contrasenya",
+	"No documents found": "",
 	"No results found": "No s'han trobat resultats",
 	"No search query generated": "No es genera cap consulta de cerca",
 	"No source available": "Sense font disponible",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "API d'Ollama",
 	"Ollama API disabled": "L'API d'Ollama desactivada",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Versió d'Ollama",
 	"On": "Activat",
 	"Only": "Només",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Document PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Extreu Imatges de PDF (OCR)",
 	"pending": "pendent",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}",
 	"Personalization": "Personalització",
 	"Pipelines": "Canonades",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Llegiu al voltant",
 	"Record voice": "Enregistra veu",
 	"Redirecting you to OpenWebUI Community": "Redirigint-te a la Comunitat OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Refusat quan no hauria d'haver-ho",
 	"Regenerate": "Regenerar",
 	"Release Notes": "Notes de la Versió",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Albada Rosé Pine",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Guarda",
 	"Save & Create": "Guarda i Crea",
 	"Save & Update": "Guarda i Actualitza",
@@ -398,6 +416,8 @@
 	"Search Documents": "Cerca Documents",
 	"Search Models": "Models de cerca",
 	"Search Prompts": "Cerca Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Recompte de resultats de cerca",
 	"Searched {{count}} sites_one": "Cercat {{count}} sites_one",
 	"Searched {{count}} sites_many": "Cercat {{recompte}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Veure novetats",
 	"Seed": "Llavor",
 	"Select a base model": "Seleccionar un model base",
+	"Select a engine": "",
 	"Select a mode": "Selecciona un mode",
 	"Select a model": "Selecciona un model",
 	"Select a pipeline": "Seleccioneu una canonada",
 	"Select a pipeline url": "Seleccionar un URL de canonada",
 	"Select an Ollama instance": "Selecciona una instància d'Ollama",
 	"Select model": "Selecciona un model",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Els models seleccionats no admeten l'entrada d'imatges",
 	"Send": "Envia",
 	"Send a Message": "Envia un Missatge",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Estableix Model Predeterminat",
 	"Set embedding model (e.g. {{model}})": "Estableix el model d'emboscada (p.ex. {{model}})",
 	"Set Image Size": "Estableix Mida de la Imatge",
-	"Set Model": "Estableix Model",
 	"Set reranking model (e.g. {{model}})": "Estableix el model de reranking (p.ex. {{model}})",
 	"Set Steps": "Estableix Passos",
 	"Set Task Model": "Defineix el model de tasca",
@@ -450,8 +471,8 @@
 	"Source": "Font",
 	"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
 	"Speech-to-Text Engine": "Motor de Veu a Text",
-	"SpeechRecognition API is not supported in this browser.": "L'API de Reconèixer Veu no és compatible amb aquest navegador.",
 	"Stop Sequence": "Atura Seqüència",
+	"STT Model": "",
 	"STT Settings": "Configuracions STT",
 	"Submit": "Envia",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítol (per exemple, sobre l'Imperi Romà)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Gràcies pel teu comentari!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "El puntuatge ha de ser un valor entre 0.0 (0%) i 1.0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Això assegura que les teves converses valuoses queden segurament guardades a la teva base de dades backend. Gràcies!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Aquesta configuració no es sincronitza entre navegadors ni dispositius.",
 	"Thorough explanation": "Explacació exhaustiva",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Consell: Actualitza diversos espais de variables consecutivament prement la tecla de tabulació en l'entrada del xat després de cada reemplaçament.",
@@ -482,6 +505,7 @@
 	"to": "a",
 	"To access the available model names for downloading,": "Per accedir als noms dels models disponibles per descarregar,",
 	"To access the GGUF models available for downloading,": "Per accedir als models GGUF disponibles per descarregar,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "a l'entrada del xat.",
 	"Today": "Avui",
 	"Toggle settings": "Commuta configuracions",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemes accedint a Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Configuracions TTS",
+	"TTS Voice": "",
 	"Type": "Tipus",
 	"Type Hugging Face Resolve (Download) URL": "Escriu URL de Resolució (Descàrrega) de Hugging Face",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uf! Hi va haver un problema connectant-se a {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Actualitza contrasenya",
 	"Upload a GGUF model": "Puja un model GGUF",
 	"Upload Files": "Pujar fitxers",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progrés de Càrrega",
 	"URL Mode": "Mode URL",
 	"Use '#' in the prompt input to load and select your documents.": "Utilitza '#' a l'entrada del prompt per carregar i seleccionar els teus documents.",
@@ -516,6 +543,7 @@
 	"Warning": "Advertiment",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Avís: Si actualitzeu o canvieu el model d'incrustació, haureu de tornar a importar tots els documents.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Configuració del carregador web",
 	"Web Params": "Paràmetres web",
 	"Web Search": "Cercador web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI farà peticions a",
 	"What’s New in": "Què hi ha de Nou en",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quan l'historial està desactivat, els nous xats en aquest navegador no apareixeran en el teu historial en cap dels teus dispositius.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Treball",
 	"Write a prompt suggestion (e.g. Who are you?)": "Escriu una suggerència de prompt (p. ex. Qui ets tu?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Escriu un resum en 50 paraules que resumeixi [tema o paraula clau].",
 	"Yesterday": "Ayer",
 	"You": "Tu",
+	"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 clone a base model": "No es pot clonar un model base",
 	"You have no archived conversations.": "No tens converses arxivades.",
 	"You have shared this chat": "Has compartit aquest xat",
 	"You're a helpful assistant.": "Ets un assistent útil.",
 	"You're now logged in.": "Ara estàs connectat.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Configuració del carregador de Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/ceb-PH/translation.json

@@ -12,6 +12,7 @@
 	"a user": "usa ka user",
 	"About": "Mahitungod sa",
 	"Account": "Account",
+	"Account Activation Pending": "",
 	"Accurate information": "",
 	"Active Users": "",
 	"Add": "",
@@ -29,6 +30,7 @@
 	"Add User": "",
 	"Adjusting these settings will apply changes universally to all users.": "Ang pag-adjust niini nga mga setting magamit ang mga pagbag-o sa tanan nga tiggamit.",
 	"admin": "Administrator",
+	"Admin": "",
 	"Admin Panel": "Admin Panel",
 	"Admin Settings": "Mga setting sa administratibo",
 	"Advanced Parameters": "advanced settings",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "",
 	"Auto-playback response": "Autoplay nga tubag",
-	"Auto-send input after 3 sec.": "Awtomatikong ipadala ang entry pagkahuman sa 3 segundos.",
 	"AUTOMATIC1111 Base URL": "Base URL AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "Ang AUTOMATIC1111 base URL gikinahanglan.",
 	"available!": "magamit!",
@@ -71,6 +72,9 @@
 	"Being lazy": "",
 	"Brave Search API Key": "",
 	"Bypass SSL verification for Websites": "",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Pagkanselar",
 	"Capabilities": "",
 	"Change Password": "Usba ang password",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Mga Setting sa Block",
 	"Chunk Size": "Gidak-on sa block",
 	"Citation": "Mga kinutlo",
+	"Clear memory": "",
 	"Click here for help.": "I-klik dinhi alang sa tabang.",
 	"Click here to": "",
 	"Click here to select": "I-klik dinhi aron makapili",
 	"Click here to select a csv file.": "",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Pag-klik dinhi aron mapili ang mga dokumento.",
 	"click here.": "I-klik dinhi.",
 	"Click on the user role button to change a user's role.": "I-klik ang User Role button aron usbon ang role sa user.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "",
 	"Confirm Password": "Kumpirma ang password",
 	"Connections": "Mga koneksyon",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Kontento",
 	"Context Length": "Ang gitas-on sa konteksto",
 	"Continue Response": "",
-	"Conversation Mode": "Talk mode",
 	"Copied shared chat URL to clipboard!": "",
 	"Copy": "",
 	"Copy last code block": "Kopyaha ang katapusang bloke sa code",
 	"Copy last response": "Kopyaha ang kataposang tubag",
 	"Copy Link": "",
 	"Copying to clipboard was successful!": "Ang pagkopya sa clipboard malampuson!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Paghimo og mugbo nga 3-5 ka pulong nga sentence isip usa ka ulohan alang sa mosunod nga pangutana, hugot nga pagsunod sa 3-5 ka pulong nga limitasyon ug paglikay sa paggamit sa pulong nga 'titulo':",
 	"Create a model": "",
 	"Create Account": "Paghimo og account",
 	"Create new key": "",
@@ -127,12 +132,12 @@
 	"Custom": "Custom",
 	"Customize models for a specific purpose": "",
 	"Dark": "Ngitngit",
+	"Dashboard": "",
 	"Database": "Database",
 	"December": "",
 	"Default": "Pinaagi sa default",
 	"Default (Automatic1111)": "Default (Awtomatiko1111)",
 	"Default (SentenceTransformers)": "",
-	"Default (Web API)": "Default (Web API)",
 	"Default Model": "",
 	"Default model updated": "Gi-update nga default template",
 	"Default Prompt Suggestions": "Default nga prompt nga mga sugyot",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Pagkaplag usa ka prompt",
 	"Discover, download, and explore custom prompts": "Pagdiskubre, pag-download ug pagsuhid sa mga naandan nga pag-aghat",
 	"Discover, download, and explore model presets": "Pagdiskobre, pag-download, ug pagsuhid sa mga preset sa template",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Ipakita ang username imbes nga 'Ikaw' sa Panaghisgutan",
 	"Document": "Dokumento",
 	"Document Settings": "Mga Setting sa Dokumento",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "I-export ang pagmapa sa dokumento",
 	"Export Models": "",
 	"Export Prompts": "Export prompts",
+	"External Models": "",
 	"Failed to create API Key.": "",
 	"Failed to read clipboard contents": "Napakyas sa pagbasa sa sulod sa clipboard",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "",
 	"General": "Heneral",
 	"General Settings": "kinatibuk-ang mga setting",
+	"Generate Image": "",
 	"Generating search query": "",
 	"Generation Info": "",
 	"Good Response": "",
@@ -252,6 +260,7 @@
 	"Info": "",
 	"Input commands": "Pagsulod sa input commands",
 	"Install from Github URL": "",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "",
 	"January": "",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT token",
 	"Keep Alive": "Padayon nga aktibo",
 	"Keyboard shortcuts": "Mga shortcut sa keyboard",
+	"Knowledge": "",
 	"Language": "Pinulongan",
 	"Last Active": "",
 	"Light": "Kahayag",
-	"Listening...": "Paminaw...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Ang mga LLM mahimong masayop. ",
+	"Local Models": "",
 	"LTR": "",
 	"Made by OpenWebUI Community": "Gihimo sa komunidad sa OpenWebUI",
 	"Make sure to enclose them with": "Siguruha nga palibutan sila",
+	"Manage": "",
 	"Manage Models": "Pagdumala sa mga templates",
 	"Manage Ollama Models": "Pagdumala sa mga modelo sa Ollama",
 	"Manage Pipelines": "",
@@ -307,6 +319,7 @@
 	"Name your model": "",
 	"New Chat": "Bag-ong diskusyon",
 	"New Password": "Bag-ong Password",
+	"No documents found": "",
 	"No results found": "",
 	"No search query generated": "",
 	"No source available": "Walay tinubdan nga anaa",
@@ -323,6 +336,7 @@
 	"Ollama": "",
 	"Ollama API": "",
 	"Ollama API disabled": "",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama nga bersyon",
 	"On": "Gipaandar",
 	"Only": "Lamang",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "",
 	"PDF Extract Images (OCR)": "PDF Image Extraction (OCR)",
 	"pending": "gipugngan",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Gidili ang pagtugot sa dihang nag-access sa mikropono: {{error}}",
 	"Personalization": "",
 	"Pipelines": "",
@@ -367,6 +383,7 @@
 	"Read Aloud": "",
 	"Record voice": "Irekord ang tingog",
 	"Redirecting you to OpenWebUI Community": "Gi-redirect ka sa komunidad sa OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "",
 	"Regenerate": "",
 	"Release Notes": "Release Notes",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Aube Pine Rosé",
 	"RTL": "",
+	"Running": "",
 	"Save": "Tipigi",
 	"Save & Create": "I-save ug Paghimo",
 	"Save & Update": "I-save ug I-update",
@@ -398,6 +416,8 @@
 	"Search Documents": "Pangitaa ang mga dokumento",
 	"Search Models": "",
 	"Search Prompts": "Pangitaa ang mga prompt",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "",
 	"Searched {{count}} sites_one": "",
 	"Searched {{count}} sites_other": "",
@@ -407,12 +427,14 @@
 	"See what's new": "Tan-awa unsay bag-o",
 	"Seed": "Binhi",
 	"Select a base model": "",
+	"Select a engine": "",
 	"Select a mode": "Pagpili og mode",
 	"Select a model": "Pagpili og modelo",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select an Ollama instance": "Pagpili usa ka pananglitan sa Ollama",
 	"Select model": "Pagpili og modelo",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "",
 	"Send": "",
 	"Send a Message": "Magpadala ug mensahe",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Ibutang ang default template",
 	"Set embedding model (e.g. {{model}})": "",
 	"Set Image Size": "Ibutang ang gidak-on sa hulagway",
-	"Set Model": "I-configure ang template",
 	"Set reranking model (e.g. {{model}})": "",
 	"Set Steps": "Ipasabot ang mga lakang",
 	"Set Task Model": "",
@@ -449,8 +470,8 @@
 	"Source": "Tinubdan",
 	"Speech recognition error: {{error}}": "Sayop sa pag-ila sa tingog: {{error}}",
 	"Speech-to-Text Engine": "Engine sa pag-ila sa tingog",
-	"SpeechRecognition API is not supported in this browser.": "Ang SpeechRecognition API wala gisuportahan niini nga browser.",
 	"Stop Sequence": "Pagkasunod-sunod sa pagsira",
+	"STT Model": "",
 	"STT Settings": "Mga setting sa STT",
 	"Submit": "Isumite",
 	"Subtitle (e.g. about the Roman Empire)": "",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Kini nagsiguro nga ang imong bililhon nga mga panag-istoryahanay luwas nga natipig sa imong backend database. ",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Kini nga setting wala mag-sync tali sa mga browser o device.",
 	"Thorough explanation": "",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Sugyot: Pag-update sa daghang variable nga lokasyon nga sunud-sunod pinaagi sa pagpindot sa tab key sa chat entry pagkahuman sa matag puli.",
@@ -481,6 +504,7 @@
 	"to": "adunay",
 	"To access the available model names for downloading,": "Aron ma-access ang mga ngalan sa modelo nga ma-download,",
 	"To access the GGUF models available for downloading,": "Aron ma-access ang mga modelo sa GGUF nga magamit alang sa pag-download,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "sa entrada sa iring.",
 	"Today": "",
 	"Toggle settings": "I-toggle ang mga setting",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Ibabaw nga P",
 	"Trouble accessing Ollama?": "Adunay mga problema sa pag-access sa Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Mga Setting sa TTS",
+	"TTS Voice": "",
 	"Type": "",
 	"Type Hugging Face Resolve (Download) URL": "Pagsulod sa resolusyon (pag-download) URL Hugging Face",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh!  {{provider}}.",
@@ -497,6 +523,7 @@
 	"Update password": "I-update ang password",
 	"Upload a GGUF model": "Pag-upload ug modelo sa GGUF",
 	"Upload Files": "",
+	"Upload Pipeline": "",
 	"Upload Progress": "Pag-uswag sa Pag-upload",
 	"URL Mode": "URL mode",
 	"Use '#' in the prompt input to load and select your documents.": "Gamita ang '#' sa dali nga pagsulod aron makarga ug mapili ang imong mga dokumento.",
@@ -515,6 +542,7 @@
 	"Warning": "",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "",
 	"Web Params": "",
 	"Web Search": "",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "Ang WebUI maghimo mga hangyo sa",
 	"What’s New in": "Unsay bag-o sa",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Kung ang kasaysayan gipalong, ang mga bag-ong chat sa kini nga browser dili makita sa imong kasaysayan sa bisan unsang mga aparato.",
-	"Whisper (Local)": "Whisper (Lokal)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "",
 	"Write a prompt suggestion (e.g. Who are you?)": "Pagsulat og gisugyot nga prompt (eg. Kinsa ka?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Pagsulat og 50 ka pulong nga summary nga nagsumaryo [topic o keyword].",
 	"Yesterday": "",
 	"You": "",
+	"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 clone a base model": "",
 	"You have no archived conversations.": "",
 	"You have shared this chat": "",
 	"You're a helpful assistant.": "Usa ka ka mapuslanon nga katabang",
 	"You're now logged in.": "Konektado ka na karon.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "",
 	"Youtube Loader Settings": ""
 }

+ 56 - 26
src/lib/i18n/locales/de-DE/translation.json

@@ -12,8 +12,9 @@
 	"a user": "ein Benutzer",
 	"About": "Über",
 	"Account": "Account",
+	"Account Activation Pending": "",
 	"Accurate information": "Genaue Information",
-	"Active Users": "",
+	"Active Users": "Aktive Benutzer",
 	"Add": "Hinzufügen",
 	"Add a model id": "Hinzufügen einer Modell-ID",
 	"Add a short description about what this model does": "Fügen Sie eine kurze Beschreibung hinzu, was dieses Modell tut",
@@ -29,6 +30,7 @@
 	"Add User": "User hinzufügen",
 	"Adjusting these settings will apply changes universally to all users.": "Das Anpassen dieser Einstellungen wirkt sich universell auf alle Benutzer aus.",
 	"admin": "Administrator",
+	"Admin": "",
 	"Admin Panel": "Admin Panel",
 	"Admin Settings": "Admin Einstellungen",
 	"Advanced Parameters": "Erweiterte Parameter",
@@ -38,7 +40,7 @@
 	"All Users": "Alle Benutzer",
 	"Allow": "Erlauben",
 	"Allow Chat Deletion": "Chat Löschung erlauben",
-	"Allow non-local voices": "",
+	"Allow non-local voices": "Nicht-lokale Stimmen erlauben",
 	"alphanumeric characters and hyphens": "alphanumerische Zeichen und Bindestriche",
 	"Already have an account?": "Hast du vielleicht schon ein Account?",
 	"an assistant": "ein Assistent",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "August",
 	"Auto-playback response": "Automatische Wiedergabe der Antwort",
-	"Auto-send input after 3 sec.": "Automatisches Senden der Eingabe nach 3 Sek",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Basis URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Basis URL wird benötigt",
 	"available!": "verfügbar!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Faul sein",
 	"Brave Search API Key": "API-Schlüssel für die Brave-Suche",
 	"Bypass SSL verification for Websites": "Bypass SSL-Verifizierung für Websites",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Abbrechen",
 	"Capabilities": "Fähigkeiten",
 	"Change Password": "Passwort ändern",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk Parameter",
 	"Chunk Size": "Chunk Size",
 	"Citation": "Zitate",
+	"Clear memory": "Memory löschen",
 	"Click here for help.": "Klicke hier für Hilfe.",
 	"Click here to": "Klicke hier, um",
 	"Click here to select": "Klicke hier um auszuwählen",
 	"Click here to select a csv file.": "Klicke hier um eine CSV-Datei auszuwählen.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Klicke hier um Dokumente auszuwählen",
 	"click here.": "hier klicken.",
 	"Click on the user role button to change a user's role.": "Klicke auf die Benutzerrollenschaltfläche, um die Rolle eines Benutzers zu ändern.",
@@ -105,18 +111,17 @@
 	"Concurrent Requests": "Gleichzeitige Anforderungen",
 	"Confirm Password": "Passwort bestätigen",
 	"Connections": "Verbindungen",
-	"Content": "Inhalt",
+	"Contact Admin for WebUI Access": "",
+	"Content": "Info",
 	"Context Length": "Context Length",
 	"Continue Response": "Antwort fortsetzen",
-	"Conversation Mode": "Konversationsmodus",
 	"Copied shared chat URL to clipboard!": "Geteilte Chat-URL in die Zwischenablage kopiert!",
 	"Copy": "Kopieren",
 	"Copy last code block": "Letzten Codeblock kopieren",
 	"Copy last response": "Letzte Antwort kopieren",
 	"Copy Link": "Link kopieren",
 	"Copying to clipboard was successful!": "Das Kopieren in die Zwischenablage war erfolgreich!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Erstelle einen prägnanten Satz mit 3-5 Wörtern als Überschrift für die folgende Abfrage. Halte dich dabei strikt an die 3-5-Wort-Grenze und vermeide die Verwendung des Wortes Titel:",
-	"Create a model": "Erstellen eines Modells",
+	"Create a model": "Ein Modell erstellen",
 	"Create Account": "Konto erstellen",
 	"Create new key": "Neuen Schlüssel erstellen",
 	"Create new secret key": "Neuen API Schlüssel erstellen",
@@ -127,12 +132,12 @@
 	"Custom": "Benutzerdefiniert",
 	"Customize models for a specific purpose": "Modelle für einen bestimmten Zweck anpassen",
 	"Dark": "Dunkel",
+	"Dashboard": "",
 	"Database": "Datenbank",
 	"December": "Dezember",
 	"Default": "Standard",
 	"Default (Automatic1111)": "Standard (Automatic1111)",
 	"Default (SentenceTransformers)": "Standard (SentenceTransformers)",
-	"Default (Web API)": "Standard (Web-API)",
 	"Default Model": "Standardmodell",
 	"Default model updated": "Standardmodell aktualisiert",
 	"Default Prompt Suggestions": "Standard-Prompt-Vorschläge",
@@ -153,10 +158,11 @@
 	"Discover a prompt": "Einen Prompt entdecken",
 	"Discover, download, and explore custom prompts": "Benutzerdefinierte Prompts entdecken, herunterladen und erkunden",
 	"Discover, download, and explore model presets": "Modellvorgaben entdecken, herunterladen und erkunden",
+	"Dismissible": "ausblendbar",
 	"Display the username instead of You in the Chat": "Den Benutzernamen anstelle von 'du' im Chat anzeigen",
 	"Document": "Dokument",
 	"Document Settings": "Dokumenteinstellungen",
-	"Documentation": "",
+	"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 Deine Daten bleiben sicher auf Deinen lokal gehosteten Server.",
 	"Don't Allow": "Nicht erlauben",
@@ -171,7 +177,7 @@
 	"Edit Doc": "Dokument bearbeiten",
 	"Edit User": "Benutzer bearbeiten",
 	"Email": "E-Mail",
-	"Embedding Batch Size": "",
+	"Embedding Batch Size": "Embedding Batch Größe",
 	"Embedding Model": "Embedding-Modell",
 	"Embedding Model Engine": "Embedding-Modell-Engine",
 	"Embedding model set to \"{{embedding_model}}\"": "Embedding-Modell auf \"{{embedding_model}}\" gesetzt",
@@ -200,34 +206,36 @@
 	"Enter Top K": "Gib Top K ein",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "Gib die URL ein (z.B. http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://localhost:11434)": "Gib die URL ein (z.B. http://localhost:11434)",
-	"Enter Your Email": "Gib deine E-Mail-Adresse ein",
-	"Enter Your Full Name": "Gib deinen vollständigen Namen ein",
-	"Enter Your Password": "Gib dein Passwort ein",
+	"Enter Your Email": "E-Mail-Adresse",
+	"Enter Your Full Name": "Name",
+	"Enter Your Password": "Passwort",
 	"Enter Your Role": "Gebe deine Rolle ein",
 	"Error": "Fehler",
 	"Experimental": "Experimentell",
 	"Export": "Exportieren",
 	"Export All Chats (All Users)": "Alle Chats exportieren (alle Benutzer)",
-	"Export chat (.json)": "",
+	"Export chat (.json)": "Chat exportieren (.json)",
 	"Export Chats": "Chats exportieren",
 	"Export Documents Mapping": "Dokumentenmapping exportieren",
 	"Export Models": "Modelle exportieren",
 	"Export Prompts": "Prompts exportieren",
+	"External Models": "",
 	"Failed to create API Key.": "API Key erstellen fehlgeschlagen",
 	"Failed to read clipboard contents": "Fehler beim Lesen des Zwischenablageninhalts",
-	"Failed to update settings": "",
+	"Failed to update settings": "Fehler beim Aktualisieren der Einstellungen",
 	"February": "Februar",
 	"Feel free to add specific details": "Ergänze Details.",
 	"File Mode": "File Modus",
 	"File not found.": "Datei nicht gefunden.",
 	"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Fingerprint spoofing erkannt: Initialen können nicht als Avatar verwendet werden. Es wird auf das Standardprofilbild zurückgegriffen.",
-	"Fluidly stream large external response chunks": "Streamen Sie große externe Antwortblöcke flüssig",
+	"Fluidly stream large external response chunks": "Große externe Antwortblöcke flüssig streamen",
 	"Focus chat input": "Chat-Eingabe fokussieren",
 	"Followed instructions perfectly": "Anweisungen perfekt befolgt",
 	"Format your variables using square brackets like this:": "Formatiere deine Variablen mit eckigen Klammern wie folgt:",
 	"Frequency Penalty": "Frequenz-Strafe",
 	"General": "Allgemein",
 	"General Settings": "Allgemeine Einstellungen",
+	"Generate Image": "",
 	"Generating search query": "Suchanfrage generieren",
 	"Generation Info": "Generierungsinformationen",
 	"Good Response": "Gute Antwort",
@@ -252,6 +260,7 @@
 	"Info": "Info",
 	"Input commands": "Eingabebefehle",
 	"Install from Github URL": "Installieren Sie von der Github-URL",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Benutzeroberfläche",
 	"Invalid Tag": "Ungültiger Tag",
 	"January": "Januar",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT-Token",
 	"Keep Alive": "Keep Alive",
 	"Keyboard shortcuts": "Tastenkürzel",
+	"Knowledge": "",
 	"Language": "Sprache",
 	"Last Active": "Zuletzt aktiv",
 	"Light": "Hell",
-	"Listening...": "Hören...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs können Fehler machen. Überprüfe wichtige Informationen.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Von der OpenWebUI-Community",
 	"Make sure to enclose them with": "Formatiere deine Variablen mit:",
+	"Manage": "Verwalten",
 	"Manage Models": "Modelle verwalten",
 	"Manage Ollama Models": "Ollama-Modelle verwalten",
 	"Manage Pipelines": "Verwalten von Pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Benennen Sie Ihr Modell",
 	"New Chat": "Neuer Chat",
 	"New Password": "Neues Passwort",
+	"No documents found": "",
 	"No results found": "Keine Ergebnisse gefunden",
 	"No search query generated": "Keine Suchanfrage generiert",
 	"No source available": "Keine Quelle verfügbar.",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama-API",
 	"Ollama API disabled": "Ollama-API deaktiviert",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama-Version",
 	"On": "Ein",
 	"Only": "Nur",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF-Dokument (.pdf)",
 	"PDF Extract Images (OCR)": "Text von Bildern aus PDFs extrahieren (OCR)",
 	"pending": "ausstehend",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Zugriff auf das Mikrofon verweigert: {{error}}",
 	"Personalization": "Personalisierung",
 	"Pipelines": "Pipelines",
@@ -362,11 +378,12 @@
 	"Prompts": "Prompts",
 	"Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" von Ollama.com herunterladen",
 	"Pull a model from Ollama.com": "Ein Modell von Ollama.com abrufen",
-	"Query Params": "Query Parameter",
-	"RAG Template": "RAG-Vorlage",
+	"Query Params": "Abfrage Parameter",
+	"RAG Template": "RAG-Template",
 	"Read Aloud": "Vorlesen",
 	"Record voice": "Stimme aufnehmen",
 	"Redirecting you to OpenWebUI Community": "Du wirst zur OpenWebUI-Community weitergeleitet",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Abgelehnt, obwohl es nicht hätte sein sollen.",
 	"Regenerate": "Neu generieren",
 	"Release Notes": "Versionshinweise",
@@ -378,13 +395,14 @@
 	"Reranking Model": "Reranking Modell",
 	"Reranking model disabled": "Rranking Modell deaktiviert",
 	"Reranking model set to \"{{reranking_model}}\"": "Reranking Modell auf \"{{reranking_model}}\" gesetzt",
-	"Reset Upload Directory": "",
+	"Reset Upload Directory": "Uploadverzeichnis löschen",
 	"Reset Vector Storage": "Vektorspeicher zurücksetzen",
 	"Response AutoCopy to Clipboard": "Antwort automatisch in die Zwischenablage kopieren",
 	"Role": "Rolle",
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "Läuft",
 	"Save": "Speichern",
 	"Save & Create": "Speichern und erstellen",
 	"Save & Update": "Speichern und aktualisieren",
@@ -398,6 +416,8 @@
 	"Search Documents": "Dokumente suchen",
 	"Search Models": "Modelle suchen",
 	"Search Prompts": "Prompts suchen",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Anzahl der Suchergebnisse",
 	"Searched {{count}} sites_one": "Gesucht {{count}} sites_one",
 	"Searched {{count}} sites_other": "Gesucht {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "Was gibt's Neues",
 	"Seed": "Seed",
 	"Select a base model": "Wählen Sie ein Basismodell",
+	"Select a engine": "Wähle eine Engine",
 	"Select a mode": "Einen Modus auswählen",
 	"Select a model": "Ein Modell auswählen",
 	"Select a pipeline": "Wählen Sie eine Pipeline aus",
 	"Select a pipeline url": "Auswählen einer Pipeline-URL",
 	"Select an Ollama instance": "Eine Ollama Instanz auswählen",
 	"Select model": "Modell auswählen",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Ausgewählte Modelle unterstützen keine Bildeingaben",
 	"Send": "Senden",
 	"Send a Message": "Eine Nachricht senden",
@@ -425,20 +447,19 @@
 	"Set Default Model": "Standardmodell festlegen",
 	"Set embedding model (e.g. {{model}})": "Eingabemodell festlegen (z.B. {{model}})",
 	"Set Image Size": "Bildgröße festlegen",
-	"Set Model": "Modell festlegen",
 	"Set reranking model (e.g. {{model}})": "Rerankingmodell festlegen (z.B. {{model}})",
 	"Set Steps": "Schritte festlegen",
 	"Set Task Model": "Aufgabenmodell festlegen",
 	"Set Voice": "Stimme festlegen",
 	"Settings": "Einstellungen",
 	"Settings saved successfully!": "Einstellungen erfolgreich gespeichert!",
-	"Settings updated successfully": "",
+	"Settings updated successfully": "Settings updated successfully",
 	"Share": "Teilen",
 	"Share Chat": "Chat teilen",
 	"Share to OpenWebUI Community": "Mit OpenWebUI Community teilen",
 	"short-summary": "kurze-zusammenfassung",
 	"Show": "Anzeigen",
-	"Show Admin Details in Account Pending Overlay": "",
+	"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
 	"Show shortcuts": "Verknüpfungen anzeigen",
 	"Showcased creativity": "Kreativität zur Schau gestellt",
 	"sidebar": "Seitenleiste",
@@ -449,8 +470,8 @@
 	"Source": "Quellen",
 	"Speech recognition error: {{error}}": "Spracherkennungsfehler: {{error}}",
 	"Speech-to-Text Engine": "Sprache-zu-Text-Engine",
-	"SpeechRecognition API is not supported in this browser.": "Die Spracherkennungs-API wird in diesem Browser nicht unterstützt.",
 	"Stop Sequence": "Stop Sequence",
+	"STT Model": "",
 	"STT Settings": "STT-Einstellungen",
 	"Submit": "Senden",
 	"Subtitle (e.g. about the Roman Empire)": "Untertitel (z.B. über das Römische Reich)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "Danke für dein Feedback",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Der Score sollte ein Wert zwischen 0,0 (0 %) und 1,0 (100 %) sein.",
 	"Theme": "Design",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Dadurch werden deine wertvollen Unterhaltungen sicher in der Backend-Datenbank gespeichert. Vielen Dank!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Diese Einstellung wird nicht zwischen Browsern oder Geräten synchronisiert.",
 	"Thorough explanation": "Genaue Erklärung",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Tipp: Aktualisiere mehrere Variablen nacheinander, indem du nach jeder Aktualisierung die Tabulatortaste im Chat-Eingabefeld drückst.",
@@ -481,6 +504,7 @@
 	"to": "für",
 	"To access the available model names for downloading,": "Um auf die verfügbaren Modellnamen zum Herunterladen zuzugreifen,",
 	"To access the GGUF models available for downloading,": "Um auf die verfügbaren GGUF Modelle zum Herunterladen zuzugreifen",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "to chat input.",
 	"Today": "Heute",
 	"Toggle settings": "Einstellungen umschalten",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Probleme beim Zugriff auf Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS-Einstellungen",
+	"TTS Voice": "",
 	"Type": "Art",
 	"Type Hugging Face Resolve (Download) URL": "Gib die Hugging Face Resolve (Download) URL ein",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Ups! Es gab ein Problem bei der Verbindung mit {{provider}}.",
@@ -497,6 +523,7 @@
 	"Update password": "Passwort aktualisieren",
 	"Upload a GGUF model": "GGUF Model hochladen",
 	"Upload Files": "Dateien hochladen",
+	"Upload Pipeline": "",
 	"Upload Progress": "Upload Progress",
 	"URL Mode": "URL Modus",
 	"Use '#' in the prompt input to load and select your documents.": "Verwende '#' in der Prompt-Eingabe, um deine Dokumente zu laden und auszuwählen.",
@@ -515,6 +542,7 @@
 	"Warning": "Warnung",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Warnung: Wenn du dein Einbettungsmodell aktualisierst oder änderst, musst du alle Dokumente erneut importieren.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web Loader Einstellungen",
 	"Web Params": "Web Parameter",
 	"Web Search": "Websuche",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "Wenn aktiviert sendet WebUI externe Anfragen an",
 	"What’s New in": "Was gibt's Neues in",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Wenn die Historie ausgeschaltet ist, werden neue Chats nicht in deiner Historie auf deine Geräte angezeigt.",
-	"Whisper (Local)": "Whisper (Lokal)",
-	"Widescreen Mode": "",
+	"Whisper (Local)": "",
+	"Widescreen Mode": "Widescreen Modus",
 	"Workspace": "Arbeitsbereich",
 	"Write a prompt suggestion (e.g. Who are you?)": "Gebe einen Prompt-Vorschlag ein (z.B. Wer bist du?)",
 	"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.",
 	"Yesterday": "Gestern",
 	"You": "Du",
+	"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Du kannst deine Interaktionen mit LLMs personalisieren, indem du Erinnerungen durch den 'Verwalten'-Button unten hinzufügst, um sie hilfreicher und auf dich zugeschnitten zu machen.",
 	"You cannot clone a base model": "Sie können ein Basismodell nicht klonen",
 	"You have no archived conversations.": "Du hast keine archivierten Unterhaltungen.",
 	"You have shared this chat": "Du hast diesen Chat",
 	"You're a helpful assistant.": "Du bist ein hilfreicher Assistent.",
 	"You're now logged in.": "Du bist nun eingeloggt.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "YouTube",
 	"Youtube Loader Settings": "YouTube-Ladeeinstellungen"
 }

+ 38 - 8
src/lib/i18n/locales/dg-DG/translation.json

@@ -12,6 +12,7 @@
 	"a user": "such user",
 	"About": "Much About",
 	"Account": "Account",
+	"Account Activation Pending": "",
 	"Accurate information": "",
 	"Active Users": "",
 	"Add": "",
@@ -29,6 +30,7 @@
 	"Add User": "",
 	"Adjusting these settings will apply changes universally to all users.": "Adjusting these settings will apply changes to all users. Such universal, very wow.",
 	"admin": "admin",
+	"Admin": "",
 	"Admin Panel": "Admin Panel",
 	"Admin Settings": "Admin Settings",
 	"Advanced Parameters": "Advanced Parameters",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "",
 	"Auto-playback response": "Auto-playback response",
-	"Auto-send input after 3 sec.": "Auto-send after 3 sec.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Base URL is required.",
 	"available!": "available! So excite!",
@@ -71,6 +72,9 @@
 	"Being lazy": "",
 	"Brave Search API Key": "",
 	"Bypass SSL verification for Websites": "",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Cancel",
 	"Capabilities": "",
 	"Change Password": "Change Password",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Citation": "",
+	"Clear memory": "",
 	"Click here for help.": "Click for help. Much assist.",
 	"Click here to": "",
 	"Click here to select": "Click to select",
 	"Click here to select a csv file.": "",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Click to select documents",
 	"click here.": "click here. Such click.",
 	"Click on the user role button to change a user's role.": "Click user role button to change role.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "",
 	"Confirm Password": "Confirm Password",
 	"Connections": "Connections",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Content",
 	"Context Length": "Context Length",
 	"Continue Response": "",
-	"Conversation Mode": "Conversation Mode",
 	"Copied shared chat URL to clipboard!": "",
 	"Copy": "",
 	"Copy last code block": "Copy last code block",
 	"Copy last response": "Copy last response",
 	"Copy Link": "",
 	"Copying to clipboard was successful!": "Copying to clipboard was success! Very success!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Create short phrase, 3-5 word, as header for query, much strict, avoid 'title':",
 	"Create a model": "",
 	"Create Account": "Create Account",
 	"Create new key": "",
@@ -127,12 +132,12 @@
 	"Custom": "Custom",
 	"Customize models for a specific purpose": "",
 	"Dark": "Dark",
+	"Dashboard": "",
 	"Database": "Database",
 	"December": "",
 	"Default": "Default",
 	"Default (Automatic1111)": "Default (Automatic1111)",
 	"Default (SentenceTransformers)": "",
-	"Default (Web API)": "Default (Web API)",
 	"Default Model": "",
 	"Default model updated": "Default model much updated",
 	"Default Prompt Suggestions": "Default Prompt Suggestions",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Discover a prompt",
 	"Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts",
 	"Discover, download, and explore model presets": "Discover, download, and explore model presets",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Display username instead of You in Chat",
 	"Document": "Document",
 	"Document Settings": "Document Settings",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Export Mappings of Dogos",
 	"Export Models": "",
 	"Export Prompts": "Export Promptos",
+	"External Models": "",
 	"Failed to create API Key.": "",
 	"Failed to read clipboard contents": "Failed to read clipboard borks",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "",
 	"General": "Woweral",
 	"General Settings": "General Doge Settings",
+	"Generate Image": "",
 	"Generating search query": "",
 	"Generation Info": "",
 	"Good Response": "",
@@ -252,6 +260,7 @@
 	"Info": "",
 	"Input commands": "Input commands",
 	"Install from Github URL": "",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "",
 	"January": "",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT Borken",
 	"Keep Alive": "Keep Wow",
 	"Keyboard shortcuts": "Keyboard Barkcuts",
+	"Knowledge": "",
 	"Language": "Doge Speak",
 	"Last Active": "",
 	"Light": "Light",
-	"Listening...": "Listening...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs can make borks. Verify important info.",
+	"Local Models": "",
 	"LTR": "",
 	"Made by OpenWebUI Community": "Made by OpenWebUI Community",
 	"Make sure to enclose them with": "Make sure to enclose them with",
+	"Manage": "",
 	"Manage Models": "Manage Wowdels",
 	"Manage Ollama Models": "Manage Ollama Wowdels",
 	"Manage Pipelines": "",
@@ -307,6 +319,7 @@
 	"Name your model": "",
 	"New Chat": "New Bark",
 	"New Password": "New Barkword",
+	"No documents found": "",
 	"No results found": "",
 	"No search query generated": "",
 	"No source available": "No source available",
@@ -323,6 +336,7 @@
 	"Ollama": "",
 	"Ollama API": "",
 	"Ollama API disabled": "",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama Version",
 	"On": "On",
 	"Only": "Only",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "",
 	"PDF Extract Images (OCR)": "PDF Extract Wowmages (OCR)",
 	"pending": "pending",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}",
 	"Personalization": "Personalization",
 	"Pipelines": "",
@@ -367,6 +383,7 @@
 	"Read Aloud": "",
 	"Record voice": "Record Bark",
 	"Redirecting you to OpenWebUI Community": "Redirecting you to OpenWebUI Community",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "",
 	"Regenerate": "",
 	"Release Notes": "Release Borks",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "",
+	"Running": "",
 	"Save": "Save much wow",
 	"Save & Create": "Save & Create much create",
 	"Save & Update": "Save & Update much update",
@@ -398,6 +416,8 @@
 	"Search Documents": "Search Documents much find",
 	"Search Models": "",
 	"Search Prompts": "Search Prompts much wow",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "",
 	"Searched {{count}} sites_one": "",
 	"Searched {{count}} sites_other": "",
@@ -407,12 +427,14 @@
 	"See what's new": "See what's new so amaze",
 	"Seed": "Seed very plant",
 	"Select a base model": "",
+	"Select a engine": "",
 	"Select a mode": "Select a mode very choose",
 	"Select a model": "Select a model much choice",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select an Ollama instance": "Select an Ollama instance very choose",
 	"Select model": "Select model much choice",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "",
 	"Send": "",
 	"Send a Message": "Send a Message much message",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Set Default Model much model",
 	"Set embedding model (e.g. {{model}})": "",
 	"Set Image Size": "Set Image Size very size",
-	"Set Model": "Set Model so speak",
 	"Set reranking model (e.g. {{model}})": "",
 	"Set Steps": "Set Steps so many steps",
 	"Set Task Model": "",
@@ -449,8 +470,8 @@
 	"Source": "Source",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}} so error",
 	"Speech-to-Text Engine": "Speech-to-Text Engine much speak",
-	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API is not supported in this browser. Much sad.",
 	"Stop Sequence": "Stop Sequence much stop",
+	"STT Model": "",
 	"STT Settings": "STT Settings very settings",
 	"Submit": "Submit much submit",
 	"Subtitle (e.g. about the Roman Empire)": "",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "",
 	"Theme": "Theme much theme",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "This ensures that your valuable conversations are securely saved to your backend database. Thank you! Much secure!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "This setting does not sync across browsers or devices. Very not sync.",
 	"Thorough explanation": "",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement. Much tip!",
@@ -481,6 +504,7 @@
 	"to": "to very to",
 	"To access the available model names for downloading,": "To access the available model names for downloading, much access",
 	"To access the GGUF models available for downloading,": "To access the GGUF models available for downloading, much access",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "to chat input. Very chat.",
 	"Today": "",
 	"Toggle settings": "Toggle settings much toggle",
@@ -488,7 +512,9 @@
 	"Top K": "Top K very top",
 	"Top P": "Top P very top",
 	"Trouble accessing Ollama?": "Trouble accessing Ollama? Much trouble?",
+	"TTS Model": "",
 	"TTS Settings": "TTS Settings much settings",
+	"TTS Voice": "",
 	"Type": "",
 	"Type Hugging Face Resolve (Download) URL": "Type Hugging Face Resolve (Download) URL much download",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! There was an issue connecting to {{provider}}. Much uh-oh!",
@@ -497,6 +523,7 @@
 	"Update password": "Update password much change",
 	"Upload a GGUF model": "Upload a GGUF model very upload",
 	"Upload Files": "",
+	"Upload Pipeline": "",
 	"Upload Progress": "Upload Progress much progress",
 	"URL Mode": "URL Mode much mode",
 	"Use '#' in the prompt input to load and select your documents.": "Use '#' in the prompt input to load and select your documents. Much use.",
@@ -515,6 +542,7 @@
 	"Warning": "",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "",
 	"Web": "Web very web",
+	"Web API": "",
 	"Web Loader Settings": "",
 	"Web Params": "",
 	"Web Search": "",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI will make requests to much request",
 	"What’s New in": "What’s New in much new",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "When history is turned off, new chats on this browser won't appear in your history on any of your devices. Much history.",
-	"Whisper (Local)": "Whisper (Local) much whisper",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "",
 	"Write a prompt suggestion (e.g. Who are you?)": "Write a prompt suggestion (e.g. Who are you?) much suggest",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Write a summary in 50 words that summarizes [topic or keyword]. Much summarize.",
 	"Yesterday": "",
 	"You": "",
+	"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 clone a base model": "",
 	"You have no archived conversations.": "",
 	"You have shared this chat": "",
 	"You're a helpful assistant.": "You're a helpful assistant. Much helpful.",
 	"You're now logged in.": "You're now logged in. Much logged.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "",
 	"Youtube Loader Settings": ""
 }

+ 36 - 6
src/lib/i18n/locales/en-GB/translation.json

@@ -12,6 +12,7 @@
 	"a user": "",
 	"About": "",
 	"Account": "",
+	"Account Activation Pending": "",
 	"Accurate information": "",
 	"Active Users": "",
 	"Add": "",
@@ -29,6 +30,7 @@
 	"Add User": "",
 	"Adjusting these settings will apply changes universally to all users.": "",
 	"admin": "",
+	"Admin": "",
 	"Admin Panel": "",
 	"Admin Settings": "",
 	"Advanced Parameters": "",
@@ -59,7 +61,6 @@
 	"Audio": "",
 	"August": "",
 	"Auto-playback response": "",
-	"Auto-send input after 3 sec.": "",
 	"AUTOMATIC1111 Base URL": "",
 	"AUTOMATIC1111 Base URL is required.": "",
 	"available!": "",
@@ -71,6 +72,9 @@
 	"Being lazy": "",
 	"Brave Search API Key": "",
 	"Bypass SSL verification for Websites": "",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "",
 	"Capabilities": "",
 	"Change Password": "",
@@ -88,10 +92,12 @@
 	"Chunk Params": "",
 	"Chunk Size": "",
 	"Citation": "",
+	"Clear memory": "",
 	"Click here for help.": "",
 	"Click here to": "",
 	"Click here to select": "",
 	"Click here to select a csv file.": "",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "",
 	"click here.": "",
 	"Click on the user role button to change a user's role.": "",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "",
 	"Confirm Password": "",
 	"Connections": "",
+	"Contact Admin for WebUI Access": "",
 	"Content": "",
 	"Context Length": "",
 	"Continue Response": "",
-	"Conversation Mode": "",
 	"Copied shared chat URL to clipboard!": "",
 	"Copy": "",
 	"Copy last code block": "",
 	"Copy last response": "",
 	"Copy Link": "",
 	"Copying to clipboard was successful!": "",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "",
 	"Create a model": "",
 	"Create Account": "",
 	"Create new key": "",
@@ -127,12 +132,12 @@
 	"Custom": "",
 	"Customize models for a specific purpose": "",
 	"Dark": "",
+	"Dashboard": "",
 	"Database": "",
 	"December": "",
 	"Default": "",
 	"Default (Automatic1111)": "",
 	"Default (SentenceTransformers)": "",
-	"Default (Web API)": "",
 	"Default Model": "",
 	"Default model updated": "",
 	"Default Prompt Suggestions": "",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "",
 	"Discover, download, and explore custom prompts": "",
 	"Discover, download, and explore model presets": "",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "",
 	"Document": "",
 	"Document Settings": "",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "",
 	"Export Models": "",
 	"Export Prompts": "",
+	"External Models": "",
 	"Failed to create API Key.": "",
 	"Failed to read clipboard contents": "",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "",
 	"General": "",
 	"General Settings": "",
+	"Generate Image": "",
 	"Generating search query": "",
 	"Generation Info": "",
 	"Good Response": "",
@@ -252,6 +260,7 @@
 	"Info": "",
 	"Input commands": "",
 	"Install from Github URL": "",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "",
 	"Invalid Tag": "",
 	"January": "",
@@ -264,14 +273,17 @@
 	"JWT Token": "",
 	"Keep Alive": "",
 	"Keyboard shortcuts": "",
+	"Knowledge": "",
 	"Language": "",
 	"Last Active": "",
 	"Light": "",
 	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "",
+	"Local Models": "",
 	"LTR": "",
 	"Made by OpenWebUI Community": "",
 	"Make sure to enclose them with": "",
+	"Manage": "",
 	"Manage Models": "",
 	"Manage Ollama Models": "",
 	"Manage Pipelines": "",
@@ -307,6 +319,7 @@
 	"Name your model": "",
 	"New Chat": "",
 	"New Password": "",
+	"No documents found": "",
 	"No results found": "",
 	"No search query generated": "",
 	"No source available": "",
@@ -323,6 +336,7 @@
 	"Ollama": "",
 	"Ollama API": "",
 	"Ollama API disabled": "",
+	"Ollama API is disabled": "",
 	"Ollama Version": "",
 	"On": "",
 	"Only": "",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "",
 	"PDF Extract Images (OCR)": "",
 	"pending": "",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "",
 	"Personalization": "",
 	"Pipelines": "",
@@ -367,6 +383,7 @@
 	"Read Aloud": "",
 	"Record voice": "",
 	"Redirecting you to OpenWebUI Community": "",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "",
 	"Regenerate": "",
 	"Release Notes": "",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "",
 	"Rosé Pine Dawn": "",
 	"RTL": "",
+	"Running": "",
 	"Save": "",
 	"Save & Create": "",
 	"Save & Update": "",
@@ -398,6 +416,8 @@
 	"Search Documents": "",
 	"Search Models": "",
 	"Search Prompts": "",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "",
 	"Searched {{count}} sites_one": "",
 	"Searched {{count}} sites_other": "",
@@ -407,12 +427,14 @@
 	"See what's new": "",
 	"Seed": "",
 	"Select a base model": "",
+	"Select a engine": "",
 	"Select a mode": "",
 	"Select a model": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select an Ollama instance": "",
 	"Select model": "",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "",
 	"Send": "",
 	"Send a Message": "",
@@ -425,7 +447,6 @@
 	"Set Default Model": "",
 	"Set embedding model (e.g. {{model}})": "",
 	"Set Image Size": "",
-	"Set Model": "",
 	"Set reranking model (e.g. {{model}})": "",
 	"Set Steps": "",
 	"Set Task Model": "",
@@ -449,8 +470,8 @@
 	"Source": "",
 	"Speech recognition error: {{error}}": "",
 	"Speech-to-Text Engine": "",
-	"SpeechRecognition API is not supported in this browser.": "",
 	"Stop Sequence": "",
+	"STT Model": "",
 	"STT Settings": "",
 	"Submit": "",
 	"Subtitle (e.g. about the Roman Empire)": "",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "",
 	"Theme": "",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "",
 	"Thorough explanation": "",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "",
@@ -481,6 +504,7 @@
 	"to": "",
 	"To access the available model names for downloading,": "",
 	"To access the GGUF models available for downloading,": "",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "",
 	"Today": "",
 	"Toggle settings": "",
@@ -488,7 +512,9 @@
 	"Top K": "",
 	"Top P": "",
 	"Trouble accessing Ollama?": "",
+	"TTS Model": "",
 	"TTS Settings": "",
+	"TTS Voice": "",
 	"Type": "",
 	"Type Hugging Face Resolve (Download) URL": "",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "",
@@ -497,6 +523,7 @@
 	"Update password": "",
 	"Upload a GGUF model": "",
 	"Upload Files": "",
+	"Upload Pipeline": "",
 	"Upload Progress": "",
 	"URL Mode": "",
 	"Use '#' in the prompt input to load and select your documents.": "",
@@ -515,6 +542,7 @@
 	"Warning": "",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "",
 	"Web": "",
+	"Web API": "",
 	"Web Loader Settings": "",
 	"Web Params": "",
 	"Web Search": "",
@@ -532,11 +560,13 @@
 	"Write a summary in 50 words that summarizes [topic or keyword].": "",
 	"Yesterday": "",
 	"You": "",
+	"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 clone a base model": "",
 	"You have no archived conversations.": "",
 	"You have shared this chat": "",
 	"You're a helpful assistant.": "",
 	"You're now logged in.": "",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "",
 	"Youtube Loader Settings": ""
 }

+ 36 - 6
src/lib/i18n/locales/en-US/translation.json

@@ -12,6 +12,7 @@
 	"a user": "",
 	"About": "",
 	"Account": "",
+	"Account Activation Pending": "",
 	"Accurate information": "",
 	"Active Users": "",
 	"Add": "",
@@ -29,6 +30,7 @@
 	"Add User": "",
 	"Adjusting these settings will apply changes universally to all users.": "",
 	"admin": "",
+	"Admin": "",
 	"Admin Panel": "",
 	"Admin Settings": "",
 	"Advanced Parameters": "",
@@ -59,7 +61,6 @@
 	"Audio": "",
 	"August": "",
 	"Auto-playback response": "",
-	"Auto-send input after 3 sec.": "",
 	"AUTOMATIC1111 Base URL": "",
 	"AUTOMATIC1111 Base URL is required.": "",
 	"available!": "",
@@ -71,6 +72,9 @@
 	"Being lazy": "",
 	"Brave Search API Key": "",
 	"Bypass SSL verification for Websites": "",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "",
 	"Capabilities": "",
 	"Change Password": "",
@@ -88,10 +92,12 @@
 	"Chunk Params": "",
 	"Chunk Size": "",
 	"Citation": "",
+	"Clear memory": "",
 	"Click here for help.": "",
 	"Click here to": "",
 	"Click here to select": "",
 	"Click here to select a csv file.": "",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "",
 	"click here.": "",
 	"Click on the user role button to change a user's role.": "",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "",
 	"Confirm Password": "",
 	"Connections": "",
+	"Contact Admin for WebUI Access": "",
 	"Content": "",
 	"Context Length": "",
 	"Continue Response": "",
-	"Conversation Mode": "",
 	"Copied shared chat URL to clipboard!": "",
 	"Copy": "",
 	"Copy last code block": "",
 	"Copy last response": "",
 	"Copy Link": "",
 	"Copying to clipboard was successful!": "",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "",
 	"Create a model": "",
 	"Create Account": "",
 	"Create new key": "",
@@ -127,12 +132,12 @@
 	"Custom": "",
 	"Customize models for a specific purpose": "",
 	"Dark": "",
+	"Dashboard": "",
 	"Database": "",
 	"December": "",
 	"Default": "",
 	"Default (Automatic1111)": "",
 	"Default (SentenceTransformers)": "",
-	"Default (Web API)": "",
 	"Default Model": "",
 	"Default model updated": "",
 	"Default Prompt Suggestions": "",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "",
 	"Discover, download, and explore custom prompts": "",
 	"Discover, download, and explore model presets": "",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "",
 	"Document": "",
 	"Document Settings": "",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "",
 	"Export Models": "",
 	"Export Prompts": "",
+	"External Models": "",
 	"Failed to create API Key.": "",
 	"Failed to read clipboard contents": "",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "",
 	"General": "",
 	"General Settings": "",
+	"Generate Image": "",
 	"Generating search query": "",
 	"Generation Info": "",
 	"Good Response": "",
@@ -252,6 +260,7 @@
 	"Info": "",
 	"Input commands": "",
 	"Install from Github URL": "",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "",
 	"Invalid Tag": "",
 	"January": "",
@@ -264,14 +273,17 @@
 	"JWT Token": "",
 	"Keep Alive": "",
 	"Keyboard shortcuts": "",
+	"Knowledge": "",
 	"Language": "",
 	"Last Active": "",
 	"Light": "",
 	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "",
+	"Local Models": "",
 	"LTR": "",
 	"Made by OpenWebUI Community": "",
 	"Make sure to enclose them with": "",
+	"Manage": "",
 	"Manage Models": "",
 	"Manage Ollama Models": "",
 	"Manage Pipelines": "",
@@ -307,6 +319,7 @@
 	"Name your model": "",
 	"New Chat": "",
 	"New Password": "",
+	"No documents found": "",
 	"No results found": "",
 	"No search query generated": "",
 	"No source available": "",
@@ -323,6 +336,7 @@
 	"Ollama": "",
 	"Ollama API": "",
 	"Ollama API disabled": "",
+	"Ollama API is disabled": "",
 	"Ollama Version": "",
 	"On": "",
 	"Only": "",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "",
 	"PDF Extract Images (OCR)": "",
 	"pending": "",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "",
 	"Personalization": "",
 	"Pipelines": "",
@@ -367,6 +383,7 @@
 	"Read Aloud": "",
 	"Record voice": "",
 	"Redirecting you to OpenWebUI Community": "",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "",
 	"Regenerate": "",
 	"Release Notes": "",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "",
 	"Rosé Pine Dawn": "",
 	"RTL": "",
+	"Running": "",
 	"Save": "",
 	"Save & Create": "",
 	"Save & Update": "",
@@ -398,6 +416,8 @@
 	"Search Documents": "",
 	"Search Models": "",
 	"Search Prompts": "",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "",
 	"Searched {{count}} sites_one": "",
 	"Searched {{count}} sites_other": "",
@@ -407,12 +427,14 @@
 	"See what's new": "",
 	"Seed": "",
 	"Select a base model": "",
+	"Select a engine": "",
 	"Select a mode": "",
 	"Select a model": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select an Ollama instance": "",
 	"Select model": "",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "",
 	"Send": "",
 	"Send a Message": "",
@@ -425,7 +447,6 @@
 	"Set Default Model": "",
 	"Set embedding model (e.g. {{model}})": "",
 	"Set Image Size": "",
-	"Set Model": "",
 	"Set reranking model (e.g. {{model}})": "",
 	"Set Steps": "",
 	"Set Task Model": "",
@@ -449,8 +470,8 @@
 	"Source": "",
 	"Speech recognition error: {{error}}": "",
 	"Speech-to-Text Engine": "",
-	"SpeechRecognition API is not supported in this browser.": "",
 	"Stop Sequence": "",
+	"STT Model": "",
 	"STT Settings": "",
 	"Submit": "",
 	"Subtitle (e.g. about the Roman Empire)": "",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "",
 	"Theme": "",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "",
 	"Thorough explanation": "",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "",
@@ -481,6 +504,7 @@
 	"to": "",
 	"To access the available model names for downloading,": "",
 	"To access the GGUF models available for downloading,": "",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "",
 	"Today": "",
 	"Toggle settings": "",
@@ -488,7 +512,9 @@
 	"Top K": "",
 	"Top P": "",
 	"Trouble accessing Ollama?": "",
+	"TTS Model": "",
 	"TTS Settings": "",
+	"TTS Voice": "",
 	"Type": "",
 	"Type Hugging Face Resolve (Download) URL": "",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "",
@@ -497,6 +523,7 @@
 	"Update password": "",
 	"Upload a GGUF model": "",
 	"Upload Files": "",
+	"Upload Pipeline": "",
 	"Upload Progress": "",
 	"URL Mode": "",
 	"Use '#' in the prompt input to load and select your documents.": "",
@@ -515,6 +542,7 @@
 	"Warning": "",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "",
 	"Web": "",
+	"Web API": "",
 	"Web Loader Settings": "",
 	"Web Params": "",
 	"Web Search": "",
@@ -532,11 +560,13 @@
 	"Write a summary in 50 words that summarizes [topic or keyword].": "",
 	"Yesterday": "",
 	"You": "",
+	"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 clone a base model": "",
 	"You have no archived conversations.": "",
 	"You have shared this chat": "",
 	"You're a helpful assistant.": "",
 	"You're now logged in.": "",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "",
 	"Youtube Loader Settings": ""
 }

+ 38 - 8
src/lib/i18n/locales/es-ES/translation.json

@@ -12,6 +12,7 @@
 	"a user": "un usuario",
 	"About": "Sobre nosotros",
 	"Account": "Cuenta",
+	"Account Activation Pending": "",
 	"Accurate information": "Información precisa",
 	"Active Users": "",
 	"Add": "Agregar",
@@ -29,6 +30,7 @@
 	"Add User": "Agregar Usuario",
 	"Adjusting these settings will apply changes universally to all users.": "Ajustar estas opciones aplicará los cambios universalmente a todos los usuarios.",
 	"admin": "admin",
+	"Admin": "",
 	"Admin Panel": "Panel de Administración",
 	"Admin Settings": "Configuración de Administrador",
 	"Advanced Parameters": "Parámetros Avanzados",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Agosto",
 	"Auto-playback response": "Respuesta de reproducción automática",
-	"Auto-send input after 3 sec.": "Envía la información entrada automáticamente luego de 3 segundos.",
 	"AUTOMATIC1111 Base URL": "Dirección URL de AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "La dirección URL de AUTOMATIC1111 es requerida.",
 	"available!": "¡disponible!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Ser perezoso",
 	"Brave Search API Key": "Clave de API de Brave Search",
 	"Bypass SSL verification for Websites": "Desactivar la verificación SSL para sitios web",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Cancelar",
 	"Capabilities": "Capacidades",
 	"Change Password": "Cambia la Contraseña",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parámetros de fragmentos",
 	"Chunk Size": "Tamaño de fragmentos",
 	"Citation": "Cita",
+	"Clear memory": "",
 	"Click here for help.": "Presiona aquí para obtener ayuda.",
 	"Click here to": "Presiona aquí para",
 	"Click here to select": "Presiona aquí para seleccionar",
 	"Click here to select a csv file.": "Presiona aquí para seleccionar un archivo csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Presiona aquí para seleccionar documentos",
 	"click here.": "Presiona aquí.",
 	"Click on the user role button to change a user's role.": "Presiona en el botón de roles del usuario para cambiar su rol.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Solicitudes simultáneas",
 	"Confirm Password": "Confirmar Contraseña",
 	"Connections": "Conexiones",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Contenido",
 	"Context Length": "Longitud del contexto",
 	"Continue Response": "Continuar Respuesta",
-	"Conversation Mode": "Modo de Conversación",
 	"Copied shared chat URL to clipboard!": "¡URL de chat compartido copiado al portapapeles!",
 	"Copy": "Copiar",
 	"Copy last code block": "Copia el último bloque de código",
 	"Copy last response": "Copia la última respuesta",
 	"Copy Link": "Copiar enlace",
 	"Copying to clipboard was successful!": "¡La copia al portapapeles se ha realizado correctamente!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Cree una frase concisa de 3 a 5 palabras como encabezado para la siguiente consulta, respetando estrictamente el límite de 3 a 5 palabras y evitando el uso de la palabra 'título':",
 	"Create a model": "Crear un modelo",
 	"Create Account": "Crear una cuenta",
 	"Create new key": "Crear una nueva clave",
@@ -127,12 +132,12 @@
 	"Custom": "Personalizado",
 	"Customize models for a specific purpose": "Personalizar modelos para un propósito específico",
 	"Dark": "Oscuro",
+	"Dashboard": "",
 	"Database": "Base de datos",
 	"December": "Diciembre",
 	"Default": "Por defecto",
 	"Default (Automatic1111)": "Por defecto (Automatic1111)",
 	"Default (SentenceTransformers)": "Por defecto (SentenceTransformers)",
-	"Default (Web API)": "Por defecto (Web API)",
 	"Default Model": "Modelo predeterminado",
 	"Default model updated": "El modelo por defecto ha sido actualizado",
 	"Default Prompt Suggestions": "Sugerencias de mensajes por defecto",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Descubre un Prompt",
 	"Discover, download, and explore custom prompts": "Descubre, descarga, y explora Prompts personalizados",
 	"Discover, download, and explore model presets": "Descubre, descarga y explora ajustes preestablecidos de modelos",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Mostrar el nombre de usuario en lugar de Usted en el chat",
 	"Document": "Documento",
 	"Document Settings": "Configuración del Documento",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exportar el mapeo de documentos",
 	"Export Models": "Modelos de exportación",
 	"Export Prompts": "Exportar Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "No se pudo crear la clave API.",
 	"Failed to read clipboard contents": "No se pudo leer el contenido del portapapeles",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Penalización de frecuencia",
 	"General": "General",
 	"General Settings": "Opciones Generales",
+	"Generate Image": "",
 	"Generating search query": "Generación de consultas de búsqueda",
 	"Generation Info": "Información de Generación",
 	"Good Response": "Buena Respuesta",
@@ -252,6 +260,7 @@
 	"Info": "Información",
 	"Input commands": "Ingresar comandos",
 	"Install from Github URL": "Instalar desde la URL de Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interfaz",
 	"Invalid Tag": "Etiqueta Inválida",
 	"January": "Enero",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Mantener Vivo",
 	"Keyboard shortcuts": "Atajos de teclado",
+	"Knowledge": "",
 	"Language": "Lenguaje",
 	"Last Active": "Última Actividad",
 	"Light": "Claro",
-	"Listening...": "Escuchando...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Los LLM pueden cometer errores. Verifica la información importante.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Hecho por la comunidad de OpenWebUI",
 	"Make sure to enclose them with": "Asegúrese de adjuntarlos con",
+	"Manage": "",
 	"Manage Models": "Administrar Modelos",
 	"Manage Ollama Models": "Administrar Modelos Ollama",
 	"Manage Pipelines": "Administrar canalizaciones",
@@ -307,6 +319,7 @@
 	"Name your model": "Asigne un nombre a su modelo",
 	"New Chat": "Nuevo Chat",
 	"New Password": "Nueva Contraseña",
+	"No documents found": "",
 	"No results found": "No se han encontrado resultados",
 	"No search query generated": "No se ha generado ninguna consulta de búsqueda",
 	"No source available": "No hay fuente disponible",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API de Ollama deshabilitada",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Versión de Ollama",
 	"On": "Activado",
 	"Only": "Solamente",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF document (.pdf)",
 	"PDF Extract Images (OCR)": "Extraer imágenes de PDF (OCR)",
 	"pending": "pendiente",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permiso denegado al acceder al micrófono: {{error}}",
 	"Personalization": "Personalización",
 	"Pipelines": "Tuberías",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Leer al oído",
 	"Record voice": "Grabar voz",
 	"Redirecting you to OpenWebUI Community": "Redireccionándote a la comunidad OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Rechazado cuando no debería",
 	"Regenerate": "Regenerar",
 	"Release Notes": "Notas de la versión",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Guardar",
 	"Save & Create": "Guardar y Crear",
 	"Save & Update": "Guardar y Actualizar",
@@ -398,6 +416,8 @@
 	"Search Documents": "Buscar Documentos",
 	"Search Models": "Modelos de búsqueda",
 	"Search Prompts": "Buscar Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Recuento de resultados de búsqueda",
 	"Searched {{count}} sites_one": "Buscado {{count}} sites_one",
 	"Searched {{count}} sites_many": "Buscado {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Ver las novedades",
 	"Seed": "Seed",
 	"Select a base model": "Seleccionar un modelo base",
+	"Select a engine": "",
 	"Select a mode": "Selecciona un modo",
 	"Select a model": "Selecciona un modelo",
 	"Select a pipeline": "Selección de una canalización",
 	"Select a pipeline url": "Selección de una dirección URL de canalización",
 	"Select an Ollama instance": "Seleccione una instancia de Ollama",
 	"Select model": "Selecciona un modelo",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Los modelos seleccionados no admiten entradas de imagen",
 	"Send": "Enviar",
 	"Send a Message": "Enviar un Mensaje",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Establecer modelo predeterminado",
 	"Set embedding model (e.g. {{model}})": "Establecer modelo de embedding (ej. {{model}})",
 	"Set Image Size": "Establecer tamaño de imagen",
-	"Set Model": "Establecer el modelo",
 	"Set reranking model (e.g. {{model}})": "Establecer modelo de reranking (ej. {{model}})",
 	"Set Steps": "Establecer Pasos",
 	"Set Task Model": "Establecer modelo de tarea",
@@ -450,8 +471,8 @@
 	"Source": "Fuente",
 	"Speech recognition error: {{error}}": "Error de reconocimiento de voz: {{error}}",
 	"Speech-to-Text Engine": "Motor de voz a texto",
-	"SpeechRecognition API is not supported in this browser.": "La API SpeechRecognition no es compatible con este navegador.",
 	"Stop Sequence": "Detener secuencia",
+	"STT Model": "",
 	"STT Settings": "Configuraciones de STT",
 	"Submit": "Enviar",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítulo (por ejemplo, sobre el Imperio Romano)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "¡Gracias por tu retroalimentación!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "El puntaje debe ser un valor entre 0.0 (0%) y 1.0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Esto garantiza que sus valiosas conversaciones se guarden de forma segura en su base de datos en el backend. ¡Gracias!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Esta configuración no se sincroniza entre navegadores o dispositivos.",
 	"Thorough explanation": "Explicación exhaustiva",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Consejo: Actualice múltiples variables consecutivamente presionando la tecla tab en la entrada del chat después de cada reemplazo.",
@@ -482,6 +505,7 @@
 	"to": "para",
 	"To access the available model names for downloading,": "Para acceder a los nombres de modelos disponibles para descargar,",
 	"To access the GGUF models available for downloading,": "Para acceder a los modelos GGUF disponibles para descargar,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "a la entrada del chat.",
 	"Today": "Hoy",
 	"Toggle settings": "Alternar configuración",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "¿Problemas para acceder a Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Configuración de TTS",
+	"TTS Voice": "",
 	"Type": "Tipo",
 	"Type Hugging Face Resolve (Download) URL": "Escriba la URL (Descarga) de Hugging Face Resolve",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "¡Uh oh! Hubo un problema al conectarse a {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Actualizar contraseña",
 	"Upload a GGUF model": "Subir un modelo GGUF",
 	"Upload Files": "Subir archivos",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progreso de carga",
 	"URL Mode": "Modo de URL",
 	"Use '#' in the prompt input to load and select your documents.": "Utilice '#' en el prompt para cargar y seleccionar sus documentos.",
@@ -516,6 +543,7 @@
 	"Warning": "Advertencia",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Advertencia: Si actualiza o cambia su modelo de inserción, necesitará volver a importar todos los documentos.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web Loader Settings",
 	"Web Params": "Web Params",
 	"Web Search": "Búsqueda en la Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI realizará solicitudes a",
 	"What’s New in": "Novedades en",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Cuando el historial está desactivado, los nuevos chats en este navegador no aparecerán en el historial de ninguno de sus dispositivos..",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Espacio de trabajo",
 	"Write a prompt suggestion (e.g. Who are you?)": "Escribe una sugerencia para un prompt (por ejemplo, ¿quién eres?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Escribe un resumen en 50 palabras que resuma [tema o palabra clave].",
 	"Yesterday": "Ayer",
 	"You": "Usted",
+	"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 clone a base model": "No se puede clonar un modelo base",
 	"You have no archived conversations.": "No tiene conversaciones archivadas.",
 	"You have shared this chat": "Usted ha compartido esta conversación",
 	"You're a helpful assistant.": "Usted es un asistente útil.",
 	"You're now logged in.": "Usted ahora está conectado.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Configuración del cargador de Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/fa-IR/translation.json

@@ -12,6 +12,7 @@
 	"a user": "یک کاربر",
 	"About": "درباره",
 	"Account": "حساب کاربری",
+	"Account Activation Pending": "",
 	"Accurate information": "اطلاعات دقیق",
 	"Active Users": "",
 	"Add": "اضافه کردن",
@@ -29,6 +30,7 @@
 	"Add User": "اضافه کردن کاربر",
 	"Adjusting these settings will apply changes universally to all users.": "با تنظیم این تنظیمات، تغییرات به طور کلی برای همه کاربران اعمال می شود.",
 	"admin": "مدیر",
+	"Admin": "",
 	"Admin Panel": "پنل مدیریت",
 	"Admin Settings": "تنظیمات مدیریت",
 	"Advanced Parameters": "پارامترهای پیشرفته",
@@ -59,7 +61,6 @@
 	"Audio": "صدا",
 	"August": "آگوست",
 	"Auto-playback response": "پخش خودکار پاسخ ",
-	"Auto-send input after 3 sec.": "به طور خودکار ورودی را پس از 3 ثانیه ارسال کن.",
 	"AUTOMATIC1111 Base URL": "پایه URL AUTOMATIC1111 ",
 	"AUTOMATIC1111 Base URL is required.": "به URL پایه AUTOMATIC1111 مورد نیاز است.",
 	"available!": "در دسترس!",
@@ -71,6 +72,9 @@
 	"Being lazy": "حالت سازنده",
 	"Brave Search API Key": "کلید API جستجوی شجاع",
 	"Bypass SSL verification for Websites": "عبور از تأیید SSL برای وب سایت ها",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "لغو",
 	"Capabilities": "قابلیت",
 	"Change Password": "تغییر رمز عبور",
@@ -88,10 +92,12 @@
 	"Chunk Params": "پارامترهای تکه",
 	"Chunk Size": "اندازه تکه",
 	"Citation": "استناد",
+	"Clear memory": "",
 	"Click here for help.": "برای کمک اینجا را کلیک کنید.",
 	"Click here to": "برای کمک اینجا را کلیک کنید.",
 	"Click here to select": "برای انتخاب اینجا کلیک کنید",
 	"Click here to select a csv file.": "برای انتخاب یک فایل csv اینجا را کلیک کنید.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "برای انتخاب اسناد اینجا را کلیک کنید.",
 	"click here.": "اینجا کلیک کنید.",
 	"Click on the user role button to change a user's role.": "برای تغییر نقش کاربر، روی دکمه نقش کاربر کلیک کنید.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "درخواست های همزمان",
 	"Confirm Password": "تایید رمز عبور",
 	"Connections": "ارتباطات",
+	"Contact Admin for WebUI Access": "",
 	"Content": "محتوا",
 	"Context Length": "طول زمینه",
 	"Continue Response": "ادامه پاسخ",
-	"Conversation Mode": "حالت مکالمه",
 	"Copied shared chat URL to clipboard!": "URL چت به کلیپ بورد کپی شد!",
 	"Copy": "کپی",
 	"Copy last code block": "کپی آخرین بلوک کد",
 	"Copy last response": "کپی آخرین پاسخ",
 	"Copy Link": "کپی لینک",
 	"Copying to clipboard was successful!": "کپی کردن در کلیپ بورد با موفقیت انجام شد!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "یک عبارت مختصر و ۳ تا ۵ کلمه ای را به عنوان سرفصل برای پرس و جو زیر ایجاد کنید، به شدت محدودیت ۳-۵ کلمه را رعایت کنید و از استفاده از کلمه 'عنوان' خودداری کنید:",
 	"Create a model": "ایجاد یک مدل",
 	"Create Account": "ساخت حساب کاربری",
 	"Create new key": "ساخت کلید جدید",
@@ -127,12 +132,12 @@
 	"Custom": "دلخواه",
 	"Customize models for a specific purpose": "سفارشی کردن مدل ها برای یک هدف خاص",
 	"Dark": "تیره",
+	"Dashboard": "",
 	"Database": "پایگاه داده",
 	"December": "دسامبر",
 	"Default": "پیشفرض",
 	"Default (Automatic1111)": "پیشفرض (Automatic1111)",
 	"Default (SentenceTransformers)": "پیشفرض (SentenceTransformers)",
-	"Default (Web API)": "پیشفرض (Web API)",
 	"Default Model": "مدل پیشفرض",
 	"Default model updated": "مدل پیشفرض به\u200cروزرسانی شد",
 	"Default Prompt Suggestions": "پیشنهادات پرامپت پیش فرض",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "یک اعلان را کشف کنید",
 	"Discover, download, and explore custom prompts": "پرامپت\u200cهای سفارشی را کشف، دانلود و کاوش کنید",
 	"Discover, download, and explore model presets": "پیش تنظیمات مدل را کشف، دانلود و کاوش کنید",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "نمایش نام کاربری به جای «شما» در چت",
 	"Document": "سند",
 	"Document Settings": "تنظیمات سند",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "اکسپورت از نگاشت اسناد",
 	"Export Models": "مدل های صادرات",
 	"Export Prompts": "اکسپورت از پرامپت\u200cها",
+	"External Models": "",
 	"Failed to create API Key.": "ایجاد کلید API با خطا مواجه شد.",
 	"Failed to read clipboard contents": "خواندن محتوای کلیپ بورد ناموفق بود",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "مجازات فرکانس",
 	"General": "عمومی",
 	"General Settings": "تنظیمات عمومی",
+	"Generate Image": "",
 	"Generating search query": "در حال تولید پرسوجوی جستجو",
 	"Generation Info": "اطلاعات تولید",
 	"Good Response": "پاسخ خوب",
@@ -252,6 +260,7 @@
 	"Info": "اطلاعات",
 	"Input commands": "ورودی دستورات",
 	"Install from Github URL": "نصب از ادرس Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "رابط",
 	"Invalid Tag": "تگ نامعتبر",
 	"January": "ژانویه",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT توکن",
 	"Keep Alive": "Keep Alive",
 	"Keyboard shortcuts": "میانبرهای صفحه کلید",
+	"Knowledge": "",
 	"Language": "زبان",
 	"Last Active": "آخرین فعال",
 	"Light": "روشن",
-	"Listening...": "در حال گوش دادن...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "مدل\u200cهای زبانی بزرگ می\u200cتوانند اشتباه کنند. اطلاعات مهم را راستی\u200cآزمایی کنید.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "ساخته شده توسط OpenWebUI Community",
 	"Make sure to enclose them with": "مطمئن شوید که آنها را با این محصور کنید:",
+	"Manage": "",
 	"Manage Models": "مدیریت مدل\u200cها",
 	"Manage Ollama Models": "مدیریت مدل\u200cهای اولاما",
 	"Manage Pipelines": "مدیریت خطوط لوله",
@@ -307,6 +319,7 @@
 	"Name your model": "نام مدل خود را",
 	"New Chat": "گپ جدید",
 	"New Password": "رمز عبور جدید",
+	"No documents found": "",
 	"No results found": "نتیجه\u200cای یافت نشد",
 	"No search query generated": "پرسوجوی جستجویی ایجاد نشده است",
 	"No source available": "منبعی در دسترس نیست",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API Ollama غیرفعال شد",
+	"Ollama API is disabled": "",
 	"Ollama Version": "نسخه اولاما",
 	"On": "روشن",
 	"Only": "فقط",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF سند (.pdf)",
 	"PDF Extract Images (OCR)": "استخراج تصاویر از PDF (OCR)",
 	"pending": "در انتظار",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "هنگام دسترسی به میکروفون، اجازه داده نشد: {{error}}",
 	"Personalization": "شخصی سازی",
 	"Pipelines": "خط لوله",
@@ -367,6 +383,7 @@
 	"Read Aloud": "خواندن به صورت صوتی",
 	"Record voice": "ضبط صدا",
 	"Redirecting you to OpenWebUI Community": "در حال هدایت به OpenWebUI Community",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "رد شده زمانی که باید نباشد",
 	"Regenerate": "ری\u200cسازی",
 	"Release Notes": "یادداشت\u200cهای انتشار",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "ذخیره",
 	"Save & Create": "ذخیره و ایجاد",
 	"Save & Update": "ذخیره و به\u200cروزرسانی",
@@ -398,6 +416,8 @@
 	"Search Documents": "جستجوی اسناد",
 	"Search Models": "مدل های جستجو",
 	"Search Prompts": "جستجوی پرامپت\u200cها",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "تعداد نتایج جستجو",
 	"Searched {{count}} sites_one": "جستجو {{count}} sites_one",
 	"Searched {{count}} sites_other": "جستجو {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "ببینید موارد جدید چه بوده",
 	"Seed": "Seed",
 	"Select a base model": "انتخاب یک مدل پایه",
+	"Select a engine": "",
 	"Select a mode": "یک حالت انتخاب کنید",
 	"Select a model": "انتخاب یک مدل",
 	"Select a pipeline": "انتخاب یک خط لوله",
 	"Select a pipeline url": "یک ادرس خط لوله را انتخاب کنید",
 	"Select an Ollama instance": "انتخاب یک نمونه از اولاما",
 	"Select model": "انتخاب یک مدل",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "مدل) های (انتخاب شده ورودیهای تصویر را پشتیبانی نمیکند",
 	"Send": "ارسال",
 	"Send a Message": "ارسال یک پیام",
@@ -425,7 +447,6 @@
 	"Set Default Model": "تنظیم مدل پیش فرض",
 	"Set embedding model (e.g. {{model}})": "تنظیم مدل پیچشی (برای مثال {{model}})",
 	"Set Image Size": "تنظیم اندازه تصویر",
-	"Set Model": "تنظیم مدل",
 	"Set reranking model (e.g. {{model}})": "تنظیم مدل ری\u200cراینگ (برای مثال {{model}})",
 	"Set Steps": "تنظیم گام\u200cها",
 	"Set Task Model": "تنظیم مدل تکلیف",
@@ -449,8 +470,8 @@
 	"Source": "منبع",
 	"Speech recognition error: {{error}}": "خطای تشخیص گفتار: {{error}}",
 	"Speech-to-Text Engine": "موتور گفتار به متن",
-	"SpeechRecognition API is not supported in this browser.": "API تشخیص گفتار در این مرورگر پشتیبانی نمی شود.",
 	"Stop Sequence": "توالی توقف",
+	"STT Model": "",
 	"STT Settings": "STT تنظیمات",
 	"Submit": "ارسال",
 	"Subtitle (e.g. about the Roman Empire)": "زیرنویس (برای مثال: درباره رمانی)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "با تشکر از بازخورد شما!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "امتیاز باید یک مقدار بین 0.0 (0%) و 1.0 (100%) باشد.",
 	"Theme": "قالب",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "این تضمین می کند که مکالمات ارزشمند شما به طور ایمن در پایگاه داده بکند ذخیره می شود. تشکر!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "این تنظیم در مرورگرها یا دستگاه\u200cها همگام\u200cسازی نمی\u200cشود.",
 	"Thorough explanation": "توضیح کامل",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "با فشردن کلید Tab در ورودی چت پس از هر بار تعویض، چندین متغیر را به صورت متوالی به روزرسانی کنید.",
@@ -481,6 +504,7 @@
 	"to": "به",
 	"To access the available model names for downloading,": "برای دسترسی به نام مدل های موجود برای دانلود،",
 	"To access the GGUF models available for downloading,": "برای دسترسی به مدل\u200cهای GGUF موجود برای دانلود،",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "در ورودی گپ.",
 	"Today": "امروز",
 	"Toggle settings": "نمایش/عدم نمایش تنظیمات",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "در دسترسی به اولاما مشکل دارید؟",
+	"TTS Model": "",
 	"TTS Settings": "تنظیمات TTS",
+	"TTS Voice": "",
 	"Type": "نوع",
 	"Type Hugging Face Resolve (Download) URL": "مقدار URL دانلود (Resolve) Hugging Face را وارد کنید",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "اوه اوه! مشکلی در اتصال به {{provider}} وجود داشت.",
@@ -497,6 +523,7 @@
 	"Update password": "به روزرسانی رمزعبور",
 	"Upload a GGUF model": "آپلود یک مدل GGUF",
 	"Upload Files": "بارگذاری پروندهها",
+	"Upload Pipeline": "",
 	"Upload Progress": "پیشرفت آپلود",
 	"URL Mode": "حالت URL",
 	"Use '#' in the prompt input to load and select your documents.": "در پرامپت از '#' برای لود و انتخاب اسناد خود استفاده کنید.",
@@ -515,6 +542,7 @@
 	"Warning": "هشدار",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "هشدار: اگر شما به روز کنید یا تغییر دهید مدل شما، باید تمام سند ها را مجددا وارد کنید.",
 	"Web": "وب",
+	"Web API": "",
 	"Web Loader Settings": "تنظیمات لودر وب",
 	"Web Params": "پارامترهای وب",
 	"Web Search": "جستجوی وب",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI درخواست\u200cها را ارسال خواهد کرد به",
 	"What’s New in": "موارد جدید در",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "وقتی سابقه خاموش است، چت\u200cهای جدید در این مرورگر در سابقه شما در هیچ یک از دستگاه\u200cهایتان ظاهر نمی\u200cشوند.",
-	"Whisper (Local)": "ویسپر (محلی)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "محیط کار",
 	"Write a prompt suggestion (e.g. Who are you?)": "یک پیشنهاد پرامپت بنویسید (مثلاً شما کی هستید؟)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "خلاصه ای در 50 کلمه بنویسید که [موضوع یا کلمه کلیدی] را خلاصه کند.",
 	"Yesterday": "دیروز",
 	"You": "شما",
+	"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 clone a base model": "شما نمیتوانید یک مدل پایه را کلون کنید",
 	"You have no archived conversations.": "شما هیچ گفتگوی ذخیره شده ندارید.",
 	"You have shared this chat": "شما این گفتگو را به اشتراک گذاشته اید",
 	"You're a helpful assistant.": "تو یک دستیار سودمند هستی.",
 	"You're now logged in.": "شما اکنون وارد شده\u200cاید.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "یوتیوب",
 	"Youtube Loader Settings": "تنظیمات لودر یوتیوب"
 }

+ 38 - 8
src/lib/i18n/locales/fi-FI/translation.json

@@ -12,6 +12,7 @@
 	"a user": "käyttäjä",
 	"About": "Tietoja",
 	"Account": "Tili",
+	"Account Activation Pending": "",
 	"Accurate information": "Tarkkaa tietoa",
 	"Active Users": "",
 	"Add": "Lisää",
@@ -29,6 +30,7 @@
 	"Add User": "Lisää käyttäjä",
 	"Adjusting these settings will apply changes universally to all users.": "Näiden asetusten säätäminen vaikuttaa kaikkiin käyttäjiin.",
 	"admin": "hallinta",
+	"Admin": "",
 	"Admin Panel": "Hallintapaneeli",
 	"Admin Settings": "Hallinta-asetukset",
 	"Advanced Parameters": "Edistyneet parametrit",
@@ -59,7 +61,6 @@
 	"Audio": "Ääni",
 	"August": "elokuu",
 	"Auto-playback response": "Soita vastaus automaattisesti",
-	"Auto-send input after 3 sec.": "Lähetä syöte automaattisesti 3 sekunnin kuluttua",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111-perus-URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111-perus-URL vaaditaan.",
 	"available!": "saatavilla!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Oli laiska",
 	"Brave Search API Key": "Brave Search API -avain",
 	"Bypass SSL verification for Websites": "Ohita SSL-varmennus verkkosivustoille",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Peruuta",
 	"Capabilities": "Ominaisuuksia",
 	"Change Password": "Vaihda salasana",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Osien parametrit",
 	"Chunk Size": "Osien koko",
 	"Citation": "Sitaatti",
+	"Clear memory": "",
 	"Click here for help.": "Klikkaa tästä saadaksesi apua.",
 	"Click here to": "Klikkaa tästä",
 	"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.": "",
 	"Click here to select documents.": "Klikkaa tästä valitaksesi asiakirjoja.",
 	"click here.": "klikkaa tästä.",
 	"Click on the user role button to change a user's role.": "Klikkaa käyttäjän roolipainiketta vaihtaaksesi käyttäjän roolia.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Samanaikaiset pyynnöt",
 	"Confirm Password": "Vahvista salasana",
 	"Connections": "Yhteydet",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Sisältö",
 	"Context Length": "Kontekstin pituus",
 	"Continue Response": "Jatka vastausta",
-	"Conversation Mode": "Keskustelutila",
 	"Copied shared chat URL to clipboard!": "Jaettu keskustelulinkki kopioitu leikepöydälle!",
 	"Copy": "Kopioi",
 	"Copy last code block": "Kopioi viimeisin koodilohko",
 	"Copy last response": "Kopioi viimeisin vastaus",
 	"Copy Link": "Kopioi linkki",
 	"Copying to clipboard was successful!": "Kopioiminen leikepöydälle onnistui!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Luo tiivis, 3-5 sanan lause otsikoksi seuraavalle kyselylle, noudattaen tiukasti 3-5 sanan rajoitusta ja välttäen sanan 'otsikko' käyttöä:",
 	"Create a model": "Mallin luominen",
 	"Create Account": "Luo tili",
 	"Create new key": "Luo uusi avain",
@@ -127,12 +132,12 @@
 	"Custom": "Mukautettu",
 	"Customize models for a specific purpose": "Mallien mukauttaminen tiettyyn tarkoitukseen",
 	"Dark": "Tumma",
+	"Dashboard": "",
 	"Database": "Tietokanta",
 	"December": "joulukuu",
 	"Default": "Oletus",
 	"Default (Automatic1111)": "Oletus (AUTOMATIC1111)",
 	"Default (SentenceTransformers)": "Oletus (SentenceTransformers)",
-	"Default (Web API)": "Oletus (web-API)",
 	"Default Model": "Oletusmalli",
 	"Default model updated": "Oletusmalli päivitetty",
 	"Default Prompt Suggestions": "Oletuskehotteiden ehdotukset",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Löydä kehote",
 	"Discover, download, and explore custom prompts": "Löydä ja lataa mukautettuja kehotteita",
 	"Discover, download, and explore model presets": "Löydä ja lataa mallien esiasetuksia",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Näytä käyttäjänimi keskustelussa",
 	"Document": "Asiakirja",
 	"Document Settings": "Asiakirja-asetukset",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Vie asiakirjakartoitus",
 	"Export Models": "Vie malleja",
 	"Export Prompts": "Vie kehotteet",
+	"External Models": "",
 	"Failed to create API Key.": "API-avaimen luonti epäonnistui.",
 	"Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Taajuussakko",
 	"General": "Yleinen",
 	"General Settings": "Yleisasetukset",
+	"Generate Image": "",
 	"Generating search query": "Hakukyselyn luominen",
 	"Generation Info": "Generointitiedot",
 	"Good Response": "Hyvä vastaus",
@@ -252,6 +260,7 @@
 	"Info": "Info",
 	"Input commands": "Syötä komennot",
 	"Install from Github URL": "Asenna Githubin URL-osoitteesta",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Käyttöliittymä",
 	"Invalid Tag": "Virheellinen tagi",
 	"January": "tammikuu",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT-token",
 	"Keep Alive": "Pysy aktiivisena",
 	"Keyboard shortcuts": "Pikanäppäimet",
+	"Knowledge": "",
 	"Language": "Kieli",
 	"Last Active": "Viimeksi aktiivinen",
 	"Light": "Vaalea",
-	"Listening...": "Kuunnellaan...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Kielimallit voivat tehdä virheitä. Varmista tärkeät tiedot.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Tehnyt OpenWebUI-yhteisö",
 	"Make sure to enclose them with": "Varmista, että suljet ne",
+	"Manage": "",
 	"Manage Models": "Hallitse malleja",
 	"Manage Ollama Models": "Hallitse Ollama-malleja",
 	"Manage Pipelines": "Hallitse putkia",
@@ -307,6 +319,7 @@
 	"Name your model": "Mallin nimeäminen",
 	"New Chat": "Uusi keskustelu",
 	"New Password": "Uusi salasana",
+	"No documents found": "",
 	"No results found": "Ei tuloksia",
 	"No search query generated": "Hakukyselyä ei luotu",
 	"No source available": "Ei lähdettä saatavilla",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API poistettu käytöstä",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama-versio",
 	"On": "Päällä",
 	"Only": "Vain",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF-tiedosto (.pdf)",
 	"PDF Extract Images (OCR)": "PDF-tiedoston kuvien erottelu (OCR)",
 	"pending": "odottaa",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Mikrofonin käyttöoikeus evätty: {{error}}",
 	"Personalization": "Henkilökohtaisuus",
 	"Pipelines": "Putkistot",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Lue ääneen",
 	"Record voice": "Nauhoita ääni",
 	"Redirecting you to OpenWebUI Community": "Ohjataan sinut OpenWebUI-yhteisöön",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Kieltäytyi, vaikka ei olisi pitänyt",
 	"Regenerate": "Uudelleenluo",
 	"Release Notes": "Julkaisutiedot",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosee-mänty",
 	"Rosé Pine Dawn": "Aamuinen Rosee-mänty",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Tallenna",
 	"Save & Create": "Tallenna ja luo",
 	"Save & Update": "Tallenna ja päivitä",
@@ -398,6 +416,8 @@
 	"Search Documents": "Hae asiakirjoja",
 	"Search Models": "Hae malleja",
 	"Search Prompts": "Hae kehotteita",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Hakutulosten määrä",
 	"Searched {{count}} sites_one": "Haettu {{count}} sites_one",
 	"Searched {{count}} sites_other": "Haku {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "Katso, mitä uutta",
 	"Seed": "Siemen",
 	"Select a base model": "Valitse perusmalli",
+	"Select a engine": "",
 	"Select a mode": "Valitse tila",
 	"Select a model": "Valitse malli",
 	"Select a pipeline": "Valitse putki",
 	"Select a pipeline url": "Valitse putken URL-osoite",
 	"Select an Ollama instance": "Valitse Ollama-instanssi",
 	"Select model": "Valitse malli",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Valitut mallit eivät tue kuvasyötteitä",
 	"Send": "Lähetä",
 	"Send a Message": "Lähetä viesti",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Aseta oletusmalli",
 	"Set embedding model (e.g. {{model}})": "Aseta upotusmalli (esim. {{model}})",
 	"Set Image Size": "Aseta kuvan koko",
-	"Set Model": "Aseta malli",
 	"Set reranking model (e.g. {{model}})": "Aseta uudelleenpisteytysmalli (esim. {{model}})",
 	"Set Steps": "Aseta askelmäärä",
 	"Set Task Model": "Aseta tehtävämalli",
@@ -449,8 +470,8 @@
 	"Source": "Lähde",
 	"Speech recognition error: {{error}}": "Puheentunnistusvirhe: {{error}}",
 	"Speech-to-Text Engine": "Puheentunnistusmoottori",
-	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition-rajapinta ei ole tuettu tässä selaimessa.",
 	"Stop Sequence": "Lopetussekvenssi",
+	"STT Model": "",
 	"STT Settings": "Puheentunnistusasetukset",
 	"Submit": "Lähetä",
 	"Subtitle (e.g. about the Roman Empire)": "Alaotsikko (esim. Rooman valtakunnasta)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "Kiitos palautteestasi!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Pisteytyksen tulee olla arvo välillä 0.0 (0%) ja 1.0 (100%).",
 	"Theme": "Teema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Tämä varmistaa, että arvokkaat keskustelusi tallennetaan turvallisesti backend-tietokantaasi. Kiitos!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Tämä asetus ei synkronoidu selainten tai laitteiden välillä.",
 	"Thorough explanation": "Perusteellinen selitys",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Vinkki: Päivitä useita muuttujapaikkoja peräkkäin painamalla tabulaattoria keskustelusyötteessä jokaisen korvauksen jälkeen.",
@@ -481,6 +504,7 @@
 	"to": "->",
 	"To access the available model names for downloading,": "Päästäksesi käsiksi ladattavissa oleviin mallinimiin,",
 	"To access the GGUF models available for downloading,": "Päästäksesi käsiksi ladattavissa oleviin GGUF-malleihin,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "keskustelusyötteeseen.",
 	"Today": "Tänään",
 	"Toggle settings": "Kytke asetukset",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Ongelmia Ollama-yhteydessä?",
+	"TTS Model": "",
 	"TTS Settings": "Puheentuottamisasetukset",
+	"TTS Voice": "",
 	"Type": "Tyyppi",
 	"Type Hugging Face Resolve (Download) URL": "Kirjoita Hugging Face -resolve-osoite",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Voi ei! Yhteysongelma {{provider}}:n kanssa.",
@@ -497,6 +523,7 @@
 	"Update password": "Päivitä salasana",
 	"Upload a GGUF model": "Lataa GGUF-malli",
 	"Upload Files": "Lataa tiedostoja",
+	"Upload Pipeline": "",
 	"Upload Progress": "Latauksen eteneminen",
 	"URL Mode": "URL-tila",
 	"Use '#' in the prompt input to load and select your documents.": "Käytä '#' syötteessä ladataksesi ja valitaksesi asiakirjoja.",
@@ -515,6 +542,7 @@
 	"Warning": "Varoitus",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Varoitus: Jos päivität tai vaihdat upotusmallia, sinun on tuotava kaikki asiakirjat uudelleen.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web Loader asetukset",
 	"Web Params": "Web-parametrit",
 	"Web Search": "Web-haku",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI tekee pyyntöjä",
 	"What’s New in": "Mitä uutta",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Kun historia on pois päältä, uudet keskustelut tässä selaimessa eivät näy historiassasi millään laitteellasi.",
-	"Whisper (Local)": "Whisper (paikallinen)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Työtilat",
 	"Write a prompt suggestion (e.g. Who are you?)": "Kirjoita ehdotettu kehote (esim. Kuka olet?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Kirjoita 50 sanan yhteenveto, joka tiivistää [aihe tai avainsana].",
 	"Yesterday": "Eilen",
 	"You": "Sinä",
+	"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 clone a base model": "Perusmallia ei voi kloonata",
 	"You have no archived conversations.": "Sinulla ei ole arkistoituja keskusteluja.",
 	"You have shared this chat": "Olet jakanut tämän keskustelun",
 	"You're a helpful assistant.": "Olet avulias apulainen.",
 	"You're now logged in.": "Olet nyt kirjautunut sisään.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube Loader-asetukset"
 }

+ 38 - 8
src/lib/i18n/locales/fr-CA/translation.json

@@ -12,6 +12,7 @@
 	"a user": "un utilisateur",
 	"About": "À propos",
 	"Account": "Compte",
+	"Account Activation Pending": "",
 	"Accurate information": "Information précise",
 	"Active Users": "",
 	"Add": "Ajouter",
@@ -29,6 +30,7 @@
 	"Add User": "Ajouter un utilisateur",
 	"Adjusting these settings will apply changes universally to all users.": "L'ajustement de ces paramètres appliquera les changements à tous les utilisateurs.",
 	"admin": "Administrateur",
+	"Admin": "",
 	"Admin Panel": "Panneau d'administration",
 	"Admin Settings": "Paramètres d'administration",
 	"Advanced Parameters": "Paramètres avancés",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Août",
 	"Auto-playback response": "Réponse en lecture automatique",
-	"Auto-send input after 3 sec.": "Envoyer automatiquement l'entrée après 3 sec.",
 	"AUTOMATIC1111 Base URL": "URL de base AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "L'URL de base AUTOMATIC1111 est requise.",
 	"available!": "disponible !",
@@ -71,6 +72,9 @@
 	"Being lazy": "En manque de temps",
 	"Brave Search API Key": "Clé d’API de recherche brave",
 	"Bypass SSL verification for Websites": "Parcourir la vérification SSL pour les sites Web",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Annuler",
 	"Capabilities": "Capacités",
 	"Change Password": "Changer le mot de passe",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Size": "Taille de bloc",
 	"Citation": "Citations",
+	"Clear memory": "",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here to": "Cliquez ici pour",
 	"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.": "",
 	"Click here to select documents.": "Cliquez ici pour sélectionner des documents.",
 	"click here.": "cliquez ici.",
 	"Click on the user role button to change a user's role.": "Cliquez sur le bouton de rôle d'utilisateur pour changer le rôle d'un utilisateur.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Demandes simultanées",
 	"Confirm Password": "Confirmer le mot de passe",
 	"Connections": "Connexions",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Contenu",
 	"Context Length": "Longueur du contexte",
 	"Continue Response": "Continuer la réponse",
-	"Conversation Mode": "Mode de conversation",
 	"Copied shared chat URL to clipboard!": "URL de chat partagé copié dans le presse-papier !",
 	"Copy": "Copier",
 	"Copy last code block": "Copier le dernier bloc de code",
 	"Copy last response": "Copier la dernière réponse",
 	"Copy Link": "Copier le lien",
 	"Copying to clipboard was successful!": "La copie dans le presse-papiers a réussi !",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Créez une phrase concise de 3 à 5 mots comme en-tête pour la requête suivante, en respectant strictement la limite de 3 à 5 mots et en évitant l'utilisation du mot 'titre' :",
 	"Create a model": "Créer un modèle",
 	"Create Account": "Créer un compte",
 	"Create new key": "Créer une nouvelle clé",
@@ -127,12 +132,12 @@
 	"Custom": "Personnalisé",
 	"Customize models for a specific purpose": "Personnaliser les modèles dans un but spécifique",
 	"Dark": "Sombre",
+	"Dashboard": "",
 	"Database": "Base de données",
 	"December": "Décembre",
 	"Default": "Par défaut",
 	"Default (Automatic1111)": "Par défaut (Automatic1111)",
 	"Default (SentenceTransformers)": "Par défaut (SentenceTransformers)",
-	"Default (Web API)": "Par défaut (API Web)",
 	"Default Model": "Modèle par défaut",
 	"Default model updated": "Modèle par défaut mis à jour",
 	"Default Prompt Suggestions": "Suggestions de prompt par défaut",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Découvrir un prompt",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Afficher le nom d'utilisateur au lieu de 'Vous' dans la Discussion",
 	"Document": "Document",
 	"Document Settings": "Paramètres du document",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exporter le mappage des documents",
 	"Export Models": "Modèles d’exportation",
 	"Export Prompts": "Exporter les prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Impossible de créer la clé API.",
 	"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Pénalité de fréquence",
 	"General": "Général",
 	"General Settings": "Paramètres généraux",
+	"Generate Image": "",
 	"Generating search query": "Génération d’une requête de recherche",
 	"Generation Info": "Informations de génération",
 	"Good Response": "Bonne réponse",
@@ -252,6 +260,7 @@
 	"Info": "L’info",
 	"Input commands": "Entrez des commandes d'entrée",
 	"Install from Github URL": "Installer à partir de l’URL Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "Tag invalide",
 	"January": "Janvier",
@@ -264,14 +273,17 @@
 	"JWT Token": "Jeton JWT",
 	"Keep Alive": "Garder actif",
 	"Keyboard shortcuts": "Raccourcis clavier",
+	"Knowledge": "",
 	"Language": "Langue",
 	"Last Active": "Dernière activité",
 	"Light": "Lumière",
-	"Listening...": "Écoute...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Les LLMs peuvent faire des erreurs. Vérifiez les informations importantes.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Réalisé par la communauté OpenWebUI",
 	"Make sure to enclose them with": "Assurez-vous de les entourer avec",
+	"Manage": "",
 	"Manage Models": "Gérer les modèles",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Pipelines": "Gérer les pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Nommez votre modèle",
 	"New Chat": "Nouvelle discussion",
 	"New Password": "Nouveau mot de passe",
+	"No documents found": "",
 	"No results found": "Aucun résultat trouvé",
 	"No search query generated": "Aucune requête de recherche générée",
 	"No source available": "Aucune source disponible",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API Ollama désactivée",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Version Ollama",
 	"On": "Activé",
 	"Only": "Seulement",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Document PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)",
 	"pending": "en attente",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permission refusée lors de l'accès au microphone : {{error}}",
 	"Personalization": "Personnalisation",
 	"Pipelines": "Pipelines",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Lire à l'échelle",
 	"Record voice": "Enregistrer la voix",
 	"Redirecting you to OpenWebUI Community": "Vous redirige vers la communauté OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Refusé quand il ne devrait pas l'être",
 	"Regenerate": "Régénérer",
 	"Release Notes": "Notes de version",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Pin Rosé",
 	"Rosé Pine Dawn": "Aube Pin Rosé",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Enregistrer",
 	"Save & Create": "Enregistrer & Créer",
 	"Save & Update": "Enregistrer & Mettre à jour",
@@ -398,6 +416,8 @@
 	"Search Documents": "Rechercher des documents",
 	"Search Models": "Modèles de recherche",
 	"Search Prompts": "Rechercher des prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Nombre de résultats de la recherche",
 	"Searched {{count}} sites_one": "Recherche dans {{count}} sites_one",
 	"Searched {{count}} sites_many": "Recherche dans {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Voir les nouveautés",
 	"Seed": "Graine",
 	"Select a base model": "Sélectionner un modèle de base",
+	"Select a engine": "",
 	"Select a mode": "Sélectionnez un mode",
 	"Select a model": "Sélectionnez un modèle",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select model": "Sélectionnez un modèle",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Les modèles sélectionnés ne prennent pas en charge les entrées d’image",
 	"Send": "Envoyer",
 	"Send a Message": "Envoyer un message",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Définir le modèle par défaut",
 	"Set embedding model (e.g. {{model}})": "Définir le modèle d'embedding (par exemple {{model}})",
 	"Set Image Size": "Définir la taille de l'image",
-	"Set Model": "Configurer le modèle",
 	"Set reranking model (e.g. {{model}})": "Définir le modèle de reranking (par exemple {{model}})",
 	"Set Steps": "Définir les étapes",
 	"Set Task Model": "Définir le modèle de tâche",
@@ -450,8 +471,8 @@
 	"Source": "Source",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech-to-Text Engine": "Moteur reconnaissance vocale",
-	"SpeechRecognition API is not supported in this browser.": "L'API SpeechRecognition n'est pas prise en charge dans ce navigateur.",
 	"Stop Sequence": "Séquence d'arrêt",
+	"STT Model": "",
 	"STT Settings": "Paramètres de STT",
 	"Submit": "Soumettre",
 	"Subtitle (e.g. about the Roman Empire)": "Sous-titre (par exemple, sur l'empire romain)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Merci pour votre feedback!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Le score doit être une valeur entre 0.0 (0%) et 1.0 (100%).",
 	"Theme": "Thème",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Cela garantit que vos précieuses conversations sont enregistrées en toute sécurité dans votre base de données backend. Merci !",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Ce réglage ne se synchronise pas entre les navigateurs ou les appareils.",
 	"Thorough explanation": "Explication approfondie",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Astuce : Mettez à jour plusieurs emplacements de variables consécutivement en appuyant sur la touche tabulation dans l'entrée de chat après chaque remplacement.",
@@ -482,6 +505,7 @@
 	"to": "à",
 	"To access the available model names for downloading,": "Pour accéder aux noms de modèles disponibles pour le téléchargement,",
 	"To access the GGUF models available for downloading,": "Pour accéder aux modèles GGUF disponibles pour le téléchargement,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "à l'entrée du chat.",
 	"Today": "Aujourd'hui",
 	"Toggle settings": "Basculer les paramètres",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Des problèmes pour accéder à Ollama ?",
+	"TTS Model": "",
 	"TTS Settings": "Paramètres TTS",
+	"TTS Voice": "",
 	"Type": "Type",
 	"Type Hugging Face Resolve (Download) URL": "Entrez l'URL de résolution (téléchargement) Hugging Face",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh ! Il y a eu un problème de connexion à {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Mettre à jour le mot de passe",
 	"Upload a GGUF model": "Téléverser un modèle GGUF",
 	"Upload Files": "Télécharger des fichiers",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progression du Téléversement",
 	"URL Mode": "Mode URL",
 	"Use '#' in the prompt input to load and select your documents.": "Utilisez '#' dans l'entrée de prompt pour charger et sélectionner vos documents.",
@@ -516,6 +543,7 @@
 	"Warning": "Avertissement",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Attention : Si vous mettez à jour ou changez votre modèle d'intégration, vous devrez réimporter tous les documents.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Paramètres du chargeur Web",
 	"Web Params": "Paramètres Web",
 	"Web Search": "Recherche sur le Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI effectuera des demandes à",
 	"What’s New in": "Quoi de neuf dans",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Lorsque l'historique est désactivé, les nouvelles discussions sur ce navigateur n'apparaîtront pas dans votre historique sur aucun de vos appareils.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Espace de travail",
 	"Write a prompt suggestion (e.g. Who are you?)": "Rédigez une suggestion de prompt (p. ex. Qui êtes-vous ?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Rédigez un résumé en 50 mots qui résume [sujet ou mot-clé].",
 	"Yesterday": "hier",
 	"You": "Vous",
+	"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 clone a base model": "Vous ne pouvez pas cloner un modèle de base",
 	"You have no archived conversations.": "Vous n'avez aucune conversation archivée.",
 	"You have shared this chat": "Vous avez partagé cette conversation",
 	"You're a helpful assistant.": "Vous êtes un assistant utile",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Paramètres du chargeur Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/fr-FR/translation.json

@@ -12,6 +12,7 @@
 	"a user": "un utilisateur",
 	"About": "À Propos",
 	"Account": "Compte",
+	"Account Activation Pending": "",
 	"Accurate information": "Information précise",
 	"Active Users": "",
 	"Add": "Ajouter",
@@ -29,6 +30,7 @@
 	"Add User": "Ajouter un Utilisateur",
 	"Adjusting these settings will apply changes universally to all users.": "L'ajustement de ces paramètres appliquera les changements à tous les utilisateurs.",
 	"admin": "admin",
+	"Admin": "",
 	"Admin Panel": "Panneau d'Administration",
 	"Admin Settings": "Paramètres d'Administration",
 	"Advanced Parameters": "Paramètres Avancés",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Août",
 	"Auto-playback response": "Réponse en lecture automatique",
-	"Auto-send input after 3 sec.": "Envoyer automatiquement l'entrée après 3 sec.",
 	"AUTOMATIC1111 Base URL": "URL de base AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "L'URL de base AUTOMATIC1111 est requise.",
 	"available!": "disponible !",
@@ -71,6 +72,9 @@
 	"Being lazy": "Est paresseux",
 	"Brave Search API Key": "Clé API Brave Search",
 	"Bypass SSL verification for Websites": "Contourner la vérification SSL pour les sites Web.",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Annuler",
 	"Capabilities": "Capacités",
 	"Change Password": "Changer le mot de passe",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Size": "Taille de bloc",
 	"Citation": "Citation",
+	"Clear memory": "",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here to": "Cliquez ici pour",
 	"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.": "",
 	"Click here to select documents.": "Cliquez ici pour sélectionner des documents.",
 	"click here.": "cliquez ici.",
 	"Click on the user role button to change a user's role.": "Cliquez sur le bouton de rôle d'utilisateur pour changer le rôle d'un utilisateur.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Demandes simultanées",
 	"Confirm Password": "Confirmer le mot de passe",
 	"Connections": "Connexions",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Contenu",
 	"Context Length": "Longueur du contexte",
 	"Continue Response": "Continuer la Réponse",
-	"Conversation Mode": "Mode de conversation",
 	"Copied shared chat URL to clipboard!": "URL du chat copié dans le presse-papiers !",
 	"Copy": "Copier",
 	"Copy last code block": "Copier le dernier bloc de code",
 	"Copy last response": "Copier la dernière réponse",
 	"Copy Link": "Copier le Lien",
 	"Copying to clipboard was successful!": "La copie dans le presse-papiers a réussi !",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Créez une phrase concise de 3-5 mots comme en-tête pour la requête suivante, en respectant strictement la limite de 3-5 mots et en évitant l'utilisation du mot 'titre' :",
 	"Create a model": "Créer un modèle",
 	"Create Account": "Créer un compte",
 	"Create new key": "Créer une nouvelle clé",
@@ -127,12 +132,12 @@
 	"Custom": "Personnalisé",
 	"Customize models for a specific purpose": "Personnaliser les modèles pour un objectif spécifique",
 	"Dark": "Sombre",
+	"Dashboard": "",
 	"Database": "Base de données",
 	"December": "Décembre",
 	"Default": "Par défaut",
 	"Default (Automatic1111)": "Par défaut (Automatic1111)",
 	"Default (SentenceTransformers)": "Par défaut (SentenceTransformers)",
-	"Default (Web API)": "Par défaut (API Web)",
 	"Default Model": "Modèle par défaut",
 	"Default model updated": "Modèle par défaut mis à jour",
 	"Default Prompt Suggestions": "Suggestions de prompt par défaut",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Découvrir un prompt",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Afficher le nom d'utilisateur au lieu de 'Vous' dans le Chat",
 	"Document": "Document",
 	"Document Settings": "Paramètres du document",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exporter la Correspondance des Documents",
 	"Export Models": "Exporter les Modèles",
 	"Export Prompts": "Exporter les Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Échec de la création de la clé d'API.",
 	"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Pénalité de fréquence",
 	"General": "Général",
 	"General Settings": "Paramètres Généraux",
+	"Generate Image": "",
 	"Generating search query": "Génération d’une requête de recherche",
 	"Generation Info": "Informations de la Génération",
 	"Good Response": "Bonne Réponse",
@@ -252,6 +260,7 @@
 	"Info": "Info",
 	"Input commands": "Entrez les commandes d'entrée",
 	"Install from Github URL": "Installer à partir de l’URL Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "Tag Invalide",
 	"January": "Janvier",
@@ -264,14 +273,17 @@
 	"JWT Token": "Jeton JWT",
 	"Keep Alive": "Rester en vie",
 	"Keyboard shortcuts": "Raccourcis clavier",
+	"Knowledge": "",
 	"Language": "Langue",
 	"Last Active": "Dernier Activité",
 	"Light": "Clair",
-	"Listening...": "Écoute...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Les LLMs peuvent faire des erreurs. Vérifiez les informations importantes.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Réalisé par la communauté OpenWebUI",
 	"Make sure to enclose them with": "Assurez-vous de les entourer avec",
+	"Manage": "",
 	"Manage Models": "Gérer les modèles",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Pipelines": "Gérer les pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Nommez votre modèle",
 	"New Chat": "Nouveau chat",
 	"New Password": "Nouveau mot de passe",
+	"No documents found": "",
 	"No results found": "Aucun résultat",
 	"No search query generated": "Aucune requête de recherche générée",
 	"No source available": "Aucune source disponible",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "API Ollama",
 	"Ollama API disabled": "API Ollama désactivée",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Version Ollama",
 	"On": "Activé",
 	"Only": "Seulement",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Document PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)",
 	"pending": "en attente",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permission refusée lors de l'accès au microphone : {{error}}",
 	"Personalization": "Personnalisation",
 	"Pipelines": "Pipelines",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Lire à Voix Haute",
 	"Record voice": "Enregistrer la voix",
 	"Redirecting you to OpenWebUI Community": "Redirection vers la communauté OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Refuse quand il ne devrait pas",
 	"Regenerate": "Regénérer",
 	"Release Notes": "Notes de Version",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Pin Rosé",
 	"Rosé Pine Dawn": "Aube Pin Rosé",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Enregistrer",
 	"Save & Create": "Enregistrer & Créer",
 	"Save & Update": "Enregistrer & Mettre à jour",
@@ -398,6 +416,8 @@
 	"Search Documents": "Rechercher des Documents",
 	"Search Models": "Rechercher des modèles",
 	"Search Prompts": "Rechercher des Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Nombre de résultats de recherche",
 	"Searched {{count}} sites_one": "Recherché {{count}} sites_one",
 	"Searched {{count}} sites_many": "Recherché {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Voir les nouveautés",
 	"Seed": "Graine",
 	"Select a base model": "Sélectionner un modèle de base",
+	"Select a engine": "",
 	"Select a mode": "Sélectionner un mode",
 	"Select a model": "Sélectionner un modèle",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select model": "Sélectionner un modèle",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Modèle(s) séléctionés ne supportent pas les entrées images",
 	"Send": "Envoyer",
 	"Send a Message": "Envoyer un message",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Définir le Modèle par Défaut",
 	"Set embedding model (e.g. {{model}})": "Définir le modèle d'embedding (p. ex. {{model}})",
 	"Set Image Size": "Définir la Taille de l'Image",
-	"Set Model": "Définir le Modèle",
 	"Set reranking model (e.g. {{model}})": "Définir le modèle de reclassement (p. ex. {{model}})",
 	"Set Steps": "Définir les Étapes",
 	"Set Task Model": "Définir le modèle de tâche",
@@ -450,8 +471,8 @@
 	"Source": "Source",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech-to-Text Engine": "Moteur de Reconnaissance Vocale",
-	"SpeechRecognition API is not supported in this browser.": "L'API SpeechRecognition n'est pas prise en charge dans ce navigateur.",
 	"Stop Sequence": "Séquence d'Arrêt",
+	"STT Model": "",
 	"STT Settings": "Paramètres STT",
 	"Submit": "Envoyer",
 	"Subtitle (e.g. about the Roman Empire)": "Sous-Titres (p. ex. à propos de l'Empire Romain)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Merci pour votre avis !",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Le score devrait avoir une valeur entre 0.0 (0%) et 1.0 (100%).",
 	"Theme": "Thème",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Cela garantit que vos précieuses conversations sont en sécurité dans votre base de données. Merci !",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Ce paramètre ne se synchronise pas entre les navigateurs ou les appareils.",
 	"Thorough explanation": "Explication détaillée",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Conseil : Mettez à jour plusieurs emplacements de variables consécutivement en appuyant sur la touche tab dans l'entrée de chat après chaque remplacement",
@@ -482,6 +505,7 @@
 	"to": "à",
 	"To access the available model names for downloading,": "Pour accéder aux noms de modèles disponibles pour le téléchargement,",
 	"To access the GGUF models available for downloading,": "Pour accéder aux modèles GGUF disponibles pour le téléchargement,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "à l'entrée du chat.",
 	"Today": "Aujourd'hui",
 	"Toggle settings": "Basculer les paramètres",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problèmes d'accès à Ollama ?",
+	"TTS Model": "",
 	"TTS Settings": "Paramètres TTS",
+	"TTS Voice": "",
 	"Type": "Type",
 	"Type Hugging Face Resolve (Download) URL": "Entrez l'URL de Résolution (Téléchargement) Hugging Face",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh ! Il y a eu un problème de connexion à {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Mettre à Jour le Mot de Passe",
 	"Upload a GGUF model": "Téléverser un modèle GGUF",
 	"Upload Files": "Télécharger des fichiers",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progression du Téléversement",
 	"URL Mode": "Mode URL",
 	"Use '#' in the prompt input to load and select your documents.": "Utilisez '#' dans l'entrée du prompt pour charger et sélectionner vos documents.",
@@ -516,6 +543,7 @@
 	"Warning": "Avertissement",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Avertissement : Si vous mettez à jour ou modifier votre modèle d'embedding, vous devrez réimporter tous les documents.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Paramètres du Chargeur Web",
 	"Web Params": "Paramètres Web",
 	"Web Search": "Recherche sur le Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI effectuera des demandes à",
 	"What’s New in": "Quoi de neuf dans",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Lorsque l'historique est désactivé, les nouveaux chats sur ce navigateur n'apparaîtront pas dans votre historique sur aucun de vos appareils.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Espace de Travail",
 	"Write a prompt suggestion (e.g. Who are you?)": "Écrivez une suggestion de prompt (e.x. Qui est-tu ?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Ecrivez un résumé en 50 mots qui résume [sujet ou mot-clé]",
 	"Yesterday": "Hier",
 	"You": "Vous",
+	"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 clone a base model": "Vous ne pouvez pas cloner un modèle de base",
 	"You have no archived conversations.": "Vous n'avez pas de conversations archivées",
 	"You have shared this chat": "Vous avez partagé ce chat",
 	"You're a helpful assistant.": "Vous êtes un assistant utile.",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Paramètres du Chargeur YouTube"
 }

+ 38 - 8
src/lib/i18n/locales/he-IL/translation.json

@@ -12,6 +12,7 @@
 	"a user": "משתמש",
 	"About": "אודות",
 	"Account": "חשבון",
+	"Account Activation Pending": "",
 	"Accurate information": "מידע מדויק",
 	"Active Users": "",
 	"Add": "הוסף",
@@ -29,6 +30,7 @@
 	"Add User": "הוסף משתמש",
 	"Adjusting these settings will apply changes universally to all users.": "התאמת הגדרות אלו תחול על כל המשתמשים.",
 	"admin": "מנהל",
+	"Admin": "",
 	"Admin Panel": "לוח בקרה למנהל",
 	"Admin Settings": "הגדרות מנהל",
 	"Advanced Parameters": "פרמטרים מתקדמים",
@@ -59,7 +61,6 @@
 	"Audio": "אודיו",
 	"August": "אוגוסט",
 	"Auto-playback response": "תגובת השמעה אוטומטית",
-	"Auto-send input after 3 sec.": "שליחת קלט אוטומטית אחרי 3 שניות",
 	"AUTOMATIC1111 Base URL": "כתובת URL בסיסית של AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "נדרשת כתובת URL בסיסית של AUTOMATIC1111",
 	"available!": "זמין!",
@@ -71,6 +72,9 @@
 	"Being lazy": "להיות עצלן",
 	"Brave Search API Key": "מפתח API של חיפוש אמיץ",
 	"Bypass SSL verification for Websites": "עקוף אימות SSL עבור אתרים",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "בטל",
 	"Capabilities": "יכולות",
 	"Change Password": "שנה סיסמה",
@@ -88,10 +92,12 @@
 	"Chunk Params": "פרמטרי נתונים",
 	"Chunk Size": "גודל נתונים",
 	"Citation": "ציטוט",
+	"Clear memory": "",
 	"Click here for help.": "לחץ כאן לעזרה.",
 	"Click here to": "לחץ כאן כדי",
 	"Click here to select": "לחץ כאן לבחירה",
 	"Click here to select a csv file.": "לחץ כאן לבחירת קובץ csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "לחץ כאן לבחירת מסמכים.",
 	"click here.": "לחץ כאן.",
 	"Click on the user role button to change a user's role.": "לחץ על כפתור תפקיד המשתמש כדי לשנות את תפקיד המשתמש.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "בקשות בו-זמניות",
 	"Confirm Password": "אשר סיסמה",
 	"Connections": "חיבורים",
+	"Contact Admin for WebUI Access": "",
 	"Content": "תוכן",
 	"Context Length": "אורך הקשר",
 	"Continue Response": "המשך תגובה",
-	"Conversation Mode": "מצב שיחה",
 	"Copied shared chat URL to clipboard!": "העתקת כתובת URL של צ'אט משותף ללוח!",
 	"Copy": "העתק",
 	"Copy last code block": "העתק את בלוק הקוד האחרון",
 	"Copy last response": "העתק את התגובה האחרונה",
 	"Copy Link": "העתק קישור",
 	"Copying to clipboard was successful!": "ההעתקה ללוח הייתה מוצלחת!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "צור ביטוי תמציתי של 3-5 מילים ככותרת לשאילתה הבאה, תוך שמירה מדויקת על מגבלת 3-5 המילים והימנעות משימוש במילה 'כותרת':",
 	"Create a model": "יצירת מודל",
 	"Create Account": "צור חשבון",
 	"Create new key": "צור מפתח חדש",
@@ -127,12 +132,12 @@
 	"Custom": "מותאם אישית",
 	"Customize models for a specific purpose": "התאמה אישית של מודלים למטרה ספציפית",
 	"Dark": "כהה",
+	"Dashboard": "",
 	"Database": "מסד נתונים",
 	"December": "דצמבר",
 	"Default": "ברירת מחדל",
 	"Default (Automatic1111)": "ברירת מחדל (Automatic1111)",
 	"Default (SentenceTransformers)": "ברירת מחדל (SentenceTransformers)",
-	"Default (Web API)": "ברירת מחדל (Web API)",
 	"Default Model": "מודל ברירת מחדל",
 	"Default model updated": "המודל המוגדר כברירת מחדל עודכן",
 	"Default Prompt Suggestions": "הצעות ברירת מחדל לפקודות",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "גלה פקודה",
 	"Discover, download, and explore custom prompts": "גלה, הורד, וחקור פקודות מותאמות אישית",
 	"Discover, download, and explore model presets": "גלה, הורד, וחקור הגדרות מודל מוגדרות מראש",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "הצג את שם המשתמש במקום 'אתה' בצ'אט",
 	"Document": "מסמך",
 	"Document Settings": "הגדרות מסמך",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "ייצוא מיפוי מסמכים",
 	"Export Models": "ייצוא מודלים",
 	"Export Prompts": "ייצוא פקודות",
+	"External Models": "",
 	"Failed to create API Key.": "יצירת מפתח API נכשלה.",
 	"Failed to read clipboard contents": "קריאת תוכן הלוח נכשלה",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "עונש תדירות",
 	"General": "כללי",
 	"General Settings": "הגדרות כלליות",
+	"Generate Image": "",
 	"Generating search query": "יצירת שאילתת חיפוש",
 	"Generation Info": "מידע על היצירה",
 	"Good Response": "תגובה טובה",
@@ -252,6 +260,7 @@
 	"Info": "מידע",
 	"Input commands": "פקודות קלט",
 	"Install from Github URL": "התקן מכתובת URL של Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "ממשק",
 	"Invalid Tag": "תג לא חוקי",
 	"January": "ינואר",
@@ -264,14 +273,17 @@
 	"JWT Token": "אסימון JWT",
 	"Keep Alive": "השאר פעיל",
 	"Keyboard shortcuts": "קיצורי מקלדת",
+	"Knowledge": "",
 	"Language": "שפה",
 	"Last Active": "פעיל לאחרונה",
 	"Light": "בהיר",
-	"Listening...": "מאזין...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "מודלים בשפה טבעית יכולים לטעות. אמת מידע חשוב.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "נוצר על ידי קהילת OpenWebUI",
 	"Make sure to enclose them with": "ודא להקיף אותם עם",
+	"Manage": "",
 	"Manage Models": "נהל מודלים",
 	"Manage Ollama Models": "נהל מודלים של Ollama",
 	"Manage Pipelines": "ניהול צינורות",
@@ -307,6 +319,7 @@
 	"Name your model": "תן שם לדגם שלך",
 	"New Chat": "צ'אט חדש",
 	"New Password": "סיסמה חדשה",
+	"No documents found": "",
 	"No results found": "לא נמצאו תוצאות",
 	"No search query generated": "לא נוצרה שאילתת חיפוש",
 	"No source available": "אין מקור זמין",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API מושבת",
+	"Ollama API is disabled": "",
 	"Ollama Version": "גרסת Ollama",
 	"On": "פועל",
 	"Only": "רק",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "מסמך PDF (.pdf)",
 	"PDF Extract Images (OCR)": "חילוץ תמונות מ-PDF (OCR)",
 	"pending": "ממתין",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "ההרשאה נדחתה בעת גישה למיקרופון: {{error}}",
 	"Personalization": "תאור",
 	"Pipelines": "צינורות",
@@ -367,6 +383,7 @@
 	"Read Aloud": "קרא בקול",
 	"Record voice": "הקלט קול",
 	"Redirecting you to OpenWebUI Community": "מפנה אותך לקהילת OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "נדחה כאשר לא היה צריך",
 	"Regenerate": "הפק מחדש",
 	"Release Notes": "הערות שחרור",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "שמור",
 	"Save & Create": "שמור וצור",
 	"Save & Update": "שמור ועדכן",
@@ -398,6 +416,8 @@
 	"Search Documents": "חפש מסמכים",
 	"Search Models": "חיפוש מודלים",
 	"Search Prompts": "חפש פקודות",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "ספירת תוצאות חיפוש",
 	"Searched {{count}} sites_one": "חיפש {{count}} sites_one",
 	"Searched {{count}} sites_two": "חיפש {{count}} sites_two",
@@ -408,12 +428,14 @@
 	"See what's new": "ראה מה חדש",
 	"Seed": "זרע",
 	"Select a base model": "בחירת מודל בסיס",
+	"Select a engine": "",
 	"Select a mode": "בחר מצב",
 	"Select a model": "בחר מודל",
 	"Select a pipeline": "בחר קו צינור",
 	"Select a pipeline url": "בחר כתובת URL של קו צינור",
 	"Select an Ollama instance": "בחר מופע של Ollama",
 	"Select model": "בחר מודל",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "דגמים נבחרים אינם תומכים בקלט תמונה",
 	"Send": "שלח",
 	"Send a Message": "שלח הודעה",
@@ -426,7 +448,6 @@
 	"Set Default Model": "הגדר מודל ברירת מחדל",
 	"Set embedding model (e.g. {{model}})": "הגדר מודל הטמעה (למשל {{model}})",
 	"Set Image Size": "הגדר גודל תמונה",
-	"Set Model": "הגדר מודל",
 	"Set reranking model (e.g. {{model}})": "הגדר מודל דירוג מחדש (למשל {{model}})",
 	"Set Steps": "הגדר שלבים",
 	"Set Task Model": "הגדרת מודל משימה",
@@ -450,8 +471,8 @@
 	"Source": "מקור",
 	"Speech recognition error: {{error}}": "שגיאת תחקור שמע: {{error}}",
 	"Speech-to-Text Engine": "מנוע תחקור שמע",
-	"SpeechRecognition API is not supported in this browser.": "מנוע תחקור שמע אינו נתמך בדפדפן זה.",
 	"Stop Sequence": "סידור עצירה",
+	"STT Model": "",
 	"STT Settings": "הגדרות חקירה של TTS",
 	"Submit": "שלח",
 	"Subtitle (e.g. about the Roman Empire)": "תחקור (לדוגמה: על מעמד הרומי)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "תודה על המשוב שלך!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "ציון צריך להיות ערך בין 0.0 (0%) ל-1.0 (100%)",
 	"Theme": "נושא",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "פעולה זו מבטיחה שהשיחות בעלות הערך שלך יישמרו באופן מאובטח במסד הנתונים העורפי שלך. תודה!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "הגדרה זו אינה מסתנכרנת בין דפדפנים או מכשירים.",
 	"Thorough explanation": "תיאור מפורט",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "טיפ: עדכן חריצים משתנים מרובים ברציפות על-ידי לחיצה על מקש Tab בקלט הצ'אט לאחר כל החלפה.",
@@ -482,6 +505,7 @@
 	"to": "ל",
 	"To access the available model names for downloading,": "כדי לגשת לשמות הדגמים הזמינים להורדה,",
 	"To access the GGUF models available for downloading,": "כדי לגשת לדגמי GGUF הזמינים להורדה,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "לקלטת שיחה.",
 	"Today": "היום",
 	"Toggle settings": "החלפת מצב של הגדרות",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "קשה לגשת לOllama?",
+	"TTS Model": "",
 	"TTS Settings": "הגדרות TTS",
+	"TTS Voice": "",
 	"Type": "סוג",
 	"Type Hugging Face Resolve (Download) URL": "הקלד כתובת URL של פתרון פנים מחבק (הורד)",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "או-הו! אירעה בעיה בהתחברות ל- {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "עדכן סיסמה",
 	"Upload a GGUF model": "העלה מודל GGUF",
 	"Upload Files": "העלאת קבצים",
+	"Upload Pipeline": "",
 	"Upload Progress": "תקדמות העלאה",
 	"URL Mode": "מצב URL",
 	"Use '#' in the prompt input to load and select your documents.": "השתמש ב- '#' בקלט הבקשה כדי לטעון ולבחור את המסמכים שלך.",
@@ -516,6 +543,7 @@
 	"Warning": "אזהרה",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "אזהרה: אם תעדכן או תשנה את מודל ההטבעה שלך, יהיה עליך לייבא מחדש את כל המסמכים.",
 	"Web": "רשת",
+	"Web API": "",
 	"Web Loader Settings": "הגדרות טעינת אתר",
 	"Web Params": "פרמטרים Web",
 	"Web Search": "חיפוש באינטרנט",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI יבקש לבקש",
 	"What’s New in": "מה חדש ב",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "כאשר ההיסטוריה מושבתת, צ'אטים חדשים בדפדפן זה לא יופיעו בהיסטוריה שלך באף אחד מהמכשירים שלך.",
-	"Whisper (Local)": "ושפה (מקומית)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "סביבה",
 	"Write a prompt suggestion (e.g. Who are you?)": "כתוב הצעה מהירה (למשל, מי אתה?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "כתוב סיכום ב-50 מילים שמסכם [נושא או מילת מפתח].",
 	"Yesterday": "אתמול",
 	"You": "אתה",
+	"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 clone a base model": "לא ניתן לשכפל מודל בסיס",
 	"You have no archived conversations.": "אין לך שיחות בארכיון.",
 	"You have shared this chat": "שיתפת את השיחה הזו",
 	"You're a helpful assistant.": "אתה עוזר מועיל.",
 	"You're now logged in.": "כעת אתה מחובר.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "הגדרות Youtube Loader"
 }

+ 38 - 8
src/lib/i18n/locales/hi-IN/translation.json

@@ -12,6 +12,7 @@
 	"a user": "एक उपयोगकर्ता",
 	"About": "हमारे बारे में",
 	"Account": "खाता",
+	"Account Activation Pending": "",
 	"Accurate information": "सटीक जानकारी",
 	"Active Users": "",
 	"Add": "जोड़ें",
@@ -29,6 +30,7 @@
 	"Add User": "उपयोगकर्ता जोड़ें",
 	"Adjusting these settings will apply changes universally to all users.": "इन सेटिंग्स को समायोजित करने से परिवर्तन सभी उपयोगकर्ताओं पर सार्वभौमिक रूप से लागू होंगे।",
 	"admin": "व्यवस्थापक",
+	"Admin": "",
 	"Admin Panel": "व्यवस्थापक पैनल",
 	"Admin Settings": "व्यवस्थापक सेटिंग्स",
 	"Advanced Parameters": "उन्नत पैरामीटर",
@@ -59,7 +61,6 @@
 	"Audio": "ऑडियो",
 	"August": "अगस्त",
 	"Auto-playback response": "ऑटो-प्लेबैक प्रतिक्रिया",
-	"Auto-send input after 3 sec.": "3 सेकंड के बाद स्वचालित रूप से इनपुट भेजें।",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 बेस यूआरएल",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 का बेस यूआरएल आवश्यक है।",
 	"available!": "उपलब्ध!",
@@ -71,6 +72,9 @@
 	"Being lazy": "आलसी होना",
 	"Brave Search API Key": "Brave सर्च एपीआई कुंजी",
 	"Bypass SSL verification for Websites": "वेबसाइटों के लिए SSL सुनिश्चिती को छोड़ें",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "रद्द करें",
 	"Capabilities": "क्षमताओं",
 	"Change Password": "पासवर्ड बदलें",
@@ -88,10 +92,12 @@
 	"Chunk Params": "चंक पैरामीटर्स",
 	"Chunk Size": "चंक आकार",
 	"Citation": "उद्धरण",
+	"Clear memory": "",
 	"Click here for help.": "सहायता के लिए यहां क्लिक करें।",
 	"Click here to": "यहां क्लिक करें",
 	"Click here to select": "चयन करने के लिए यहां क्लिक करें।",
 	"Click here to select a csv file.": "सीएसवी फ़ाइल का चयन करने के लिए यहां क्लिक करें।",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "दस्तावेज़ चुनने के लिए यहां क्लिक करें।",
 	"click here.": "यहाँ क्लिक करें।",
 	"Click on the user role button to change a user's role.": "उपयोगकर्ता की भूमिका बदलने के लिए उपयोगकर्ता भूमिका बटन पर क्लिक करें।",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "समवर्ती अनुरोध",
 	"Confirm Password": "पासवर्ड की पुष्टि कीजिये",
 	"Connections": "सम्बन्ध",
+	"Contact Admin for WebUI Access": "",
 	"Content": "सामग्री",
 	"Context Length": "प्रसंग की लंबाई",
 	"Continue Response": "प्रतिक्रिया जारी रखें",
-	"Conversation Mode": "बातचीत का मॉड",
 	"Copied shared chat URL to clipboard!": "साझा चैट URL को क्लिपबोर्ड पर कॉपी किया गया!",
 	"Copy": "कॉपी",
 	"Copy last code block": "अंतिम कोड ब्लॉक कॉपी करें",
 	"Copy last response": "अंतिम प्रतिक्रिया कॉपी करें",
 	"Copy Link": "लिंक को कॉपी करें",
 	"Copying to clipboard was successful!": "क्लिपबोर्ड पर कॉपी बनाना सफल रहा!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "निम्नलिखित क्वेरी के लिए हेडर के रूप में एक संक्षिप्त, 3-5 शब्द वाक्यांश बनाएं, 3-5 शब्द सीमा का सख्ती से पालन करें और 'शीर्षक' शब्द के उपयोग से बचें:",
 	"Create a model": "एक मॉडल बनाएं",
 	"Create Account": "खाता बनाएं",
 	"Create new key": "नया क्रिप्टोग्राफिक क्षेत्र बनाएं",
@@ -127,12 +132,12 @@
 	"Custom": "कस्टम संस्करण",
 	"Customize models for a specific purpose": "एक विशिष्ट उद्देश्य के लिए मॉडल अनुकूलित करें",
 	"Dark": "डार्क",
+	"Dashboard": "",
 	"Database": "डेटाबेस",
 	"December": "डिसेंबर",
 	"Default": "डिफ़ॉल्ट",
 	"Default (Automatic1111)": "डिफ़ॉल्ट (Automatic1111)",
 	"Default (SentenceTransformers)": "डिफ़ॉल्ट (SentenceTransformers)",
-	"Default (Web API)": "डिफ़ॉल्ट (Web API)",
 	"Default Model": "डिफ़ॉल्ट मॉडल",
 	"Default model updated": "डिफ़ॉल्ट मॉडल अपडेट किया गया",
 	"Default Prompt Suggestions": "डिफ़ॉल्ट प्रॉम्प्ट सुझाव",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "प्रॉम्प्ट खोजें",
 	"Discover, download, and explore custom prompts": "कस्टम प्रॉम्प्ट को खोजें, डाउनलोड करें और एक्सप्लोर करें",
 	"Discover, download, and explore model presets": "मॉडल प्रीसेट खोजें, डाउनलोड करें और एक्सप्लोर करें",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "चैट में 'आप' के स्थान पर उपयोगकर्ता नाम प्रदर्शित करें",
 	"Document": "दस्तावेज़",
 	"Document Settings": "दस्तावेज़ सेटिंग्स",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "निर्यात दस्तावेज़ मैपिंग",
 	"Export Models": "निर्यात मॉडल",
 	"Export Prompts": "प्रॉम्प्ट निर्यात करें",
+	"External Models": "",
 	"Failed to create API Key.": "एपीआई कुंजी बनाने में विफल.",
 	"Failed to read clipboard contents": "क्लिपबोर्ड सामग्री पढ़ने में विफल",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "फ्रीक्वेंसी पेनल्टी",
 	"General": "सामान्य",
 	"General Settings": "सामान्य सेटिंग्स",
+	"Generate Image": "",
 	"Generating search query": "खोज क्वेरी जनरेट करना",
 	"Generation Info": "जनरेशन की जानकारी",
 	"Good Response": "अच्छी प्रतिक्रिया",
@@ -252,6 +260,7 @@
 	"Info": "सूचना-विषयक",
 	"Input commands": "इनपुट क命",
 	"Install from Github URL": "Github URL से इंस्टॉल करें",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "इंटरफेस",
 	"Invalid Tag": "अवैध टैग",
 	"January": "जनवरी",
@@ -264,14 +273,17 @@
 	"JWT Token": "जट टोकन",
 	"Keep Alive": "क्रियाशील रहो",
 	"Keyboard shortcuts": "कीबोर्ड शॉर्टकट",
+	"Knowledge": "",
 	"Language": "भाषा",
 	"Last Active": "पिछली बार सक्रिय",
 	"Light": "सुन",
-	"Listening...": "सुन रहा हूँ...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "एलएलएम गलतियाँ कर सकते हैं। महत्वपूर्ण जानकारी सत्यापित करें.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "OpenWebUI समुदाय द्वारा निर्मित",
 	"Make sure to enclose them with": "उन्हें संलग्न करना सुनिश्चित करें",
+	"Manage": "",
 	"Manage Models": "मॉडल प्रबंधित करें",
 	"Manage Ollama Models": "Ollama मॉडल प्रबंधित करें",
 	"Manage Pipelines": "पाइपलाइनों का प्रबंधन करें",
@@ -307,6 +319,7 @@
 	"Name your model": "अपने मॉडल को नाम दें",
 	"New Chat": "नई चैट",
 	"New Password": "नया पासवर्ड",
+	"No documents found": "",
 	"No results found": "कोई परिणाम नहीं मिला",
 	"No search query generated": "कोई खोज क्वेरी जनरेट नहीं हुई",
 	"No source available": "कोई स्रोत उपलब्ध नहीं है",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "ओलामा एपीआई",
 	"Ollama API disabled": "ओलामा एपीआई अक्षम",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama Version",
 	"On": "चालू",
 	"Only": "केवल",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF दस्तावेज़ (.pdf)",
 	"PDF Extract Images (OCR)": "PDF छवियाँ निकालें (OCR)",
 	"pending": "लंबित",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "माइक्रोफ़ोन तक पहुँचने पर अनुमति अस्वीकृत: {{error}}",
 	"Personalization": "पेरसनलाइज़मेंट",
 	"Pipelines": "पाइपलाइनों",
@@ -367,6 +383,7 @@
 	"Read Aloud": "जोर से पढ़ें",
 	"Record voice": "आवाज रिकॉर्ड करना",
 	"Redirecting you to OpenWebUI Community": "आपको OpenWebUI समुदाय पर पुनर्निर्देशित किया जा रहा है",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "जब ऐसा नहीं होना चाहिए था तो मना कर दिया",
 	"Regenerate": "पुनः जेनरेट",
 	"Release Notes": "रिलीज नोट्स",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "रोसे पिन",
 	"Rosé Pine Dawn": "रोसे पिन डेन",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "सहेजें",
 	"Save & Create": "सहेजें और बनाएं",
 	"Save & Update": "सहेजें और अपडेट करें",
@@ -398,6 +416,8 @@
 	"Search Documents": "दस्तावेज़ खोजें",
 	"Search Models": "मॉडल खोजें",
 	"Search Prompts": "प्रॉम्प्ट खोजें",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "खोज परिणामों की संख्या",
 	"Searched {{count}} sites_one": "{{count}} sites_one खोजा गया",
 	"Searched {{count}} sites_other": "{{count}} sites_other खोजा गया",
@@ -407,12 +427,14 @@
 	"See what's new": "देखें, क्या नया है",
 	"Seed": "सीड्\u200c",
 	"Select a base model": "एक आधार मॉडल का चयन करें",
+	"Select a engine": "",
 	"Select a mode": "एक मोड चुनें",
 	"Select a model": "एक मॉडल चुनें",
 	"Select a pipeline": "एक पाइपलाइन का चयन करें",
 	"Select a pipeline url": "एक पाइपलाइन url चुनें",
 	"Select an Ollama instance": "एक Ollama Instance चुनें",
 	"Select model": "मॉडल चुनें",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "चयनित मॉडल छवि इनपुट का समर्थन नहीं करते हैं",
 	"Send": "भेज",
 	"Send a Message": "एक संदेश भेजो",
@@ -425,7 +447,6 @@
 	"Set Default Model": "डिफ़ॉल्ट मॉडल सेट करें",
 	"Set embedding model (e.g. {{model}})": "ईम्बेडिंग मॉडल सेट करें (उदाहरण: {{model}})",
 	"Set Image Size": "छवि का आकार सेट करें",
-	"Set Model": "मॉडल सेट करें",
 	"Set reranking model (e.g. {{model}})": "रीकरण मॉडल सेट करें (उदाहरण: {{model}})",
 	"Set Steps": "चरण निर्धारित करें",
 	"Set Task Model": "कार्य मॉडल सेट करें",
@@ -449,8 +470,8 @@
 	"Source": "स्रोत",
 	"Speech recognition error: {{error}}": "वाक् पहचान त्रुटि: {{error}}",
 	"Speech-to-Text Engine": "वाक्-से-पाठ इंजन",
-	"SpeechRecognition API is not supported in this browser.": "इस ब्राउज़र में SpeechRecognition API समर्थित नहीं है",
 	"Stop Sequence": "अनुक्रम रोकें",
+	"STT Model": "",
 	"STT Settings": "STT सेटिंग्स ",
 	"Submit": "सबमिट करें",
 	"Subtitle (e.g. about the Roman Empire)": "उपशीर्षक (जैसे रोमन साम्राज्य के बारे में)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "आपकी प्रतिक्रिया के लिए धन्यवाद!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "स्कोर का मान 0.0 (0%) और 1.0 (100%) के बीच होना चाहिए।",
 	"Theme": "थीम",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "यह सुनिश्चित करता है कि आपकी मूल्यवान बातचीत आपके बैकएंड डेटाबेस में सुरक्षित रूप से सहेजी गई है। धन्यवाद!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "यह सेटिंग सभी ब्राउज़रों या डिवाइसों में समन्वयित नहीं होती है",
 	"Thorough explanation": "विस्तृत व्याख्या",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "टिप: प्रत्येक प्रतिस्थापन के बाद चैट इनपुट में टैब कुंजी दबाकर लगातार कई वैरिएबल स्लॉट अपडेट करें।",
@@ -481,6 +504,7 @@
 	"to": "तक",
 	"To access the available model names for downloading,": "डाउनलोड करने के लिए उपलब्ध मॉडल नामों तक पहुंचने के लिए,",
 	"To access the GGUF models available for downloading,": "डाउनलोडिंग के लिए उपलब्ध GGUF मॉडल तक पहुँचने के लिए,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "इनपुट चैट करने के लिए.",
 	"Today": "आज",
 	"Toggle settings": "सेटिंग्स टॉगल करें",
@@ -488,7 +512,9 @@
 	"Top K": "शीर्ष  K",
 	"Top P": "शीर्ष  P",
 	"Trouble accessing Ollama?": "Ollama तक पहुँचने में परेशानी हो रही है?",
+	"TTS Model": "",
 	"TTS Settings": "TTS सेटिंग्स",
+	"TTS Voice": "",
 	"Type": "प्रकार",
 	"Type Hugging Face Resolve (Download) URL": "हगिंग फेस रिज़ॉल्व (डाउनलोड) यूआरएल टाइप करें",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "उह ओह! {{provider}} से कनेक्ट करने में एक समस्या थी।",
@@ -497,6 +523,7 @@
 	"Update password": "पासवर्ड अपडेट करें",
 	"Upload a GGUF model": "GGUF मॉडल अपलोड करें",
 	"Upload Files": "फ़ाइलें अपलोड करें",
+	"Upload Pipeline": "",
 	"Upload Progress": "प्रगति अपलोड करें",
 	"URL Mode": "URL मोड",
 	"Use '#' in the prompt input to load and select your documents.": "अपने दस्तावेज़ों को लोड करने और चुनने के लिए शीघ्र इनपुट में '#' का उपयोग करें।",
@@ -515,6 +542,7 @@
 	"Warning": "चेतावनी",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "चेतावनी: यदि आप अपने एम्बेडिंग मॉडल को अपडेट या बदलते हैं, तो आपको सभी दस्तावेज़ों को फिर से आयात करने की आवश्यकता होगी।",
 	"Web": "वेब",
+	"Web API": "",
 	"Web Loader Settings": "वेब लोडर सेटिंग्स",
 	"Web Params": "वेब पैरामीटर",
 	"Web Search": "वेब खोज",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI अनुरोध करेगा",
 	"What’s New in": "इसमें नया क्या है",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "जब इतिहास बंद हो जाता है, तो इस ब्राउज़र पर नई चैट आपके किसी भी डिवाइस पर इतिहास में दिखाई नहीं देंगी।",
-	"Whisper (Local)": "Whisper (स्थानीय)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "वर्कस्पेस",
 	"Write a prompt suggestion (e.g. Who are you?)": "एक त्वरित सुझाव लिखें (जैसे कि आप कौन हैं?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "50 शब्दों में एक सारांश लिखें जो [विषय या कीवर्ड] का सारांश प्रस्तुत करता हो।",
 	"Yesterday": "कल",
 	"You": "आप",
+	"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 clone a base model": "आप बेस मॉडल का क्लोन नहीं बना सकते",
 	"You have no archived conversations.": "आपको कोई अंकित चैट नहीं है।",
 	"You have shared this chat": "आपने इस चैट को शेयर किया है",
 	"You're a helpful assistant.": "आप एक सहायक सहायक हैं",
 	"You're now logged in.": "अब आप लॉग इन हो गए हैं",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "यूट्यूब लोडर सेटिंग्स"
 }

+ 38 - 8
src/lib/i18n/locales/hr-HR/translation.json

@@ -12,6 +12,7 @@
 	"a user": "korisnik",
 	"About": "O aplikaciji",
 	"Account": "Račun",
+	"Account Activation Pending": "",
 	"Accurate information": "Točne informacije",
 	"Active Users": "",
 	"Add": "Dodaj",
@@ -29,6 +30,7 @@
 	"Add User": "Dodaj korisnika",
 	"Adjusting these settings will apply changes universally to all users.": "Podešavanje će se primijeniti univerzalno na sve korisnike.",
 	"admin": "administrator",
+	"Admin": "",
 	"Admin Panel": "Administratorska ploča",
 	"Admin Settings": "Administratorske postavke",
 	"Advanced Parameters": "Napredni parametri",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Kolovoz",
 	"Auto-playback response": "Automatska reprodukcija odgovora",
-	"Auto-send input after 3 sec.": "Automatsko slanje unosa nakon 3 sek.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 osnovni URL",
 	"AUTOMATIC1111 Base URL is required.": "Potreban je AUTOMATIC1111 osnovni URL.",
 	"available!": "dostupno!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Biti lijen",
 	"Brave Search API Key": "Ključ API-ja za hrabro pretraživanje",
 	"Bypass SSL verification for Websites": "Zaobiđi SSL provjeru za web stranice",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Otkaži",
 	"Capabilities": "Mogućnosti",
 	"Change Password": "Promijeni lozinku",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parametri dijelova",
 	"Chunk Size": "Veličina dijela",
 	"Citation": "Citiranje",
+	"Clear memory": "",
 	"Click here for help.": "Kliknite ovdje za pomoć.",
 	"Click here to": "Kliknite ovdje za",
 	"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.": "",
 	"Click here to select documents.": "Kliknite ovdje da odaberete dokumente.",
 	"click here.": "kliknite ovdje.",
 	"Click on the user role button to change a user's role.": "Kliknite na gumb uloge korisnika za promjenu uloge korisnika.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Istodobni zahtjevi",
 	"Confirm Password": "Potvrdite lozinku",
 	"Connections": "Povezivanja",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Sadržaj",
 	"Context Length": "Dužina konteksta",
 	"Continue Response": "Nastavi odgovor",
-	"Conversation Mode": "Način razgovora",
 	"Copied shared chat URL to clipboard!": "URL dijeljenog razgovora kopiran u međuspremnik!",
 	"Copy": "Kopiraj",
 	"Copy last code block": "Kopiraj zadnji blok koda",
 	"Copy last response": "Kopiraj zadnji odgovor",
 	"Copy Link": "Kopiraj vezu",
 	"Copying to clipboard was successful!": "Kopiranje u međuspremnik je uspješno!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Stvorite sažetu frazu od 3-5 riječi kao naslov za sljedeći upit, strogo se pridržavajući ograničenja od 3-5 riječi i izbjegavajući upotrebu riječi 'naslov':",
 	"Create a model": "Stvaranje modela",
 	"Create Account": "Stvori račun",
 	"Create new key": "Stvori novi ključ",
@@ -127,12 +132,12 @@
 	"Custom": "Prilagođeno",
 	"Customize models for a specific purpose": "Prilagodba modela za određenu svrhu",
 	"Dark": "Tamno",
+	"Dashboard": "",
 	"Database": "Baza podataka",
 	"December": "Prosinac",
 	"Default": "Zadano",
 	"Default (Automatic1111)": "Zadano (Automatic1111)",
 	"Default (SentenceTransformers)": "Zadano (SentenceTransformers)",
-	"Default (Web API)": "Zadano (Web API)",
 	"Default Model": "Zadani model",
 	"Default model updated": "Zadani model ažuriran",
 	"Default Prompt Suggestions": "Zadani prijedlozi prompta",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Otkrijte prompt",
 	"Discover, download, and explore custom prompts": "Otkrijte, preuzmite i istražite prilagođene prompte",
 	"Discover, download, and explore model presets": "Otkrijte, preuzmite i istražite unaprijed postavljene modele",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Prikaži korisničko ime umjesto Vas u razgovoru",
 	"Document": "Dokument",
 	"Document Settings": "Postavke dokumenta",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Izvoz mapiranja dokumenata",
 	"Export Models": "Izvezi modele",
 	"Export Prompts": "Izvoz prompta",
+	"External Models": "",
 	"Failed to create API Key.": "Neuspješno stvaranje API ključa.",
 	"Failed to read clipboard contents": "Neuspješno čitanje sadržaja međuspremnika",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Kazna za učestalost",
 	"General": "Općenito",
 	"General Settings": "Opće postavke",
+	"Generate Image": "",
 	"Generating search query": "Generiranje upita za pretraživanje",
 	"Generation Info": "Informacije o generaciji",
 	"Good Response": "Dobar odgovor",
@@ -252,6 +260,7 @@
 	"Info": "Informacije",
 	"Input commands": "Unos naredbi",
 	"Install from Github URL": "Instaliraj s Github URL-a",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Sučelje",
 	"Invalid Tag": "Nevažeća oznaka",
 	"January": "Siječanj",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT token",
 	"Keep Alive": "Održavanje živim",
 	"Keyboard shortcuts": "Tipkovnički prečaci",
+	"Knowledge": "",
 	"Language": "Jezik",
 	"Last Active": "Zadnja aktivnost",
 	"Light": "Svijetlo",
-	"Listening...": "Slušam...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLM-ovi mogu pogriješiti. Provjerite važne informacije.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Izradio OpenWebUI Community",
 	"Make sure to enclose them with": "Provjerite da ih zatvorite s",
+	"Manage": "",
 	"Manage Models": "Upravljanje modelima",
 	"Manage Ollama Models": "Upravljanje Ollama modelima",
 	"Manage Pipelines": "Upravljanje cjevovodima",
@@ -307,6 +319,7 @@
 	"Name your model": "Dodijelite naziv modelu",
 	"New Chat": "Novi razgovor",
 	"New Password": "Nova lozinka",
+	"No documents found": "",
 	"No results found": "Nema rezultata",
 	"No search query generated": "Nije generiran upit za pretraživanje",
 	"No source available": "Nema dostupnog izvora",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API je onemogućen",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama verzija",
 	"On": "Uključeno",
 	"Only": "Samo",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF dokument (.pdf)",
 	"PDF Extract Images (OCR)": "PDF izdvajanje slika (OCR)",
 	"pending": "u tijeku",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Pristup mikrofonu odbijen: {{error}}",
 	"Personalization": "Prilagodba",
 	"Pipelines": "Cjevovodima",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Čitaj naglas",
 	"Record voice": "Snimanje glasa",
 	"Redirecting you to OpenWebUI Community": "Preusmjeravanje na OpenWebUI zajednicu",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Odbijen kada nije trebao biti",
 	"Regenerate": "Regeneriraj",
 	"Release Notes": "Bilješke o izdanju",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Spremi",
 	"Save & Create": "Spremi i stvori",
 	"Save & Update": "Spremi i ažuriraj",
@@ -398,6 +416,8 @@
 	"Search Documents": "Pretraga dokumenata",
 	"Search Models": "Modeli pretraživanja",
 	"Search Prompts": "Pretraga prompta",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Broj rezultata pretraživanja",
 	"Searched {{count}} sites_one": "Pretraženo {{count}} sites_one",
 	"Searched {{count}} sites_few": "Pretraženo {{count}} sites_few",
@@ -408,12 +428,14 @@
 	"See what's new": "Pogledajte što je novo",
 	"Seed": "Sjeme",
 	"Select a base model": "Odabir osnovnog modela",
+	"Select a engine": "",
 	"Select a mode": "Odaberite način",
 	"Select a model": "Odaberite model",
 	"Select a pipeline": "Odabir kanala",
 	"Select a pipeline url": "Odabir URL-a kanala",
 	"Select an Ollama instance": "Odaberite Ollama instancu",
 	"Select model": "Odaberite model",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Odabrani modeli ne podržavaju unose slika",
 	"Send": "Pošalji",
 	"Send a Message": "Pošaljite poruku",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Postavi zadani model",
 	"Set embedding model (e.g. {{model}})": "Postavi model za embedding (npr. {{model}})",
 	"Set Image Size": "Postavi veličinu slike",
-	"Set Model": "Postavi model",
 	"Set reranking model (e.g. {{model}})": "Postavi model za ponovno rangiranje (npr. {{model}})",
 	"Set Steps": "Postavi korake",
 	"Set Task Model": "Postavi model zadatka",
@@ -450,8 +471,8 @@
 	"Source": "Izvor",
 	"Speech recognition error: {{error}}": "Pogreška prepoznavanja govora: {{error}}",
 	"Speech-to-Text Engine": "Stroj za prepoznavanje govora",
-	"SpeechRecognition API is not supported in this browser.": "API za prepoznavanje govora nije podržan u ovom pregledniku.",
 	"Stop Sequence": "Zaustavi sekvencu",
+	"STT Model": "",
 	"STT Settings": "STT postavke",
 	"Submit": "Pošalji",
 	"Subtitle (e.g. about the Roman Empire)": "Podnaslov (npr. o Rimskom carstvu)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Hvala na povratnim informacijama!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Ocjena treba biti vrijednost između 0,0 (0%) i 1,0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Ovo osigurava da su vaši vrijedni razgovori sigurno spremljeni u bazu podataka. Hvala vam!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Ova postavka se ne sinkronizira između preglednika ili uređaja.",
 	"Thorough explanation": "Detaljno objašnjenje",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Savjet: Ažurirajte više mjesta za varijable uzastopno pritiskom na tipku tab u unosu razgovora nakon svake zamjene.",
@@ -482,6 +505,7 @@
 	"to": "do",
 	"To access the available model names for downloading,": "Za pristup dostupnim nazivima modela za preuzimanje,",
 	"To access the GGUF models available for downloading,": "Za pristup GGUF modelima dostupnim za preuzimanje,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "u unos razgovora.",
 	"Today": "Danas",
 	"Toggle settings": "Prebaci postavke",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemi s pristupom Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS postavke",
+	"TTS Voice": "",
 	"Type": "Tip",
 	"Type Hugging Face Resolve (Download) URL": "Upišite Hugging Face Resolve (Download) URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Pojavio se problem s povezivanjem na {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Ažuriraj lozinku",
 	"Upload a GGUF model": "Učitaj GGUF model",
 	"Upload Files": "Prenesi datoteke",
+	"Upload Pipeline": "",
 	"Upload Progress": "Napredak učitavanja",
 	"URL Mode": "URL način",
 	"Use '#' in the prompt input to load and select your documents.": "Koristite '#' u unosu prompta za učitavanje i odabir vaših dokumenata.",
@@ -516,6 +543,7 @@
 	"Warning": "Upozorenje",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Upozorenje: Ako ažurirate ili promijenite svoj model za umetanje, morat ćete ponovno uvesti sve dokumente.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Postavke web učitavanja",
 	"Web Params": "Web parametri",
 	"Web Search": "Web-pretraživanje",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI će slati zahtjeve na",
 	"What’s New in": "Što je novo u",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Kada je povijest isključena, novi razgovori na ovom pregledniku neće se pojaviti u vašoj povijesti na bilo kojem od vaših uređaja.",
-	"Whisper (Local)": "Whisper (lokalno)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Radna ploča",
 	"Write a prompt suggestion (e.g. Who are you?)": "Napišite prijedlog prompta (npr. Tko si ti?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Napišite sažetak u 50 riječi koji sažima [temu ili ključnu riječ].",
 	"Yesterday": "Jučer",
 	"You": "Vi",
+	"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 clone a base model": "Ne možete klonirati osnovni model",
 	"You have no archived conversations.": "Nemate arhiviranih razgovora.",
 	"You have shared this chat": "Podijelili ste ovaj razgovor",
 	"You're a helpful assistant.": "Vi ste korisni asistent.",
 	"You're now logged in.": "Sada ste prijavljeni.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "YouTube",
 	"Youtube Loader Settings": "YouTube postavke učitavanja"
 }

+ 38 - 8
src/lib/i18n/locales/it-IT/translation.json

@@ -12,6 +12,7 @@
 	"a user": "un utente",
 	"About": "Informazioni",
 	"Account": "Account",
+	"Account Activation Pending": "",
 	"Accurate information": "Informazioni accurate",
 	"Active Users": "",
 	"Add": "Aggiungi",
@@ -29,6 +30,7 @@
 	"Add User": "Aggiungi utente",
 	"Adjusting these settings will apply changes universally to all users.": "La modifica di queste impostazioni applicherà le modifiche universalmente a tutti gli utenti.",
 	"admin": "amministratore",
+	"Admin": "",
 	"Admin Panel": "Pannello di amministrazione",
 	"Admin Settings": "Impostazioni amministratore",
 	"Advanced Parameters": "Parametri avanzati",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Agosto",
 	"Auto-playback response": "Riproduzione automatica della risposta",
-	"Auto-send input after 3 sec.": "Invio automatico dell'input dopo 3 secondi.",
 	"AUTOMATIC1111 Base URL": "URL base AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "L'URL base AUTOMATIC1111 è obbligatorio.",
 	"available!": "disponibile!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Essere pigri",
 	"Brave Search API Key": "Chiave API di ricerca Brave",
 	"Bypass SSL verification for Websites": "Aggira la verifica SSL per i siti web",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Annulla",
 	"Capabilities": "Funzionalità",
 	"Change Password": "Cambia password",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parametri chunk",
 	"Chunk Size": "Dimensione chunk",
 	"Citation": "Citazione",
+	"Clear memory": "",
 	"Click here for help.": "Clicca qui per aiuto.",
 	"Click here to": "Clicca qui per",
 	"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.": "",
 	"Click here to select documents.": "Clicca qui per selezionare i documenti.",
 	"click here.": "clicca qui.",
 	"Click on the user role button to change a user's role.": "Clicca sul pulsante del ruolo utente per modificare il ruolo di un utente.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Richieste simultanee",
 	"Confirm Password": "Conferma password",
 	"Connections": "Connessioni",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Contenuto",
 	"Context Length": "Lunghezza contesto",
 	"Continue Response": "Continua risposta",
-	"Conversation Mode": "Modalità conversazione",
 	"Copied shared chat URL to clipboard!": "URL della chat condivisa copiato negli appunti!",
 	"Copy": "Copia",
 	"Copy last code block": "Copia ultimo blocco di codice",
 	"Copy last response": "Copia ultima risposta",
 	"Copy Link": "Copia link",
 	"Copying to clipboard was successful!": "Copia negli appunti riuscita!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crea una frase concisa di 3-5 parole come intestazione per la seguente query, aderendo rigorosamente al limite di 3-5 parole ed evitando l'uso della parola 'titolo':",
 	"Create a model": "Creare un modello",
 	"Create Account": "Crea account",
 	"Create new key": "Crea nuova chiave",
@@ -127,12 +132,12 @@
 	"Custom": "Personalizzato",
 	"Customize models for a specific purpose": "Personalizza i modelli per uno scopo specifico",
 	"Dark": "Scuro",
+	"Dashboard": "",
 	"Database": "Database",
 	"December": "Dicembre",
 	"Default": "Predefinito",
 	"Default (Automatic1111)": "Predefinito (Automatic1111)",
 	"Default (SentenceTransformers)": "Predefinito (SentenceTransformers)",
-	"Default (Web API)": "Predefinito (API Web)",
 	"Default Model": "Modello di default",
 	"Default model updated": "Modello predefinito aggiornato",
 	"Default Prompt Suggestions": "Suggerimenti prompt predefiniti",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Scopri un prompt",
 	"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
 	"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Visualizza il nome utente invece di Tu nella chat",
 	"Document": "Documento",
 	"Document Settings": "Impostazioni documento",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Esporta mappatura documenti",
 	"Export Models": "Esporta modelli",
 	"Export Prompts": "Esporta prompt",
+	"External Models": "",
 	"Failed to create API Key.": "Impossibile creare la chiave API.",
 	"Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Penalità di frequenza",
 	"General": "Generale",
 	"General Settings": "Impostazioni generali",
+	"Generate Image": "",
 	"Generating search query": "Generazione di query di ricerca",
 	"Generation Info": "Informazioni generazione",
 	"Good Response": "Buona risposta",
@@ -252,6 +260,7 @@
 	"Info": "Informazioni",
 	"Input commands": "Comandi di input",
 	"Install from Github URL": "Eseguire l'installazione dall'URL di Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interfaccia",
 	"Invalid Tag": "Tag non valido",
 	"January": "Gennaio",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Mantieni attivo",
 	"Keyboard shortcuts": "Scorciatoie da tastiera",
+	"Knowledge": "",
 	"Language": "Lingua",
 	"Last Active": "Ultima attività",
 	"Light": "Chiaro",
-	"Listening...": "Ascolto...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Gli LLM possono commettere errori. Verifica le informazioni importanti.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Realizzato dalla comunità OpenWebUI",
 	"Make sure to enclose them with": "Assicurati di racchiuderli con",
+	"Manage": "",
 	"Manage Models": "Gestisci modelli",
 	"Manage Ollama Models": "Gestisci modelli Ollama",
 	"Manage Pipelines": "Gestire le pipeline",
@@ -307,6 +319,7 @@
 	"Name your model": "Assegna un nome al tuo modello",
 	"New Chat": "Nuova chat",
 	"New Password": "Nuova password",
+	"No documents found": "",
 	"No results found": "Nessun risultato trovato",
 	"No search query generated": "Nessuna query di ricerca generata",
 	"No source available": "Nessuna fonte disponibile",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API Ollama disabilitata",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Versione Ollama",
 	"On": "Attivato",
 	"Only": "Solo",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Documento PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Estrazione immagini PDF (OCR)",
 	"pending": "in sospeso",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Autorizzazione negata durante l'accesso al microfono: {{error}}",
 	"Personalization": "Personalizzazione",
 	"Pipelines": "Condutture",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Leggi ad alta voce",
 	"Record voice": "Registra voce",
 	"Redirecting you to OpenWebUI Community": "Reindirizzamento alla comunità OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Rifiutato quando non avrebbe dovuto",
 	"Regenerate": "Rigenera",
 	"Release Notes": "Note di rilascio",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Salva",
 	"Save & Create": "Salva e crea",
 	"Save & Update": "Salva e aggiorna",
@@ -398,6 +416,8 @@
 	"Search Documents": "Cerca documenti",
 	"Search Models": "Cerca modelli",
 	"Search Prompts": "Cerca prompt",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Conteggio dei risultati della ricerca",
 	"Searched {{count}} sites_one": "Ricercato {{count}} sites_one",
 	"Searched {{count}} sites_many": "Ricercato {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Guarda le novità",
 	"Seed": "Seme",
 	"Select a base model": "Selezionare un modello di base",
+	"Select a engine": "",
 	"Select a mode": "Seleziona una modalità",
 	"Select a model": "Seleziona un modello",
 	"Select a pipeline": "Selezionare una tubazione",
 	"Select a pipeline url": "Selezionare l'URL di una pipeline",
 	"Select an Ollama instance": "Seleziona un'istanza Ollama",
 	"Select model": "Seleziona modello",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "I modelli selezionati non supportano l'input di immagini",
 	"Send": "Invia",
 	"Send a Message": "Invia un messaggio",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Imposta modello predefinito",
 	"Set embedding model (e.g. {{model}})": "Imposta modello di embedding (ad esempio {{model}})",
 	"Set Image Size": "Imposta dimensione immagine",
-	"Set Model": "Imposta modello",
 	"Set reranking model (e.g. {{model}})": "Imposta modello di riclassificazione (ad esempio {{model}})",
 	"Set Steps": "Imposta passaggi",
 	"Set Task Model": "Imposta modello di attività",
@@ -450,8 +471,8 @@
 	"Source": "Fonte",
 	"Speech recognition error: {{error}}": "Errore di riconoscimento vocale: {{error}}",
 	"Speech-to-Text Engine": "Motore da voce a testo",
-	"SpeechRecognition API is not supported in this browser.": "L'API SpeechRecognition non è supportata in questo browser.",
 	"Stop Sequence": "Sequenza di arresto",
+	"STT Model": "",
 	"STT Settings": "Impostazioni STT",
 	"Submit": "Invia",
 	"Subtitle (e.g. about the Roman Empire)": "Sottotitolo (ad esempio sull'Impero Romano)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Grazie per il tuo feedback!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Il punteggio dovrebbe essere un valore compreso tra 0.0 (0%) e 1.0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Ciò garantisce che le tue preziose conversazioni siano salvate in modo sicuro nel tuo database backend. Grazie!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Questa impostazione non si sincronizza tra browser o dispositivi.",
 	"Thorough explanation": "Spiegazione dettagliata",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Suggerimento: aggiorna più slot di variabili consecutivamente premendo il tasto tab nell'input della chat dopo ogni sostituzione.",
@@ -482,6 +505,7 @@
 	"to": "a",
 	"To access the available model names for downloading,": "Per accedere ai nomi dei modelli disponibili per il download,",
 	"To access the GGUF models available for downloading,": "Per accedere ai modelli GGUF disponibili per il download,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "all'input della chat.",
 	"Today": "Oggi",
 	"Toggle settings": "Attiva/disattiva impostazioni",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemi di accesso a Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Impostazioni TTS",
+	"TTS Voice": "",
 	"Type": "Digitare",
 	"Type Hugging Face Resolve (Download) URL": "Digita l'URL di Hugging Face Resolve (Download)",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Si è verificato un problema durante la connessione a {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Aggiorna password",
 	"Upload a GGUF model": "Carica un modello GGUF",
 	"Upload Files": "Carica file",
+	"Upload Pipeline": "",
 	"Upload Progress": "Avanzamento caricamento",
 	"URL Mode": "Modalità URL",
 	"Use '#' in the prompt input to load and select your documents.": "Usa '#' nell'input del prompt per caricare e selezionare i tuoi documenti.",
@@ -516,6 +543,7 @@
 	"Warning": "Avvertimento",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Attenzione: se aggiorni o cambi il tuo modello di embedding, dovrai reimportare tutti i documenti.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Impostazioni del caricatore Web",
 	"Web Params": "Parametri Web",
 	"Web Search": "Ricerca sul Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI effettuerà richieste a",
 	"What’s New in": "Novità in",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando la cronologia è disattivata, le nuove chat su questo browser non verranno visualizzate nella cronologia su nessuno dei tuoi dispositivi.",
-	"Whisper (Local)": "Whisper (locale)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Area di lavoro",
 	"Write a prompt suggestion (e.g. Who are you?)": "Scrivi un suggerimento per il prompt (ad esempio Chi sei?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Scrivi un riassunto in 50 parole che riassume [argomento o parola chiave].",
 	"Yesterday": "Ieri",
 	"You": "Tu",
+	"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 clone a base model": "Non è possibile clonare un modello di base",
 	"You have no archived conversations.": "Non hai conversazioni archiviate.",
 	"You have shared this chat": "Hai condiviso questa chat",
 	"You're a helpful assistant.": "Sei un assistente utile.",
 	"You're now logged in.": "Ora hai effettuato l'accesso.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Impostazioni del caricatore Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/ja-JP/translation.json

@@ -12,6 +12,7 @@
 	"a user": "ユーザー",
 	"About": "概要",
 	"Account": "アカウント",
+	"Account Activation Pending": "",
 	"Accurate information": "情報の正確性",
 	"Active Users": "",
 	"Add": "追加",
@@ -29,6 +30,7 @@
 	"Add User": "ユーザーを追加",
 	"Adjusting these settings will apply changes universally to all users.": "これらの設定を調整すると、すべてのユーザーに普遍的に変更が適用されます。",
 	"admin": "管理者",
+	"Admin": "",
 	"Admin Panel": "管理者パネル",
 	"Admin Settings": "管理者設定",
 	"Advanced Parameters": "詳細パラメーター",
@@ -59,7 +61,6 @@
 	"Audio": "オーディオ",
 	"August": "8月",
 	"Auto-playback response": "応答の自動再生",
-	"Auto-send input after 3 sec.": "3 秒後に自動的に出力を送信",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 ベース URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。",
 	"available!": "利用可能!",
@@ -71,6 +72,9 @@
 	"Being lazy": "怠惰な",
 	"Brave Search API Key": "Brave Search APIキー",
 	"Bypass SSL verification for Websites": "SSL 検証をバイパスする",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "キャンセル",
 	"Capabilities": "資格",
 	"Change Password": "パスワードを変更",
@@ -88,10 +92,12 @@
 	"Chunk Params": "チャンクパラメーター",
 	"Chunk Size": "チャンクサイズ",
 	"Citation": "引用文",
+	"Clear memory": "",
 	"Click here for help.": "ヘルプについてはここをクリックしてください。",
 	"Click here to": "ここをクリックして",
 	"Click here to select": "選択するにはここをクリックしてください",
 	"Click here to select a csv file.": "CSVファイルを選択するにはここをクリックしてください。",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "ドキュメントを選択するにはここをクリックしてください。",
 	"click here.": "ここをクリックしてください。",
 	"Click on the user role button to change a user's role.": "ユーザーの役割を変更するには、ユーザー役割ボタンをクリックしてください。",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "コンカレント要求",
 	"Confirm Password": "パスワードを確認",
 	"Connections": "接続",
+	"Contact Admin for WebUI Access": "",
 	"Content": "コンテンツ",
 	"Context Length": "コンテキストの長さ",
 	"Continue Response": "続きの応答",
-	"Conversation Mode": "会話モード",
 	"Copied shared chat URL to clipboard!": "共有チャットURLをクリップボードにコピーしました!",
 	"Copy": "コピー",
 	"Copy last code block": "最後のコードブロックをコピー",
 	"Copy last response": "最後の応答をコピー",
 	"Copy Link": "リンクをコピー",
 	"Copying to clipboard was successful!": "クリップボードへのコピーが成功しました!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "次のクエリの見出しとして、3〜5語の簡潔なフレーズを作成してください。3〜5語の制限を厳守し、「タイトル」という単語の使用を避けてください。",
 	"Create a model": "モデルを作成する",
 	"Create Account": "アカウントを作成",
 	"Create new key": "新しいキーを作成",
@@ -127,12 +132,12 @@
 	"Custom": "カスタム",
 	"Customize models for a specific purpose": "特定の目的に合わせてモデルをカスタマイズする",
 	"Dark": "ダーク",
+	"Dashboard": "",
 	"Database": "データベース",
 	"December": "12月",
 	"Default": "デフォルト",
 	"Default (Automatic1111)": "デフォルト (Automatic1111)",
 	"Default (SentenceTransformers)": "デフォルト (SentenceTransformers)",
-	"Default (Web API)": "デフォルト (Web API)",
 	"Default Model": "デフォルトモデル",
 	"Default model updated": "デフォルトモデルが更新されました",
 	"Default Prompt Suggestions": "デフォルトのプロンプトの提案",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "プロンプトを見つける",
 	"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
 	"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "チャットで「あなた」の代わりにユーザー名を表示",
 	"Document": "ドキュメント",
 	"Document Settings": "ドキュメント設定",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "ドキュメントマッピングをエクスポート",
 	"Export Models": "モデルのエクスポート",
 	"Export Prompts": "プロンプトをエクスポート",
+	"External Models": "",
 	"Failed to create API Key.": "APIキーの作成に失敗しました。",
 	"Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "周波数ペナルティ",
 	"General": "一般",
 	"General Settings": "一般設定",
+	"Generate Image": "",
 	"Generating search query": "検索クエリの生成",
 	"Generation Info": "生成情報",
 	"Good Response": "良い応答",
@@ -252,6 +260,7 @@
 	"Info": "情報",
 	"Input commands": "入力コマンド",
 	"Install from Github URL": "Github URLからインストール",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "インターフェース",
 	"Invalid Tag": "無効なタグ",
 	"January": "1月",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT トークン",
 	"Keep Alive": "キープアライブ",
 	"Keyboard shortcuts": "キーボードショートカット",
+	"Knowledge": "",
 	"Language": "言語",
 	"Last Active": "最終アクティブ",
 	"Light": "ライト",
-	"Listening...": "聞いています...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLM は間違いを犯す可能性があります。重要な情報を検証してください。",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "OpenWebUI コミュニティによって作成",
 	"Make sure to enclose them with": "必ず次で囲んでください",
+	"Manage": "",
 	"Manage Models": "モデルを管理",
 	"Manage Ollama Models": "Ollama モデルを管理",
 	"Manage Pipelines": "パイプラインの管理",
@@ -307,6 +319,7 @@
 	"Name your model": "モデルに名前を付ける",
 	"New Chat": "新しいチャット",
 	"New Password": "新しいパスワード",
+	"No documents found": "",
 	"No results found": "結果が見つかりません",
 	"No search query generated": "検索クエリは生成されません",
 	"No source available": "使用可能なソースがありません",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API が無効になっています",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama バージョン",
 	"On": "オン",
 	"Only": "のみ",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF ドキュメント (.pdf)",
 	"PDF Extract Images (OCR)": "PDF 画像抽出 (OCR)",
 	"pending": "保留中",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "マイクへのアクセス時に権限が拒否されました: {{error}}",
 	"Personalization": "個人化",
 	"Pipelines": "パイプライン",
@@ -367,6 +383,7 @@
 	"Read Aloud": "読み上げ",
 	"Record voice": "音声を録音",
 	"Redirecting you to OpenWebUI Community": "OpenWebUI コミュニティにリダイレクトしています",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "許可されないのに許可されました",
 	"Regenerate": "再生成",
 	"Release Notes": "リリースノート",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "保存",
 	"Save & Create": "保存して作成",
 	"Save & Update": "保存して更新",
@@ -398,6 +416,8 @@
 	"Search Documents": "ドキュメントを検索",
 	"Search Models": "モデル検索",
 	"Search Prompts": "プロンプトを検索",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "検索結果数",
 	"Searched {{count}} sites_other": "{{count}} sites_other検索",
 	"Searching the web for '{{searchQuery}}'": "ウェブで '{{searchQuery}}' を検索する",
@@ -406,12 +426,14 @@
 	"See what's new": "新機能を見る",
 	"Seed": "シード",
 	"Select a base model": "基本モデルの選択",
+	"Select a engine": "",
 	"Select a mode": "モードを選択",
 	"Select a model": "モデルを選択",
 	"Select a pipeline": "パイプラインの選択",
 	"Select a pipeline url": "パイプラインの URL を選択する",
 	"Select an Ollama instance": "Ollama インスタンスを選択",
 	"Select model": "モデルを選択",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "一部のモデルは画像入力をサポートしていません",
 	"Send": "送信",
 	"Send a Message": "メッセージを送信",
@@ -424,7 +446,6 @@
 	"Set Default Model": "デフォルトモデルを設定",
 	"Set embedding model (e.g. {{model}})": "埋め込みモデルを設定します(例:{{model}})",
 	"Set Image Size": "画像サイズを設定",
-	"Set Model": "モデルを設定",
 	"Set reranking model (e.g. {{model}})": "モデルを設定します(例:{{model}})",
 	"Set Steps": "ステップを設定",
 	"Set Task Model": "タスクモデルの設定",
@@ -448,8 +469,8 @@
 	"Source": "ソース",
 	"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
 	"Speech-to-Text Engine": "音声テキスト変換エンジン",
-	"SpeechRecognition API is not supported in this browser.": "このブラウザでは SpeechRecognition API がサポートされていません。",
 	"Stop Sequence": "ストップシーケンス",
+	"STT Model": "",
 	"STT Settings": "STT 設定",
 	"Submit": "送信",
 	"Subtitle (e.g. about the Roman Empire)": "タイトル (例: ロマ帝国)",
@@ -468,7 +489,9 @@
 	"Thanks for your feedback!": "ご意見ありがとうございます!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "スコアは0.0(0%)から1.0(100%)の間の値にしてください。",
 	"Theme": "テーマ",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "これは、貴重な会話がバックエンドデータベースに安全に保存されることを保証します。ありがとうございます!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "この設定は、ブラウザやデバイス間で同期されません。",
 	"Thorough explanation": "詳細な説明",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "ヒント: 各置換後にチャット入力で Tab キーを押すことで、複数の変数スロットを連続して更新できます。",
@@ -480,6 +503,7 @@
 	"to": "まで",
 	"To access the available model names for downloading,": "ダウンロード可能なモデル名にアクセスするには、",
 	"To access the GGUF models available for downloading,": "ダウンロード可能な GGUF モデルにアクセスするには、",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "チャット入力へ。",
 	"Today": "今日",
 	"Toggle settings": "設定を切り替え",
@@ -487,7 +511,9 @@
 	"Top K": "トップ K",
 	"Top P": "トップ P",
 	"Trouble accessing Ollama?": "Ollama へのアクセスに問題がありますか?",
+	"TTS Model": "",
 	"TTS Settings": "TTS 設定",
+	"TTS Voice": "",
 	"Type": "種類",
 	"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ダウンロード) URL を入力してください",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "おっと! {{provider}} への接続に問題が発生しました。",
@@ -496,6 +522,7 @@
 	"Update password": "パスワードを更新",
 	"Upload a GGUF model": "GGUF モデルをアップロード",
 	"Upload Files": "ファイルのアップロード",
+	"Upload Pipeline": "",
 	"Upload Progress": "アップロードの進行状況",
 	"URL Mode": "URL モード",
 	"Use '#' in the prompt input to load and select your documents.": "プロンプト入力で '#' を使用して、ドキュメントを読み込んで選択します。",
@@ -514,6 +541,7 @@
 	"Warning": "警告",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "警告: 埋め込みモデルを更新または変更した場合は、すべてのドキュメントを再インポートする必要があります。",
 	"Web": "ウェブ",
+	"Web API": "",
 	"Web Loader Settings": "Web 読み込み設定",
 	"Web Params": "Web パラメータ",
 	"Web Search": "ウェブ検索",
@@ -524,18 +552,20 @@
 	"WebUI will make requests to": "WebUI は次に対してリクエストを行います",
 	"What’s New in": "新機能",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "履歴が無効になっている場合、このブラウザでの新しいチャットは、どのデバイスの履歴にも表示されません。",
-	"Whisper (Local)": "Whisper (ローカル)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "ワークスペース",
 	"Write a prompt suggestion (e.g. Who are you?)": "プロンプトの提案を書いてください (例: あなたは誰ですか?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "[トピックまたはキーワード] を要約する 50 語の概要を書いてください。",
 	"Yesterday": "昨日",
 	"You": "あなた",
+	"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 clone a base model": "基本モデルのクローンを作成できない",
 	"You have no archived conversations.": "これまでにアーカイブされた会話はありません。",
 	"You have shared this chat": "このチャットを共有しました",
 	"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
 	"You're now logged in.": "ログインしました。",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "YouTube",
 	"Youtube Loader Settings": "Youtubeローダー設定"
 }

+ 38 - 8
src/lib/i18n/locales/ka-GE/translation.json

@@ -12,6 +12,7 @@
 	"a user": "მომხმარებელი",
 	"About": "შესახებ",
 	"Account": "ანგარიში",
+	"Account Activation Pending": "",
 	"Accurate information": "დიდი ინფორმაცია",
 	"Active Users": "",
 	"Add": "დამატება",
@@ -29,6 +30,7 @@
 	"Add User": "მომხმარებლის დამატება",
 	"Adjusting these settings will apply changes universally to all users.": "ამ პარამეტრების რეგულირება ცვლილებებს უნივერსალურად გამოიყენებს ყველა მომხმარებლისთვის",
 	"admin": "ადმინისტრატორი",
+	"Admin": "",
 	"Admin Panel": "ადმინ პანელი",
 	"Admin Settings": "ადმინისტრატორის ხელსაწყოები",
 	"Advanced Parameters": "დამატებითი პარამეტრები",
@@ -59,7 +61,6 @@
 	"Audio": "ხმოვანი",
 	"August": "აგვისტო",
 	"Auto-playback response": "ავტომატური დაკვრის პასუხი",
-	"Auto-send input after 3 sec.": "შეყვანის ავტომატური გაგზავნა 3 წამის შემდეგ ",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 საბაზისო მისამართი",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 საბაზისო მისამართი აუცილებელია",
 	"available!": "ხელმისაწვდომია!",
@@ -71,6 +72,9 @@
 	"Being lazy": "ჩაიტყვევა",
 	"Brave Search API Key": "Brave Search API გასაღები",
 	"Bypass SSL verification for Websites": "SSL-ის ვერიფიკაციის გააუქმება ვებსაიტებზე",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "გაუქმება",
 	"Capabilities": "შესაძლებლობები",
 	"Change Password": "პაროლის შეცვლა",
@@ -88,10 +92,12 @@
 	"Chunk Params": "გადახურვის პარამეტრები",
 	"Chunk Size": "გადახურვის ზომა",
 	"Citation": "ციტატა",
+	"Clear memory": "",
 	"Click here for help.": "დახმარებისთვის, დააკლიკე აქ",
 	"Click here to": "დააკლიკე აქ",
 	"Click here to select": "ასარჩევად, დააკლიკე აქ",
 	"Click here to select a csv file.": "ასარჩევად, დააკლიკე აქ",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "დოკუმენტების ასარჩევად, დააკლიკე აქ",
 	"click here.": "დააკლიკე აქ",
 	"Click on the user role button to change a user's role.": "დააკლიკეთ მომხმარებლის როლის ღილაკს რომ შეცვალოთ მომხმარების როლი",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "თანმხლები მოთხოვნები",
 	"Confirm Password": "პაროლის დამოწმება",
 	"Connections": "კავშირები",
+	"Contact Admin for WebUI Access": "",
 	"Content": "კონტენტი",
 	"Context Length": "კონტექსტის სიგრძე",
 	"Continue Response": "პასუხის გაგრძელება",
-	"Conversation Mode": "საუბრი რეჟიმი",
 	"Copied shared chat URL to clipboard!": "ყავს ჩათის URL-ი კლიპბორდში!",
 	"Copy": "კოპირება",
 	"Copy last code block": "ბოლო ბლოკის კოპირება",
 	"Copy last response": "ბოლო პასუხის კოპირება",
 	"Copy Link": "კოპირება",
 	"Copying to clipboard was successful!": "კლავიატურაზე კოპირება წარმატებით დასრულდა",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "შექმენით მოკლე, 3-5 სიტყვიანი ფრაზა, როგორც სათაური თქვენი შემდეგი შეკითხვისთვის, მკაცრად დაიცავით 3-5 სიტყვის ლიმიტი და მოერიდეთ გამოიყენოთ სიტყვა „სათაური“.",
 	"Create a model": "შექმენით მოდელი",
 	"Create Account": "ანგარიშის შექმნა",
 	"Create new key": "პირადი ღირებულბრის შექმნა",
@@ -127,12 +132,12 @@
 	"Custom": "საკუთარი",
 	"Customize models for a specific purpose": "მოდელების მორგება კონკრეტული მიზნისთვის",
 	"Dark": "მუქი",
+	"Dashboard": "",
 	"Database": "მონაცემთა ბაზა",
 	"December": "დეკემბერი",
 	"Default": "დეფოლტი",
 	"Default (Automatic1111)": "დეფოლტ (Automatic1111)",
 	"Default (SentenceTransformers)": "დეფოლტ (SentenceTransformers)",
-	"Default (Web API)": "დეფოლტ (Web API)",
 	"Default Model": "ნაგულისხმები მოდელი",
 	"Default model updated": "დეფოლტ მოდელი განახლებულია",
 	"Default Prompt Suggestions": "დეფოლტ პრომპტი პირველი პირველი",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "აღმოაჩინეთ მოთხოვნა",
 	"Discover, download, and explore custom prompts": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მორგებული მოთხოვნები",
 	"Discover, download, and explore model presets": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მოდელის წინასწარ პარამეტრები",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "ჩატში აჩვენე მომხმარებლის სახელი თქვენს ნაცვლად",
 	"Document": "დოკუმენტი",
 	"Document Settings": "დოკუმენტის პარამეტრები",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "დოკუმენტების კავშირის ექსპორტი",
 	"Export Models": "ექსპორტის მოდელები",
 	"Export Prompts": "მოთხოვნების ექსპორტი",
+	"External Models": "",
 	"Failed to create API Key.": "API ღილაკის შექმნა ვერ მოხერხდა.",
 	"Failed to read clipboard contents": "ბუფერში შიგთავსის წაკითხვა ვერ მოხერხდა",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "სიხშირის ჯარიმა",
 	"General": "ზოგადი",
 	"General Settings": "ზოგადი პარამეტრები",
+	"Generate Image": "",
 	"Generating search query": "საძიებო მოთხოვნის გენერირება",
 	"Generation Info": "გენერაციის ინფორმაცია",
 	"Good Response": "დიდი პასუხი",
@@ -252,6 +260,7 @@
 	"Info": "ინფორმაცია",
 	"Input commands": "შეყვანით ბრძანებებს",
 	"Install from Github URL": "დააინსტალირეთ Github URL- დან",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "ინტერფეისი",
 	"Invalid Tag": "არასწორი ტეგი",
 	"January": "იანვარი",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT ტოკენი",
 	"Keep Alive": "აქტიურად დატოვება",
 	"Keyboard shortcuts": "კლავიატურის მალსახმობები",
+	"Knowledge": "",
 	"Language": "ენა",
 	"Last Active": "ბოლო აქტიური",
 	"Light": "მსუბუქი",
-	"Listening...": "გისმენ...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "შესაძლოა LLM-ებმა შეცდომები დაუშვან. გადაამოწმეთ მნიშვნელოვანი ინფორმაცია.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "დამზადებულია OpenWebUI საზოგადოების მიერ",
 	"Make sure to enclose them with": "დარწმუნდით, რომ დაურთეთ ისინი",
+	"Manage": "",
 	"Manage Models": "მოდელების მართვა",
 	"Manage Ollama Models": "Ollama მოდელების მართვა",
 	"Manage Pipelines": "მილსადენების მართვა",
@@ -307,6 +319,7 @@
 	"Name your model": "დაასახელეთ თქვენი მოდელი",
 	"New Chat": "ახალი მიმოწერა",
 	"New Password": "ახალი პაროლი",
+	"No documents found": "",
 	"No results found": "ჩვენ ვერ პოულობით ნაპოვნი ჩაწერები",
 	"No search query generated": "ძიების მოთხოვნა არ არის გენერირებული",
 	"No source available": "წყარო არ არის ხელმისაწვდომი",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API გამორთულია",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama ვერსია",
 	"On": "ჩართვა",
 	"Only": "მხოლოდ",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF დოკუმენტი (.pdf)",
 	"PDF Extract Images (OCR)": "PDF იდან ამოღებული სურათები (OCR)",
 	"pending": "ლოდინის რეჟიმშია",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "ნებართვა უარყოფილია მიკროფონზე წვდომისას: {{error}}",
 	"Personalization": "პერსონალიზაცია",
 	"Pipelines": "მილსადენები",
@@ -367,6 +383,7 @@
 	"Read Aloud": "ხმის ჩაწერა",
 	"Record voice": "ხმის ჩაწერა",
 	"Redirecting you to OpenWebUI Community": "გადამისამართდებით OpenWebUI საზოგადოებაში",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "უარა, როგორც უნდა იყოს",
 	"Regenerate": "ხელახლა გენერირება",
 	"Release Notes": "Გამოშვების შენიშვნები",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "ვარდისფერი ფიჭვის ხე",
 	"Rosé Pine Dawn": "ვარდისფერი ფიჭვის გარიჟრაჟი",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "შენახვა",
 	"Save & Create": "დამახსოვრება და შექმნა",
 	"Save & Update": "დამახსოვრება და განახლება",
@@ -398,6 +416,8 @@
 	"Search Documents": "დოკუმენტების ძიება",
 	"Search Models": "საძიებო მოდელები",
 	"Search Prompts": "მოთხოვნების ძიება",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "ძიების შედეგების რაოდენობა",
 	"Searched {{count}} sites_one": "Searched {{count}} sites_one",
 	"Searched {{count}} sites_other": "Searched {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "სიახლეების ნახვა",
 	"Seed": "სიდი",
 	"Select a base model": "აირჩიეთ ბაზის მოდელი",
+	"Select a engine": "",
 	"Select a mode": "რეჟიმის არჩევა",
 	"Select a model": "მოდელის არჩევა",
 	"Select a pipeline": "აირჩიეთ მილსადენი",
 	"Select a pipeline url": "აირჩიეთ მილსადენის url",
 	"Select an Ollama instance": "Ollama ინსტანსის არჩევა",
 	"Select model": "მოდელის არჩევა",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "შერჩეული მოდელი (ებ) ი არ უჭერს მხარს გამოსახულების შეყვანას",
 	"Send": "გაგზავნა",
 	"Send a Message": "შეტყობინების გაგზავნა",
@@ -425,7 +447,6 @@
 	"Set Default Model": "დეფოლტ მოდელის დაყენება",
 	"Set embedding model (e.g. {{model}})": "ჩვენება მოდელის დაყენება (მაგ. {{model}})",
 	"Set Image Size": "სურათის ზომის დაყენება",
-	"Set Model": "მოდელის დაყენება",
 	"Set reranking model (e.g. {{model}})": "რეტარირება მოდელის დაყენება (მაგ. {{model}})",
 	"Set Steps": "ნაბიჯების დაყენება",
 	"Set Task Model": "დააყენეთ სამუშაო მოდელი",
@@ -449,8 +470,8 @@
 	"Source": "წყარო",
 	"Speech recognition error: {{error}}": "მეტყველების ამოცნობის შეცდომა: {{error}}",
 	"Speech-to-Text Engine": "ხმოვან-ტექსტური ძრავი",
-	"SpeechRecognition API is not supported in this browser.": "მეტყველების ამოცნობის API არ არის მხარდაჭერილი ამ ბრაუზერში.",
 	"Stop Sequence": "შეჩერების თანმიმდევრობა",
+	"STT Model": "",
 	"STT Settings": "მეტყველების ამოცნობის პარამეტრები",
 	"Submit": "გაგზავნა",
 	"Subtitle (e.g. about the Roman Empire)": "სუბტიტრები (მაგ. რომის იმპერიის შესახებ)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "მადლობა გამოხმაურებისთვის!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "ქულა 0.0 (0%) და 1.0 (100%) ჩაშენებული უნდა იყოს.",
 	"Theme": "თემა",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "ეს უზრუნველყოფს, რომ თქვენი ძვირფასი საუბრები უსაფრთხოდ შეინახება თქვენს backend მონაცემთა ბაზაში. Გმადლობთ!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "ეს პარამეტრი არ სინქრონიზდება ბრაუზერებსა და მოწყობილობებში",
 	"Thorough explanation": "ვრცლად აღწერა",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "რჩევა: განაახლეთ რამდენიმე ცვლადი სლოტი თანმიმდევრულად, ყოველი ჩანაცვლების შემდეგ ჩატის ღილაკზე დაჭერით.",
@@ -481,6 +504,7 @@
 	"to": "ში",
 	"To access the available model names for downloading,": "ჩამოტვირთვისთვის ხელმისაწვდომი მოდელების სახელებზე წვდომისთვის",
 	"To access the GGUF models available for downloading,": "ჩასატვირთად ხელმისაწვდომი GGUF მოდელებზე წვდომისთვის",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "ჩატში",
 	"Today": "დღეს",
 	"Toggle settings": "პარამეტრების გადართვა",
@@ -488,7 +512,9 @@
 	"Top K": "ტოპ K",
 	"Top P": "ტოპ P",
 	"Trouble accessing Ollama?": "Ollama-ს ვერ უკავშირდები?",
+	"TTS Model": "",
 	"TTS Settings": "TTS პარამეტრები",
+	"TTS Voice": "",
 	"Type": "ტიპი",
 	"Type Hugging Face Resolve (Download) URL": "სცადე გადმოწერო Hugging Face Resolve URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "{{provider}}-თან დაკავშირების პრობლემა წარმოიშვა.",
@@ -497,6 +523,7 @@
 	"Update password": "პაროლის განახლება",
 	"Upload a GGUF model": "GGUF მოდელის ატვირთვა",
 	"Upload Files": "ატვირთეთ ფაილები",
+	"Upload Pipeline": "",
 	"Upload Progress": "პროგრესის ატვირთვა",
 	"URL Mode": "URL რეჟიმი",
 	"Use '#' in the prompt input to load and select your documents.": "პრომტში გამოიყენე '#' რომელიც გაიტანს დოკუმენტებს",
@@ -515,6 +542,7 @@
 	"Warning": "გაფრთხილება",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "გაფრთხილება: თუ განაახლებთ ან შეცვლით ჩანერგვის მოდელს, მოგიწევთ ყველა დოკუმენტის ხელახლა იმპორტი.",
 	"Web": "ვები",
+	"Web API": "",
 	"Web Loader Settings": "ვების ჩატარების პარამეტრები",
 	"Web Params": "ვების პარამეტრები",
 	"Web Search": "ვებ ძებნა",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI გამოგიგზავნით მოთხოვნებს",
 	"What’s New in": "რა არის ახალი",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "როდესაც ისტორია გამორთულია, ახალი ჩეთები ამ ბრაუზერში არ გამოჩნდება თქვენს ისტორიაში არცერთ მოწყობილობაზე.",
-	"Whisper (Local)": "ჩურჩული (ადგილობრივი)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "ვულერი",
 	"Write a prompt suggestion (e.g. Who are you?)": "დაწერეთ მოკლე წინადადება (მაგ. ვინ ხარ?",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "დაწერეთ რეზიუმე 50 სიტყვით, რომელიც აჯამებს [თემას ან საკვანძო სიტყვას].",
 	"Yesterday": "აღდგენა",
 	"You": "ჩემი",
+	"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 clone a base model": "თქვენ არ შეგიძლიათ ბაზის მოდელის კლონირება",
 	"You have no archived conversations.": "არ ხართ არქივირებული განხილვები.",
 	"You have shared this chat": "ამ ჩატის გააგზავნა",
 	"You're a helpful assistant.": "თქვენ სასარგებლო ასისტენტი ხართ.",
 	"You're now logged in.": "თქვენ შესული ხართ.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube Loader Settings"
 }

+ 38 - 8
src/lib/i18n/locales/ko-KR/translation.json

@@ -12,6 +12,7 @@
 	"a user": "사용자",
 	"About": "소개",
 	"Account": "계정",
+	"Account Activation Pending": "",
 	"Accurate information": "정확한 정보",
 	"Active Users": "",
 	"Add": "추가",
@@ -29,6 +30,7 @@
 	"Add User": "사용자 추가",
 	"Adjusting these settings will apply changes universally to all users.": "이 설정을 조정하면 모든 사용자에게 적용됩니다.",
 	"admin": "관리자",
+	"Admin": "",
 	"Admin Panel": "관리자 패널",
 	"Admin Settings": "관리자 설정",
 	"Advanced Parameters": "고급 매개변수",
@@ -59,7 +61,6 @@
 	"Audio": "오디오",
 	"August": "8월",
 	"Auto-playback response": "응답 자동 재생",
-	"Auto-send input after 3 sec.": "3초 후 입력 자동 전송",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Base URL이 필요합니다.",
 	"available!": "사용 가능!",
@@ -71,6 +72,9 @@
 	"Being lazy": "게으름 피우기",
 	"Brave Search API Key": "Brave Search API 키",
 	"Bypass SSL verification for Websites": "SSL 검증을 무시하려면 웹 사이트를 선택하세요.",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "취소",
 	"Capabilities": "기능",
 	"Change Password": "비밀번호 변경",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Citation": "인용",
+	"Clear memory": "",
 	"Click here for help.": "도움말을 보려면 여기를 클릭하세요.",
 	"Click here to": "여기를 클릭하면",
 	"Click here to select": "선택하려면 여기를 클릭하세요.",
 	"Click here to select a csv file.": "csv 파일을 선택하려면 여기를 클릭하세요.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "문서를 선택하려면 여기를 클릭하세요.",
 	"click here.": "여기를 클릭하세요.",
 	"Click on the user role button to change a user's role.": "사용자 역할 버튼을 클릭하여 사용자의 역할을 변경하세요.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "동시 요청",
 	"Confirm Password": "비밀번호 확인",
 	"Connections": "연결",
+	"Contact Admin for WebUI Access": "",
 	"Content": "내용",
 	"Context Length": "내용 길이",
 	"Continue Response": "대화 계속",
-	"Conversation Mode": "대화 모드",
 	"Copied shared chat URL to clipboard!": "공유 채팅 URL이 클립보드에 복사되었습니다!",
 	"Copy": "복사",
 	"Copy last code block": "마지막 코드 블록 복사",
 	"Copy last response": "마지막 응답 복사",
 	"Copy Link": "링크 복사",
 	"Copying to clipboard was successful!": "클립보드에 복사되었습니다!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "다음 질문에 대한 제목으로 간결한 3-5 단어 문구를 만드되 3-5 단어 제한을 엄격히 준수하고 'title' 단어 사용을 피하세요:",
 	"Create a model": "모델 만들기",
 	"Create Account": "계정 만들기",
 	"Create new key": "새 키 만들기",
@@ -127,12 +132,12 @@
 	"Custom": "사용자 정의",
 	"Customize models for a specific purpose": "특정 목적을 위한 모델 사용자 지정",
 	"Dark": "어두운",
+	"Dashboard": "",
 	"Database": "데이터베이스",
 	"December": "12월",
 	"Default": "기본값",
 	"Default (Automatic1111)": "기본값 (Automatic1111)",
 	"Default (SentenceTransformers)": "기본값 (SentenceTransformers)",
-	"Default (Web API)": "기본값 (Web API)",
 	"Default Model": "기본 모델",
 	"Default model updated": "기본 모델이 업데이트되었습니다.",
 	"Default Prompt Suggestions": "기본 프롬프트 제안",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "프롬프트 검색",
 	"Discover, download, and explore custom prompts": "사용자 정의 프롬프트 검색, 다운로드 및 탐색",
 	"Discover, download, and explore model presets": "모델 사전 설정 검색, 다운로드 및 탐색",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "채팅에서 'You' 대신 사용자 이름 표시",
 	"Document": "문서",
 	"Document Settings": "문서 설정",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "문서 매핑 내보내기",
 	"Export Models": "모델 내보내기",
 	"Export Prompts": "프롬프트 내보내기",
+	"External Models": "",
 	"Failed to create API Key.": "API 키 생성에 실패했습니다.",
 	"Failed to read clipboard contents": "클립보드 내용을 읽는 데 실패했습니다.",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "주파수 페널티",
 	"General": "일반",
 	"General Settings": "일반 설정",
+	"Generate Image": "",
 	"Generating search query": "검색 쿼리 생성",
 	"Generation Info": "생성 정보",
 	"Good Response": "좋은 응답",
@@ -252,6 +260,7 @@
 	"Info": "정보",
 	"Input commands": "입력 명령",
 	"Install from Github URL": "Github URL에서 설치",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "인터페이스",
 	"Invalid Tag": "잘못된 태그",
 	"January": "1월",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT 토큰",
 	"Keep Alive": "계속 유지하기",
 	"Keyboard shortcuts": "키보드 단축키",
+	"Knowledge": "",
 	"Language": "언어",
 	"Last Active": "최근 활동",
 	"Light": "밝음",
-	"Listening...": "청취 중...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLM은 실수를 할 수 있습니다. 중요한 정보를 확인하세요.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "OpenWebUI 커뮤니티에서 제작",
 	"Make sure to enclose them with": "다음으로 묶는 것을 잊지 마세요:",
+	"Manage": "",
 	"Manage Models": "모델 관리",
 	"Manage Ollama Models": "Ollama 모델 관리",
 	"Manage Pipelines": "파이프라인 관리",
@@ -307,6 +319,7 @@
 	"Name your model": "모델 이름 지정",
 	"New Chat": "새 채팅",
 	"New Password": "새 비밀번호",
+	"No documents found": "",
 	"No results found": "결과 없음",
 	"No search query generated": "검색어가 생성되지 않았습니다.",
 	"No source available": "사용 가능한 소스 없음",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "올라마 API",
 	"Ollama API disabled": "Ollama API 사용 안 함",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama 버전",
 	"On": "켜기",
 	"Only": "오직",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF 문서 (.pdf)",
 	"PDF Extract Images (OCR)": "PDF에서 이미지 추출 (OCR)",
 	"pending": "보류 중",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "마이크 액세스가 거부되었습니다: {{error}}",
 	"Personalization": "개인화",
 	"Pipelines": "파이프라인",
@@ -367,6 +383,7 @@
 	"Read Aloud": "읽어주기",
 	"Record voice": "음성 녹음",
 	"Redirecting you to OpenWebUI Community": "OpenWebUI 커뮤니티로 리디렉션하는 중",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "허용되지 않았지만 허용되어야 합니다.",
 	"Regenerate": "재생성",
 	"Release Notes": "릴리스 노트",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "로제 파인",
 	"Rosé Pine Dawn": "로제 파인 던",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "저장",
 	"Save & Create": "저장 및 생성",
 	"Save & Update": "저장 및 업데이트",
@@ -398,6 +416,8 @@
 	"Search Documents": "문서 검색",
 	"Search Models": "모델 검색",
 	"Search Prompts": "프롬프트 검색",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "검색 결과 개수",
 	"Searched {{count}} sites_other": "{{count}} sites_other 검색됨",
 	"Searching the web for '{{searchQuery}}'": "웹에서 '{{searchQuery}}' 검색",
@@ -406,12 +426,14 @@
 	"See what's new": "새로운 기능 보기",
 	"Seed": "시드",
 	"Select a base model": "기본 모델 선택",
+	"Select a engine": "",
 	"Select a mode": "모드 선택",
 	"Select a model": "모델 선택",
 	"Select a pipeline": "파이프라인 선택",
 	"Select a pipeline url": "파이프라인 URL 선택",
 	"Select an Ollama instance": "Ollama 인스턴스 선택",
 	"Select model": "모델 선택",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "선택한 모델은 이미지 입력을 지원하지 않습니다.",
 	"Send": "보내기",
 	"Send a Message": "메시지 보내기",
@@ -424,7 +446,6 @@
 	"Set Default Model": "기본 모델 설정",
 	"Set embedding model (e.g. {{model}})": "임베딩 모델 설정 (예: {{model}})",
 	"Set Image Size": "이미지 크기 설정",
-	"Set Model": "모델 설정",
 	"Set reranking model (e.g. {{model}})": "랭킹 모델 설정 (예: {{model}})",
 	"Set Steps": "단계 설정",
 	"Set Task Model": "작업 모델 설정",
@@ -448,8 +469,8 @@
 	"Source": "출처",
 	"Speech recognition error: {{error}}": "음성 인식 오류: {{error}}",
 	"Speech-to-Text Engine": "음성-텍스트 엔진",
-	"SpeechRecognition API is not supported in this browser.": "이 브라우저에서는 SpeechRecognition API를 지원하지 않습니다.",
 	"Stop Sequence": "중지 시퀀스",
+	"STT Model": "",
 	"STT Settings": "STT 설정",
 	"Submit": "제출",
 	"Subtitle (e.g. about the Roman Empire)": "캡션 (예: 로마 황제)",
@@ -468,7 +489,9 @@
 	"Thanks for your feedback!": "너의 피드백 감사합니다!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "점수는 0.0 (0%)에서 1.0 (100%) 사이의 값이어야 합니다.",
 	"Theme": "테마",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "이렇게 하면 소중한 대화 내용이 백엔드 데이터베이스에 안전하게 저장됩니다. 감사합니다!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "이 설정은 브라우저 또는 장치 간에 동기화되지 않습니다.",
 	"Thorough explanation": "철저한 설명",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "팁: 각 대체 후 채팅 입력에서 탭 키를 눌러 여러 개의 변수 슬롯을 연속적으로 업데이트하세요.",
@@ -480,6 +503,7 @@
 	"to": "~까지",
 	"To access the available model names for downloading,": "다운로드 가능한 모델명을 확인하려면,",
 	"To access the GGUF models available for downloading,": "다운로드 가능한 GGUF 모델을 확인하려면,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "채팅 입력으로.",
 	"Today": "오늘",
 	"Toggle settings": "설정 전환",
@@ -487,7 +511,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Ollama에 접근하는 데 문제가 있나요?",
+	"TTS Model": "",
 	"TTS Settings": "TTS 설정",
+	"TTS Voice": "",
 	"Type": "형",
 	"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (다운로드) URL 입력",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "앗! {{provider}}에 연결하는 데 문제가 있었습니다.",
@@ -496,6 +522,7 @@
 	"Update password": "비밀번호 업데이트",
 	"Upload a GGUF model": "GGUF 모델 업로드",
 	"Upload Files": "파일 업로드",
+	"Upload Pipeline": "",
 	"Upload Progress": "업로드 진행 상황",
 	"URL Mode": "URL 모드",
 	"Use '#' in the prompt input to load and select your documents.": "프롬프트 입력에서 '#'를 사용하여 문서를 로드하고 선택하세요.",
@@ -514,6 +541,7 @@
 	"Warning": "경고",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "웹 로더를 업데이트하거나 변경할 경우 모든 문서를 다시 가져와야 합니다.",
 	"Web": "웹",
+	"Web API": "",
 	"Web Loader Settings": "웹 로더 설정",
 	"Web Params": "웹 파라미터",
 	"Web Search": "웹 검색",
@@ -524,18 +552,20 @@
 	"WebUI will make requests to": "WebUI가 요청할 대상:",
 	"What’s New in": "새로운 기능:",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "기록 기능이 꺼져 있으면 이 브라우저의 새 채팅이 다른 장치의 채팅 기록에 나타나지 않습니다.",
-	"Whisper (Local)": "위스퍼 (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "워크스페이스",
 	"Write a prompt suggestion (e.g. Who are you?)": "프롬프트 제안 작성 (예: 당신은 누구인가요?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "[주제 또는 키워드]에 대한 50단어 요약문 작성.",
 	"Yesterday": "어제",
 	"You": "당신",
+	"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 clone a base model": "기본 모델은 복제할 수 없습니다",
 	"You have no archived conversations.": "채팅을 아카이브한 적이 없습니다.",
 	"You have shared this chat": "이 채팅을 공유했습니다.",
 	"You're a helpful assistant.": "당신은 유용한 어시스턴트입니다.",
 	"You're now logged in.": "로그인되었습니다.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "유튜브",
 	"Youtube Loader Settings": "유튜브 로더 설정"
 }

+ 38 - 8
src/lib/i18n/locales/lt-LT/translation.json

@@ -12,6 +12,7 @@
 	"a user": "naudotojas",
 	"About": "Apie",
 	"Account": "Paskyra",
+	"Account Activation Pending": "",
 	"Accurate information": "Tiksli informacija",
 	"Active Users": "",
 	"Add": "",
@@ -29,6 +30,7 @@
 	"Add User": "Pridėti naudotoją",
 	"Adjusting these settings will apply changes universally to all users.": "Šių nustatymų pakeitimas bus pritakytas visiems naudotojams.",
 	"admin": "Administratorius",
+	"Admin": "",
 	"Admin Panel": "Administratorių panelė",
 	"Admin Settings": "Administratorių nustatymai",
 	"Advanced Parameters": "Gilieji nustatymai",
@@ -59,7 +61,6 @@
 	"Audio": "Audio įrašas",
 	"August": "Rugpjūtis",
 	"Auto-playback response": "Automatinis atsakymo skaitymas",
-	"Auto-send input after 3 sec.": "Automatiškai išsiųsti įvestį po 3 sek.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 bazės nuoroda",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 bazės nuoroda reikalinga.",
 	"available!": "prieinama!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Būvimas tingiu",
 	"Brave Search API Key": "",
 	"Bypass SSL verification for Websites": "Išvengti SSL patikros puslapiams",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Atšaukti",
 	"Capabilities": "",
 	"Change Password": "Keisti slaptažodį",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Blokų nustatymai",
 	"Chunk Size": "Blokų dydis",
 	"Citation": "Citata",
+	"Clear memory": "",
 	"Click here for help.": "Paspauskite čia dėl pagalbos.",
 	"Click here to": "Paspauskite čia, kad:",
 	"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.": "",
 	"Click here to select documents.": "Spauskite čia norėdami pasirinkti dokumentus.",
 	"click here.": "paspauskite čia.",
 	"Click on the user role button to change a user's role.": "Paspauskite ant naudotojo rolės mygtuko tam, kad pakeisti naudotojo rolę.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "",
 	"Confirm Password": "Patvirtinkite slaptažodį",
 	"Connections": "Ryšiai",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Turinys",
 	"Context Length": "Konteksto ilgis",
 	"Continue Response": "Tęsti atsakymą",
-	"Conversation Mode": "Pokalbio metodas",
 	"Copied shared chat URL to clipboard!": "Nukopijavote pokalbio nuorodą",
 	"Copy": "Kopijuoti",
 	"Copy last code block": "Kopijuoti paskutinį kodo bloką",
 	"Copy last response": "Kopijuoti paskutinį atsakymą",
 	"Copy Link": "Kopijuoti nuorodą",
 	"Copying to clipboard was successful!": "La copie dans le presse-papiers a réussi !",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Créez une phrase concise de 3-5 mots comme en-tête pour la requête suivante, en respectant strictement la limite de 3-5 mots et en évitant l'utilisation du mot 'titre' :",
 	"Create a model": "",
 	"Create Account": "Créer un compte",
 	"Create new key": "Sukurti naują raktą",
@@ -127,12 +132,12 @@
 	"Custom": "Personalizuota",
 	"Customize models for a specific purpose": "",
 	"Dark": "Tamsus",
+	"Dashboard": "",
 	"Database": "Duomenų bazė",
 	"December": "Gruodis",
 	"Default": "Numatytasis",
 	"Default (Automatic1111)": "Numatytasis (Automatic1111)",
 	"Default (SentenceTransformers)": "Numatytasis (SentenceTransformers)",
-	"Default (Web API)": "Numatytasis (API Web)",
 	"Default Model": "",
 	"Default model updated": "Numatytasis modelis atnaujintas",
 	"Default Prompt Suggestions": "Numatytieji užklausų pasiūlymai",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Atrasti užklausas",
 	"Discover, download, and explore custom prompts": "Atrasti ir parsisiųsti užklausas",
 	"Discover, download, and explore model presets": "Atrasti ir parsisiųsti modelių konfigūracija",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Rodyti naudotojo vardą vietoje žodžio Jūs pokalbyje",
 	"Document": "Dokumentas",
 	"Document Settings": "Dokumento nuostatos",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Eksportuoti dokumentų žemėlapį",
 	"Export Models": "",
 	"Export Prompts": "Eksportuoti užklausas",
+	"External Models": "",
 	"Failed to create API Key.": "Nepavyko sukurti API rakto",
 	"Failed to read clipboard contents": "Nepavyko perskaityti kopijuoklės",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "",
 	"General": "Bendri",
 	"General Settings": "Bendri nustatymai",
+	"Generate Image": "",
 	"Generating search query": "",
 	"Generation Info": "Generavimo informacija",
 	"Good Response": "Geras atsakymas",
@@ -252,6 +260,7 @@
 	"Info": "",
 	"Input commands": "Įvesties komandos",
 	"Install from Github URL": "",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Sąsaja",
 	"Invalid Tag": "Neteisinga žyma",
 	"January": "Sausis",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT žetonas",
 	"Keep Alive": "Išlaikyti aktyviu",
 	"Keyboard shortcuts": "Klaviatūros trumpiniai",
+	"Knowledge": "",
 	"Language": "Kalba",
 	"Last Active": "Paskutinį kartą aktyvus",
 	"Light": "Šviesus",
-	"Listening...": "Klauso...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "Dideli kalbos modeliai gali klysti. Patikrinkite atsakymų teisingumą.",
+	"Local Models": "",
 	"LTR": "",
 	"Made by OpenWebUI Community": "Sukurta OpenWebUI bendruomenės",
 	"Make sure to enclose them with": "Užtikrinktie, kad įtraukiate viduje:",
+	"Manage": "",
 	"Manage Models": "Tvarkyti modelius",
 	"Manage Ollama Models": "Tvarkyti Ollama modelius",
 	"Manage Pipelines": "",
@@ -307,6 +319,7 @@
 	"Name your model": "",
 	"New Chat": "Naujas pokalbis",
 	"New Password": "Naujas slaptažodis",
+	"No documents found": "",
 	"No results found": "Rezultatų nerasta",
 	"No search query generated": "",
 	"No source available": "Šaltinių nerasta",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "",
 	"Ollama API disabled": "",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama versija",
 	"On": "Aktyvuota",
 	"Only": "Tiktais",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF dokumentas (.pdf)",
 	"PDF Extract Images (OCR)": "PDF paveikslėlių skaitymas (OCR)",
 	"pending": "laukiama",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Leidimas naudoti mikrofoną atmestas: {{error}}",
 	"Personalization": "",
 	"Pipelines": "",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Skaityti garsiai",
 	"Record voice": "Įrašyti balsą",
 	"Redirecting you to OpenWebUI Community": "Perkeliam Jus į OpenWebUI bendruomenę",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Atmesta kai neturėtų būti atmesta",
 	"Regenerate": "Generuoti iš naujo",
 	"Release Notes": "Naujovės",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "",
+	"Running": "",
 	"Save": "Išsaugoti",
 	"Save & Create": "Išsaugoti ir sukurti",
 	"Save & Update": "Išsaugoti ir atnaujinti",
@@ -398,6 +416,8 @@
 	"Search Documents": "Ieškoti dokumentų",
 	"Search Models": "",
 	"Search Prompts": "Ieškoti užklausų",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "",
 	"Searched {{count}} sites_one": "",
 	"Searched {{count}} sites_few": "",
@@ -409,12 +429,14 @@
 	"See what's new": "Žiūrėti naujoves",
 	"Seed": "Sėkla",
 	"Select a base model": "",
+	"Select a engine": "",
 	"Select a mode": "Pasirinkti režimą",
 	"Select a model": "Pasirinkti modelį",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select an Ollama instance": "Pasirinkti Ollama instanciją",
 	"Select model": "Pasirinkti modelį",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "",
 	"Send": "",
 	"Send a Message": "Siųsti žinutę",
@@ -427,7 +449,6 @@
 	"Set Default Model": "Nustatyti numatytąjį modelį",
 	"Set embedding model (e.g. {{model}})": "Nustatyti embedding modelį",
 	"Set Image Size": "Nustatyti paveikslėlių dydį",
-	"Set Model": "Nustatyti modelį",
 	"Set reranking model (e.g. {{model}})": "Nustatyti reranking modelį",
 	"Set Steps": "Numatyti etapus",
 	"Set Task Model": "",
@@ -451,8 +472,8 @@
 	"Source": "Šaltinis",
 	"Speech recognition error: {{error}}": "Balso atpažinimo problema: {{error}}",
 	"Speech-to-Text Engine": "Balso atpažinimo modelis",
-	"SpeechRecognition API is not supported in this browser.": "Šioje naršyklėje negalimas balso atpažinimas.",
 	"Stop Sequence": "Baigt sekvenciją",
+	"STT Model": "",
 	"STT Settings": "STT nustatymai",
 	"Submit": "Pateikti",
 	"Subtitle (e.g. about the Roman Empire)": "Subtitras",
@@ -471,7 +492,9 @@
 	"Thanks for your feedback!": "Ačiū už atsiliepimus",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Rezultatas turėtų būti tarp 0.0 (0%) ir 1.0 (100%)",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Tai užtikrina, kad Jūsų pokalbiai saugiai saugojami duomenų bazėje. Ačiū!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Šis parametras nesisinchronizuoja su skirtingomis naršyklėmis ir įrankiais.",
 	"Thorough explanation": "Platus paaiškinimas",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Jei norite pakeisti keletą kintamųjų vieną po kitos, spauskite Tab",
@@ -483,6 +506,7 @@
 	"to": "kam",
 	"To access the available model names for downloading,": "Tam, kad prieiti prie galimų parsisiųsti modelių",
 	"To access the GGUF models available for downloading,": "Tam, kad prieiti prie galimų parsisiųsti GGUF,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "į pokalbio įvestį",
 	"Today": "Šiandien",
 	"Toggle settings": "Atverti/užverti parametrus",
@@ -490,7 +514,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemos prieinant prie Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS parametrai",
+	"TTS Voice": "",
 	"Type": "",
 	"Type Hugging Face Resolve (Download) URL": "Įveskite Hugging Face Resolve nuorodą",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "O ne! Prisijungiant prie {{provider}} kilo problema.",
@@ -499,6 +525,7 @@
 	"Update password": "Atnaujinti slaptažodį",
 	"Upload a GGUF model": "Parsisiųsti GGUF modelį",
 	"Upload Files": "",
+	"Upload Pipeline": "",
 	"Upload Progress": "Įkėlimo progresas",
 	"URL Mode": "URL režimas",
 	"Use '#' in the prompt input to load and select your documents.": "Naudokite '#' norėdami naudoti dokumentą.",
@@ -517,6 +544,7 @@
 	"Warning": "",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Jei pakeisite embedding modelį, turėsite reimportuoti visus dokumentus",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web krovimo nustatymai",
 	"Web Params": "Web nustatymai",
 	"Web Search": "",
@@ -527,18 +555,20 @@
 	"WebUI will make requests to": "WebUI vykdys užklausas",
 	"What’s New in": "Kas naujo",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Kai istorija išjungta, pokalbiai neatsiras jūsų istorijoje.",
-	"Whisper (Local)": "Whisper (lokalus)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "",
 	"Write a prompt suggestion (e.g. Who are you?)": "Parašykite užklausą",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Parašyk santrumpą trumpesnę nei 50 žodžių šiam tekstui: [tekstas]",
 	"Yesterday": "Vakar",
 	"You": "Jūs",
+	"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 clone a base model": "",
 	"You have no archived conversations.": "Jūs neturite archyvuotų pokalbių",
 	"You have shared this chat": "Pasidalinote šiuo pokalbiu",
 	"You're a helpful assistant.": "Esi asistentas.",
 	"You're now logged in.": "Esate prisijungę.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube krovimo nustatymai"
 }

+ 38 - 8
src/lib/i18n/locales/nb-NO/translation.json

@@ -12,6 +12,7 @@
 	"a user": "en bruker",
 	"About": "Om",
 	"Account": "Konto",
+	"Account Activation Pending": "",
 	"Accurate information": "Nøyaktig informasjon",
 	"Active Users": "",
 	"Add": "Legg til",
@@ -29,6 +30,7 @@
 	"Add User": "Legg til bruker",
 	"Adjusting these settings will apply changes universally to all users.": "Justering av disse innstillingene vil gjelde universelt for alle brukere.",
 	"admin": "administrator",
+	"Admin": "",
 	"Admin Panel": "Administrasjonspanel",
 	"Admin Settings": "Administrasjonsinnstillinger",
 	"Advanced Parameters": "Avanserte parametere",
@@ -59,7 +61,6 @@
 	"Audio": "Lyd",
 	"August": "August",
 	"Auto-playback response": "Automatisk avspilling av svar",
-	"Auto-send input after 3 sec.": "Send automatisk input etter 3 sek.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Grunn-URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Grunn-URL kreves.",
 	"available!": "tilgjengelig!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Er lat",
 	"Brave Search API Key": "Brave Search API-nøkkel",
 	"Bypass SSL verification for Websites": "Omgå SSL-verifisering for nettsteder",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Avbryt",
 	"Capabilities": "Muligheter",
 	"Change Password": "Endre passord",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk-parametere",
 	"Chunk Size": "Chunk-størrelse",
 	"Citation": "Sitering",
+	"Clear memory": "",
 	"Click here for help.": "Klikk her for hjelp.",
 	"Click here to": "Klikk her for å",
 	"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.": "",
 	"Click here to select documents.": "Klikk her for å velge dokumenter.",
 	"click here.": "klikk her.",
 	"Click on the user role button to change a user's role.": "Klikk på brukerrolle-knappen for å endre en brukers rolle.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Samtidige forespørsler",
 	"Confirm Password": "Bekreft passord",
 	"Connections": "Tilkoblinger",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Innhold",
 	"Context Length": "Kontekstlengde",
 	"Continue Response": "Fortsett svar",
-	"Conversation Mode": "Samtalemodus",
 	"Copied shared chat URL to clipboard!": "Kopiert delt chat-URL til utklippstavlen!",
 	"Copy": "Kopier",
 	"Copy last code block": "Kopier siste kodeblokk",
 	"Copy last response": "Kopier siste svar",
 	"Copy Link": "Kopier lenke",
 	"Copying to clipboard was successful!": "Kopiering til utklippstavlen var vellykket!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Lag en kort, 3-5 ords frase som en overskrift for den følgende forespørselen, strikt overhold 3-5 ords grensen og unngå bruk av ordet 'tittel':",
 	"Create a model": "Lag en modell",
 	"Create Account": "Opprett konto",
 	"Create new key": "Lag ny nøkkel",
@@ -127,12 +132,12 @@
 	"Custom": "Tilpasset",
 	"Customize models for a specific purpose": "Tilpass modeller for et spesifikt formål",
 	"Dark": "Mørk",
+	"Dashboard": "",
 	"Database": "Database",
 	"December": "Desember",
 	"Default": "Standard",
 	"Default (Automatic1111)": "Standard (Automatic1111)",
 	"Default (SentenceTransformers)": "Standard (SentenceTransformers)",
-	"Default (Web API)": "Standard (Web API)",
 	"Default Model": "Standardmodell",
 	"Default model updated": "Standardmodell oppdatert",
 	"Default Prompt Suggestions": "Standard promptforslag",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Oppdag en prompt",
 	"Discover, download, and explore custom prompts": "Oppdag, last ned og utforsk egendefinerte prompts",
 	"Discover, download, and explore model presets": "Oppdag, last ned og utforsk modellforhåndsinnstillinger",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Vis brukernavnet i stedet for Du i chatten",
 	"Document": "Dokument",
 	"Document Settings": "Dokumentinnstillinger",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Eksporter dokumentkartlegging",
 	"Export Models": "Eksporter modeller",
 	"Export Prompts": "Eksporter prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Kunne ikke opprette API-nøkkel.",
 	"Failed to read clipboard contents": "Kunne ikke lese utklippstavleinnhold",
 	"Failed to update settings": "Kunne ikke oppdatere innstillinger",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Frekvensstraff",
 	"General": "Generelt",
 	"General Settings": "Generelle innstillinger",
+	"Generate Image": "",
 	"Generating search query": "Genererer søkeforespørsel",
 	"Generation Info": "Generasjonsinfo",
 	"Good Response": "Godt svar",
@@ -252,6 +260,7 @@
 	"Info": "Info",
 	"Input commands": "Inntast kommandoer",
 	"Install from Github URL": "Installer fra Github-URL",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Grensesnitt",
 	"Invalid Tag": "Ugyldig tag",
 	"January": "Januar",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT-token",
 	"Keep Alive": "Hold i live",
 	"Keyboard shortcuts": "Hurtigtaster",
+	"Knowledge": "",
 	"Language": "Språk",
 	"Last Active": "Sist aktiv",
 	"Light": "Lys",
-	"Listening...": "Lytter...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLM-er kan gjøre feil. Verifiser viktig informasjon.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Laget av OpenWebUI-fellesskapet",
 	"Make sure to enclose them with": "Sørg for å omslutte dem med",
+	"Manage": "",
 	"Manage Models": "Administrer modeller",
 	"Manage Ollama Models": "Administrer Ollama-modeller",
 	"Manage Pipelines": "Administrer pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Gi modellen din et navn",
 	"New Chat": "Ny chat",
 	"New Password": "Nytt passord",
+	"No documents found": "",
 	"No results found": "Ingen resultater funnet",
 	"No search query generated": "Ingen søkeforespørsel generert",
 	"No source available": "Ingen kilde tilgjengelig",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API deaktivert",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama versjon",
 	"On": "På",
 	"Only": "Kun",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF-dokument (.pdf)",
 	"PDF Extract Images (OCR)": "PDF-ekstraktbilder (OCR)",
 	"pending": "avventer",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Tillatelse nektet ved tilgang til mikrofon: {{error}}",
 	"Personalization": "Personalisering",
 	"Pipelines": "Pipelines",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Les høyt",
 	"Record voice": "Ta opp stemme",
 	"Redirecting you to OpenWebUI Community": "Omdirigerer deg til OpenWebUI-fellesskapet",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Avvist når det ikke skulle ha vært det",
 	"Regenerate": "Regenerer",
 	"Release Notes": "Utgivelsesnotater",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Lagre",
 	"Save & Create": "Lagre og opprett",
 	"Save & Update": "Lagre og oppdater",
@@ -398,6 +416,8 @@
 	"Search Documents": "Søk dokumenter",
 	"Search Models": "Søk modeller",
 	"Search Prompts": "Søk prompter",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Antall søkeresultater",
 	"Searched {{count}} sites_one": "Søkte på {{count}} side",
 	"Searched {{count}} sites_other": "Søkte på {{count}} sider",
@@ -407,12 +427,14 @@
 	"See what's new": "Se hva som er nytt",
 	"Seed": "Seed",
 	"Select a base model": "Velg en grunnmodell",
+	"Select a engine": "",
 	"Select a mode": "Velg en modus",
 	"Select a model": "Velg en modell",
 	"Select a pipeline": "Velg en pipeline",
 	"Select a pipeline url": "Velg en pipeline-URL",
 	"Select an Ollama instance": "Velg en Ollama-instans",
 	"Select model": "Velg modell",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Valgte modell(er) støtter ikke bildeforslag",
 	"Send": "Send",
 	"Send a Message": "Send en melding",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Sett standardmodell",
 	"Set embedding model (e.g. {{model}})": "Sett embedding-modell (f.eks. {{model}})",
 	"Set Image Size": "Sett bildestørrelse",
-	"Set Model": "Sett modell",
 	"Set reranking model (e.g. {{model}})": "Sett reranking-modell (f.eks. {{model}})",
 	"Set Steps": "Sett steg",
 	"Set Task Model": "Sett oppgavemodell",
@@ -449,8 +470,8 @@
 	"Source": "Kilde",
 	"Speech recognition error: {{error}}": "Feil ved talegjenkjenning: {{error}}",
 	"Speech-to-Text Engine": "Tale-til-tekst-motor",
-	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API støttes ikke i denne nettleseren.",
 	"Stop Sequence": "Stoppsekvens",
+	"STT Model": "",
 	"STT Settings": "STT-innstillinger",
 	"Submit": "Send inn",
 	"Subtitle (e.g. about the Roman Empire)": "Undertittel (f.eks. om Romerriket)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "Takk for tilbakemeldingen!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Poengsummen skal være en verdi mellom 0,0 (0%) og 1,0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Dette sikrer at dine verdifulle samtaler er trygt lagret i backend-databasen din. Takk!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Denne innstillingen synkroniseres ikke mellom nettlesere eller enheter.",
 	"Thorough explanation": "Grundig forklaring",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Tips: Oppdater flere variabelplasser etter hverandre ved å trykke på tab-tasten i chatinputen etter hver erstatning.",
@@ -481,6 +504,7 @@
 	"to": "til",
 	"To access the available model names for downloading,": "For å få tilgang til tilgjengelige modelnavn for nedlasting,",
 	"To access the GGUF models available for downloading,": "For å få tilgang til GGUF-modellene som er tilgjengelige for nedlasting,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "til chatinput.",
 	"Today": "I dag",
 	"Toggle settings": "Veksle innstillinger",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemer med tilgang til Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS-innstillinger",
+	"TTS Voice": "",
 	"Type": "Type",
 	"Type Hugging Face Resolve (Download) URL": "Skriv inn Hugging Face Resolve (nedlasting) URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Oops! Det oppsto et problem med tilkoblingen til {{provider}}.",
@@ -497,6 +523,7 @@
 	"Update password": "Oppdater passord",
 	"Upload a GGUF model": "Last opp en GGUF-modell",
 	"Upload Files": "Last opp filer",
+	"Upload Pipeline": "",
 	"Upload Progress": "Opplastingsfremdrift",
 	"URL Mode": "URL-modus",
 	"Use '#' in the prompt input to load and select your documents.": "Bruk '#' i prompt-input for å laste og velge dokumentene dine.",
@@ -515,6 +542,7 @@
 	"Warning": "Advarsel",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Advarsel: Hvis du oppdaterer eller endrer embedding-modellen din, må du re-importere alle dokumenter.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web-lasterinnstillinger",
 	"Web Params": "Web-parametere",
 	"Web Search": "Websøk",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI vil gjøre forespørsler til",
 	"What’s New in": "Hva er nytt i",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Når historikken er slått av, vil nye chatter på denne nettleseren ikke vises i historikken din på noen av enhetene dine.",
-	"Whisper (Local)": "Whisper (lokal)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Arbeidsområde",
 	"Write a prompt suggestion (e.g. Who are you?)": "Skriv et promptforslag (f.eks. Hvem er du?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Skriv et sammendrag på 50 ord som oppsummerer [emne eller nøkkelord].",
 	"Yesterday": "I går",
 	"You": "Du",
+	"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 clone a base model": "Du kan ikke klone en grunnmodell",
 	"You have no archived conversations.": "Du har ingen arkiverte samtaler.",
 	"You have shared this chat": "Du har delt denne chatten",
 	"You're a helpful assistant.": "Du er en hjelpsom assistent.",
 	"You're now logged in.": "Du er nå logget inn.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube-lasterinnstillinger"
 }

+ 38 - 8
src/lib/i18n/locales/nl-NL/translation.json

@@ -12,6 +12,7 @@
 	"a user": "een gebruiker",
 	"About": "Over",
 	"Account": "Account",
+	"Account Activation Pending": "",
 	"Accurate information": "Accurate informatie",
 	"Active Users": "",
 	"Add": "Toevoegen",
@@ -29,6 +30,7 @@
 	"Add User": "Voeg Gebruiker toe",
 	"Adjusting these settings will apply changes universally to all users.": "Het aanpassen van deze instellingen zal universeel worden toegepast op alle gebruikers.",
 	"admin": "admin",
+	"Admin": "",
 	"Admin Panel": "Administratieve Paneel",
 	"Admin Settings": "Administratieve Settings",
 	"Advanced Parameters": "Geavanceerde Parameters",
@@ -59,7 +61,6 @@
 	"Audio": "Audio",
 	"August": "Augustus",
 	"Auto-playback response": "Automatisch afspelen van antwoord",
-	"Auto-send input after 3 sec.": "Automatisch verzenden van input na 3 sec.",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Basis URL is verplicht",
 	"available!": "beschikbaar!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Lustig zijn",
 	"Brave Search API Key": "Brave Search API-sleutel",
 	"Bypass SSL verification for Websites": "SSL-verificatie omzeilen voor websites",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Annuleren",
 	"Capabilities": "Mogelijkheden",
 	"Change Password": "Wijzig Wachtwoord",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Grootte",
 	"Citation": "Citaat",
+	"Clear memory": "",
 	"Click here for help.": "Klik hier voor hulp.",
 	"Click here to": "Klik hier om",
 	"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.": "",
 	"Click here to select documents.": "Klik hier om documenten te selecteren",
 	"click here.": "klik hier.",
 	"Click on the user role button to change a user's role.": "Klik op de gebruikersrol knop om de rol van een gebruiker te wijzigen.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Gelijktijdige verzoeken",
 	"Confirm Password": "Bevestig Wachtwoord",
 	"Connections": "Verbindingen",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Inhoud",
 	"Context Length": "Context Lengte",
 	"Continue Response": "Doorgaan met Antwoord",
-	"Conversation Mode": "Gespreksmodus",
 	"Copied shared chat URL to clipboard!": "URL van gedeelde gesprekspagina gekopieerd naar klembord!",
 	"Copy": "Kopieer",
 	"Copy last code block": "Kopieer laatste code blok",
 	"Copy last response": "Kopieer laatste antwoord",
 	"Copy Link": "Kopieer Link",
 	"Copying to clipboard was successful!": "Kopiëren naar klembord was succesvol!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Maak een beknopte, 3-5 woorden tellende zin als kop voor de volgende query, strikt aanhoudend aan de 3-5 woorden limiet en het vermijden van het gebruik van het woord 'titel':",
 	"Create a model": "Een model maken",
 	"Create Account": "Maak Account",
 	"Create new key": "Maak nieuwe sleutel",
@@ -127,12 +132,12 @@
 	"Custom": "Aangepast",
 	"Customize models for a specific purpose": "Modellen aanpassen voor een specifiek doel",
 	"Dark": "Donker",
+	"Dashboard": "",
 	"Database": "Database",
 	"December": "December",
 	"Default": "Standaard",
 	"Default (Automatic1111)": "Standaard (Automatic1111)",
 	"Default (SentenceTransformers)": "Standaard (SentenceTransformers)",
-	"Default (Web API)": "Standaard (Web API)",
 	"Default Model": "Standaard model",
 	"Default model updated": "Standaard model bijgewerkt",
 	"Default Prompt Suggestions": "Standaard Prompt Suggesties",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Ontdek een prompt",
 	"Discover, download, and explore custom prompts": "Ontdek, download en verken aangepaste prompts",
 	"Discover, download, and explore model presets": "Ontdek, download en verken model presets",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Toon de gebruikersnaam in plaats van Jij in de Chat",
 	"Document": "Document",
 	"Document Settings": "Document Instellingen",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exporteer Documenten Mapping",
 	"Export Models": "Modellen exporteren",
 	"Export Prompts": "Exporteer Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Kan API Key niet aanmaken.",
 	"Failed to read clipboard contents": "Kan klembord inhoud niet lezen",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Frequentie Straf",
 	"General": "Algemeen",
 	"General Settings": "Algemene Instellingen",
+	"Generate Image": "",
 	"Generating search query": "Zoekopdracht genereren",
 	"Generation Info": "Generatie Info",
 	"Good Response": "Goede Antwoord",
@@ -252,6 +260,7 @@
 	"Info": "Info",
 	"Input commands": "Voer commando's in",
 	"Install from Github URL": "Installeren vanaf Github-URL",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "Ongeldige Tag",
 	"January": "Januari",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT Token",
 	"Keep Alive": "Houd Actief",
 	"Keyboard shortcuts": "Toetsenbord snelkoppelingen",
+	"Knowledge": "",
 	"Language": "Taal",
 	"Last Active": "Laatst Actief",
 	"Light": "Licht",
-	"Listening...": "Luisteren...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs kunnen fouten maken. Verifieer belangrijke informatie.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Gemaakt door OpenWebUI Community",
 	"Make sure to enclose them with": "Zorg ervoor dat je ze omringt met",
+	"Manage": "",
 	"Manage Models": "Beheer Modellen",
 	"Manage Ollama Models": "Beheer Ollama Modellen",
 	"Manage Pipelines": "Pijplijnen beheren",
@@ -307,6 +319,7 @@
 	"Name your model": "Geef uw model een naam",
 	"New Chat": "Nieuwe Chat",
 	"New Password": "Nieuw Wachtwoord",
+	"No documents found": "",
 	"No results found": "Geen resultaten gevonden",
 	"No search query generated": "Geen zoekopdracht gegenereerd",
 	"No source available": "Geen bron beschikbaar",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API uitgeschakeld",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Ollama Versie",
 	"On": "Aan",
 	"Only": "Alleen",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF document (.pdf)",
 	"PDF Extract Images (OCR)": "PDF Extract Afbeeldingen (OCR)",
 	"pending": "wachtend",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Toestemming geweigerd bij toegang tot microfoon: {{error}}",
 	"Personalization": "Personalisatie",
 	"Pipelines": "Pijpleidingen",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Voorlezen",
 	"Record voice": "Neem stem op",
 	"Redirecting you to OpenWebUI Community": "Je wordt doorgestuurd naar OpenWebUI Community",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Geweigerd terwijl het niet had moeten",
 	"Regenerate": "Regenereren",
 	"Release Notes": "Release Notes",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Opslaan",
 	"Save & Create": "Opslaan & Creëren",
 	"Save & Update": "Opslaan & Bijwerken",
@@ -398,6 +416,8 @@
 	"Search Documents": "Zoek Documenten",
 	"Search Models": "Modellen zoeken",
 	"Search Prompts": "Zoek Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Aantal zoekresultaten",
 	"Searched {{count}} sites_one": "Gezocht op {{count}} sites_one",
 	"Searched {{count}} sites_other": "Gezocht op {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "Zie wat er nieuw is",
 	"Seed": "Seed",
 	"Select a base model": "Selecteer een basismodel",
+	"Select a engine": "",
 	"Select a mode": "Selecteer een modus",
 	"Select a model": "Selecteer een model",
 	"Select a pipeline": "Selecteer een pijplijn",
 	"Select a pipeline url": "Selecteer een pijplijn-URL",
 	"Select an Ollama instance": "Selecteer een Ollama instantie",
 	"Select model": "Selecteer een model",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Geselecteerde modellen ondersteunen geen beeldinvoer",
 	"Send": "Verzenden",
 	"Send a Message": "Stuur een Bericht",
@@ -425,7 +447,6 @@
 	"Set Default Model": "Stel Standaard Model in",
 	"Set embedding model (e.g. {{model}})": "Stel embedding model in (bv. {{model}})",
 	"Set Image Size": "Stel Afbeelding Grootte in",
-	"Set Model": "Stel die model op",
 	"Set reranking model (e.g. {{model}})": "Stel reranking model in (bv. {{model}})",
 	"Set Steps": "Stel Stappen in",
 	"Set Task Model": "Taakmodel instellen",
@@ -449,8 +470,8 @@
 	"Source": "Bron",
 	"Speech recognition error: {{error}}": "Spraakherkenning fout: {{error}}",
 	"Speech-to-Text Engine": "Spraak-naar-tekst Engine",
-	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API wordt niet ondersteund in deze browser.",
 	"Stop Sequence": "Stop Sequentie",
+	"STT Model": "",
 	"STT Settings": "STT Instellingen",
 	"Submit": "Verzenden",
 	"Subtitle (e.g. about the Roman Empire)": "Ondertitel (bijv. over de Romeinse Empire)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "Bedankt voor uw feedback!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Het score moet een waarde zijn tussen 0.0 (0%) en 1.0 (100%).",
 	"Theme": "Thema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Dit zorgt ervoor dat je waardevolle gesprekken veilig worden opgeslagen in je backend database. Dank je wel!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Deze instelling wordt niet gesynchroniseerd tussen browsers of apparaten.",
 	"Thorough explanation": "Gevorderde uitleg",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Tip: Werk meerdere variabele slots achtereenvolgens bij door op de tab-toets te drukken in de chat input na elke vervanging.",
@@ -481,6 +504,7 @@
 	"to": "naar",
 	"To access the available model names for downloading,": "Om de beschikbare modelnamen voor downloaden te openen,",
 	"To access the GGUF models available for downloading,": "Om toegang te krijgen tot de GGUF modellen die beschikbaar zijn voor downloaden,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "naar chat input.",
 	"Today": "Vandaag",
 	"Toggle settings": "Wissel instellingen",
@@ -488,7 +512,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemen met toegang tot Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "TTS instellingen",
+	"TTS Voice": "",
 	"Type": "Type",
 	"Type Hugging Face Resolve (Download) URL": "Type Hugging Face Resolve (Download) URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Er was een probleem met verbinden met {{provider}}.",
@@ -497,6 +523,7 @@
 	"Update password": "Wijzig wachtwoord",
 	"Upload a GGUF model": "Upload een GGUF model",
 	"Upload Files": "Bestanden uploaden",
+	"Upload Pipeline": "",
 	"Upload Progress": "Upload Voortgang",
 	"URL Mode": "URL Modus",
 	"Use '#' in the prompt input to load and select your documents.": "Gebruik '#' in de prompt input om je documenten te laden en te selecteren.",
@@ -515,6 +542,7 @@
 	"Warning": "Waarschuwing",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Warning: Als je de embedding model bijwerkt of wijzigt, moet je alle documenten opnieuw importeren.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Web Loader instellingen",
 	"Web Params": "Web Params",
 	"Web Search": "Zoeken op het web",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "WebUI zal verzoeken doen naar",
 	"What’s New in": "Wat is nieuw in",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Wanneer geschiedenis is uitgeschakeld, zullen nieuwe chats op deze browser niet verschijnen in je geschiedenis op een van je apparaten.",
-	"Whisper (Local)": "Fluister (Lokaal)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Werkruimte",
 	"Write a prompt suggestion (e.g. Who are you?)": "Schrijf een prompt suggestie (bijv. Wie ben je?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Schrijf een samenvatting in 50 woorden die [onderwerp of trefwoord] samenvat.",
 	"Yesterday": "gisteren",
 	"You": "U",
+	"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 clone a base model": "U kunt een basismodel niet klonen",
 	"You have no archived conversations.": "U heeft geen gearchiveerde gesprekken.",
 	"You have shared this chat": "U heeft dit gesprek gedeeld",
 	"You're a helpful assistant.": "Jij bent een behulpzame assistent.",
 	"You're now logged in.": "Je bent nu ingelogd.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube-laderinstellingen"
 }

+ 38 - 8
src/lib/i18n/locales/pa-IN/translation.json

@@ -12,6 +12,7 @@
 	"a user": "ਇੱਕ ਉਪਭੋਗਤਾ",
 	"About": "ਬਾਰੇ",
 	"Account": "ਖਾਤਾ",
+	"Account Activation Pending": "",
 	"Accurate information": "ਸਹੀ ਜਾਣਕਾਰੀ",
 	"Active Users": "",
 	"Add": "ਸ਼ਾਮਲ ਕਰੋ",
@@ -29,6 +30,7 @@
 	"Add User": "ਉਪਭੋਗਤਾ ਸ਼ਾਮਲ ਕਰੋ",
 	"Adjusting these settings will apply changes universally to all users.": "ਇਹ ਸੈਟਿੰਗਾਂ ਨੂੰ ਠੀਕ ਕਰਨ ਨਾਲ ਸਾਰੇ ਉਪਭੋਗਤਾਵਾਂ ਲਈ ਬਦਲਾਅ ਲਾਗੂ ਹੋਣਗੇ।",
 	"admin": "ਪ੍ਰਬੰਧਕ",
+	"Admin": "",
 	"Admin Panel": "ਪ੍ਰਬੰਧਕ ਪੈਨਲ",
 	"Admin Settings": "ਪ੍ਰਬੰਧਕ ਸੈਟਿੰਗਾਂ",
 	"Advanced Parameters": "ਉੱਚ ਸਤਰ ਦੇ ਪੈਰਾਮੀਟਰ",
@@ -59,7 +61,6 @@
 	"Audio": "ਆਡੀਓ",
 	"August": "ਅਗਸਤ",
 	"Auto-playback response": "ਆਟੋ-ਪਲੇਬੈਕ ਜਵਾਬ",
-	"Auto-send input after 3 sec.": "3 ਸਕਿੰਟ ਬਾਅਦ ਆਟੋ-ਭੇਜੋ ਇਨਪੁਟ",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 ਬੇਸ URL",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ਬੇਸ URL ਦੀ ਲੋੜ ਹੈ।",
 	"available!": "ਉਪਲਬਧ ਹੈ!",
@@ -71,6 +72,9 @@
 	"Being lazy": "ਆਲਸੀ ਹੋਣਾ",
 	"Brave Search API Key": "ਬਹਾਦਰ ਖੋਜ API ਕੁੰਜੀ",
 	"Bypass SSL verification for Websites": "ਵੈਬਸਾਈਟਾਂ ਲਈ SSL ਪ੍ਰਮਾਣਿਕਤਾ ਨੂੰ ਬਾਈਪਾਸ ਕਰੋ",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "ਰੱਦ ਕਰੋ",
 	"Capabilities": "ਸਮਰੱਥਾਵਾਂ",
 	"Change Password": "ਪਾਸਵਰਡ ਬਦਲੋ",
@@ -88,10 +92,12 @@
 	"Chunk Params": "ਚੰਕ ਪੈਰਾਮੀਟਰ",
 	"Chunk Size": "ਚੰਕ ਆਕਾਰ",
 	"Citation": "ਹਵਾਲਾ",
+	"Clear memory": "",
 	"Click here for help.": "ਮਦਦ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।",
 	"Click here to": "ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ",
 	"Click here to select": "ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ",
 	"Click here to select a csv file.": "CSV ਫਾਈਲ ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "ਡਾਕੂਮੈਂਟ ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।",
 	"click here.": "ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।",
 	"Click on the user role button to change a user's role.": "ਉਪਭੋਗਤਾ ਦੀ ਭੂਮਿਕਾ ਬਦਲਣ ਲਈ ਉਪਭੋਗਤਾ ਭੂਮਿਕਾ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰੋ।",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "ਸਮਕਾਲੀ ਬੇਨਤੀਆਂ",
 	"Confirm Password": "ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ",
 	"Connections": "ਕਨੈਕਸ਼ਨ",
+	"Contact Admin for WebUI Access": "",
 	"Content": "ਸਮੱਗਰੀ",
 	"Context Length": "ਸੰਦਰਭ ਲੰਬਾਈ",
 	"Continue Response": "ਜਵਾਬ ਜਾਰੀ ਰੱਖੋ",
-	"Conversation Mode": "ਗੱਲਬਾਤ ਮੋਡ",
 	"Copied shared chat URL to clipboard!": "ਸਾਂਝੇ ਕੀਤੇ ਗੱਲਬਾਤ URL ਨੂੰ ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰ ਦਿੱਤਾ!",
 	"Copy": "ਕਾਪੀ ਕਰੋ",
 	"Copy last code block": "ਆਖਰੀ ਕੋਡ ਬਲਾਕ ਨੂੰ ਕਾਪੀ ਕਰੋ",
 	"Copy last response": "ਆਖਰੀ ਜਵਾਬ ਨੂੰ ਕਾਪੀ ਕਰੋ",
 	"Copy Link": "ਲਿੰਕ ਕਾਪੀ ਕਰੋ",
 	"Copying to clipboard was successful!": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰਨਾ ਸਫਲ ਰਿਹਾ!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "ਹੇਠਾਂ ਦਿੱਤੀ ਪੁੱਛਗਿੱਛ ਲਈ ਇੱਕ ਛੋਟਾ, 3-5 ਸ਼ਬਦਾਂ ਦਾ ਵਾਕ ਬਣਾਓ, 3-5 ਸ਼ਬਦਾਂ ਦੀ ਸੀਮਾ ਦਾ ਪਾਲਣ ਕਰਦੇ ਹੋਏ ਅਤੇ 'ਸਿਰਲੇਖ' ਸ਼ਬਦ ਦੇ ਇਸਤੇਮਾਲ ਤੋਂ ਬਚਦੇ ਹੋਏ:",
 	"Create a model": "ਇੱਕ ਮਾਡਲ ਬਣਾਓ",
 	"Create Account": "ਖਾਤਾ ਬਣਾਓ",
 	"Create new key": "ਨਵੀਂ ਕੁੰਜੀ ਬਣਾਓ",
@@ -127,12 +132,12 @@
 	"Custom": "ਕਸਟਮ",
 	"Customize models for a specific purpose": "ਕਿਸੇ ਖਾਸ ਉਦੇਸ਼ ਲਈ ਮਾਡਲਾਂ ਨੂੰ ਅਨੁਕੂਲਿਤ ਕਰੋ",
 	"Dark": "ਗੂੜ੍ਹਾ",
+	"Dashboard": "",
 	"Database": "ਡਾਟਾਬੇਸ",
 	"December": "ਦਸੰਬਰ",
 	"Default": "ਮੂਲ",
 	"Default (Automatic1111)": "ਮੂਲ (Automatic1111)",
 	"Default (SentenceTransformers)": "ਮੂਲ (ਸੈਂਟੈਂਸਟ੍ਰਾਂਸਫਾਰਮਰਸ)",
-	"Default (Web API)": "ਮੂਲ (ਵੈਬ API)",
 	"Default Model": "ਡਿਫਾਲਟ ਮਾਡਲ",
 	"Default model updated": "ਮੂਲ ਮਾਡਲ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ",
 	"Default Prompt Suggestions": "ਮੂਲ ਪ੍ਰੰਪਟ ਸੁਝਾਅ",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "ਇੱਕ ਪ੍ਰੰਪਟ ਖੋਜੋ",
 	"Discover, download, and explore custom prompts": "ਕਸਟਮ ਪ੍ਰੰਪਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
 	"Discover, download, and explore model presets": "ਮਾਡਲ ਪ੍ਰੀਸੈਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "ਗੱਲਬਾਤ 'ਚ ਤੁਹਾਡੇ ਸਥਾਨ 'ਤੇ ਉਪਭੋਗਤਾ ਨਾਮ ਦਿਖਾਓ",
 	"Document": "ਡਾਕੂਮੈਂਟ",
 	"Document Settings": "ਡਾਕੂਮੈਂਟ ਸੈਟਿੰਗਾਂ",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "ਡਾਕੂਮੈਂਟ ਮੈਪਿੰਗ ਨਿਰਯਾਤ ਕਰੋ",
 	"Export Models": "ਨਿਰਯਾਤ ਮਾਡਲ",
 	"Export Prompts": "ਪ੍ਰੰਪਟ ਨਿਰਯਾਤ ਕਰੋ",
+	"External Models": "",
 	"Failed to create API Key.": "API ਕੁੰਜੀ ਬਣਾਉਣ ਵਿੱਚ ਅਸਫਲ।",
 	"Failed to read clipboard contents": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਪੜ੍ਹਣ ਵਿੱਚ ਅਸਫਲ",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "ਬਾਰੰਬਾਰਤਾ ਜੁਰਮਾਨਾ",
 	"General": "ਆਮ",
 	"General Settings": "ਆਮ ਸੈਟਿੰਗਾਂ",
+	"Generate Image": "",
 	"Generating search query": "ਖੋਜ ਪੁੱਛਗਿੱਛ ਤਿਆਰ ਕਰਨਾ",
 	"Generation Info": "ਜਨਰੇਸ਼ਨ ਜਾਣਕਾਰੀ",
 	"Good Response": "ਵਧੀਆ ਜਵਾਬ",
@@ -252,6 +260,7 @@
 	"Info": "ਜਾਣਕਾਰੀ",
 	"Input commands": "ਇਨਪੁਟ ਕਮਾਂਡਾਂ",
 	"Install from Github URL": "Github URL ਤੋਂ ਇੰਸਟਾਲ ਕਰੋ",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "ਇੰਟਰਫੇਸ",
 	"Invalid Tag": "ਗਲਤ ਟੈਗ",
 	"January": "ਜਨਵਰੀ",
@@ -264,14 +273,17 @@
 	"JWT Token": "JWT ਟੋਕਨ",
 	"Keep Alive": "ਜੀਵਿਤ ਰੱਖੋ",
 	"Keyboard shortcuts": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕਟ",
+	"Knowledge": "",
 	"Language": "ਭਾਸ਼ਾ",
 	"Last Active": "ਆਖਰੀ ਸਰਗਰਮ",
 	"Light": "ਹਲਕਾ",
-	"Listening...": "ਸੁਣ ਰਿਹਾ ਹੈ...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs ਗਲਤੀਆਂ ਕਰ ਸਕਦੇ ਹਨ। ਮਹੱਤਵਪੂਰਨ ਜਾਣਕਾਰੀ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਦੁਆਰਾ ਬਣਾਇਆ ਗਿਆ",
 	"Make sure to enclose them with": "ਸੁਨਿਸ਼ਚਿਤ ਕਰੋ ਕਿ ਉਨ੍ਹਾਂ ਨੂੰ ਘੇਰੋ",
+	"Manage": "",
 	"Manage Models": "ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Ollama Models": "ਓਲਾਮਾ ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Pipelines": "ਪਾਈਪਲਾਈਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
@@ -307,6 +319,7 @@
 	"Name your model": "ਆਪਣੇ ਮਾਡਲ ਦਾ ਨਾਮ ਦੱਸੋ",
 	"New Chat": "ਨਵੀਂ ਗੱਲਬਾਤ",
 	"New Password": "ਨਵਾਂ ਪਾਸਵਰਡ",
+	"No documents found": "",
 	"No results found": "ਕੋਈ ਨਤੀਜੇ ਨਹੀਂ ਮਿਲੇ",
 	"No search query generated": "ਕੋਈ ਖੋਜ ਪੁੱਛਗਿੱਛ ਤਿਆਰ ਨਹੀਂ ਕੀਤੀ ਗਈ",
 	"No source available": "ਕੋਈ ਸਰੋਤ ਉਪਲਬਧ ਨਹੀਂ",
@@ -323,6 +336,7 @@
 	"Ollama": "ਓਲਾਮਾ",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API ਅਸਮਰੱਥ",
+	"Ollama API is disabled": "",
 	"Ollama Version": "ਓਲਾਮਾ ਵਰਜਨ",
 	"On": "ਚਾਲੂ",
 	"Only": "ਸਿਰਫ਼",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF ਡਾਕੂਮੈਂਟ (.pdf)",
 	"PDF Extract Images (OCR)": "PDF ਚਿੱਤਰ ਕੱਢੋ (OCR)",
 	"pending": "ਬਕਾਇਆ",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚਣ ਸਮੇਂ ਆਗਿਆ ਰੱਦ ਕੀਤੀ ਗਈ: {{error}}",
 	"Personalization": "ਪਰਸੋਨਲਿਸ਼ਮ",
 	"Pipelines": "ਪਾਈਪਲਾਈਨਾਂ",
@@ -367,6 +383,7 @@
 	"Read Aloud": "ਜੋਰ ਨਾਲ ਪੜ੍ਹੋ",
 	"Record voice": "ਆਵਾਜ਼ ਰਿਕਾਰਡ ਕਰੋ",
 	"Redirecting you to OpenWebUI Community": "ਤੁਹਾਨੂੰ ਓਪਨਵੈਬਯੂਆਈ ਕਮਿਊਨਿਟੀ ਵੱਲ ਰੀਡਾਇਰੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "ਜਦੋਂ ਇਹ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਸੀ ਤਾਂ ਇਨਕਾਰ ਕੀਤਾ",
 	"Regenerate": "ਮੁੜ ਬਣਾਓ",
 	"Release Notes": "ਰਿਲੀਜ਼ ਨੋਟਸ",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "ਰੋਜ਼ ਪਾਈਨ",
 	"Rosé Pine Dawn": "ਰੋਜ਼ ਪਾਈਨ ਡਾਨ",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "ਸੰਭਾਲੋ",
 	"Save & Create": "ਸੰਭਾਲੋ ਅਤੇ ਬਣਾਓ",
 	"Save & Update": "ਸੰਭਾਲੋ ਅਤੇ ਅੱਪਡੇਟ ਕਰੋ",
@@ -398,6 +416,8 @@
 	"Search Documents": "ਡਾਕੂਮੈਂਟ ਖੋਜੋ",
 	"Search Models": "ਖੋਜ ਮਾਡਲ",
 	"Search Prompts": "ਪ੍ਰੰਪਟ ਖੋਜੋ",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "ਖੋਜ ਨਤੀਜੇ ਦੀ ਗਿਣਤੀ",
 	"Searched {{count}} sites_one": "ਖੋਜਿਆ {{count}} sites_one",
 	"Searched {{count}} sites_other": "ਖੋਜਿਆ {{count}} sites_other",
@@ -407,12 +427,14 @@
 	"See what's new": "ਨਵਾਂ ਕੀ ਹੈ ਵੇਖੋ",
 	"Seed": "ਬੀਜ",
 	"Select a base model": "ਆਧਾਰ ਮਾਡਲ ਚੁਣੋ",
+	"Select a engine": "",
 	"Select a mode": "ਇੱਕ ਮੋਡ ਚੁਣੋ",
 	"Select a model": "ਇੱਕ ਮਾਡਲ ਚੁਣੋ",
 	"Select a pipeline": "ਪਾਈਪਲਾਈਨ ਚੁਣੋ",
 	"Select a pipeline url": "ਪਾਈਪਲਾਈਨ URL ਚੁਣੋ",
 	"Select an Ollama instance": "ਇੱਕ ਓਲਾਮਾ ਇੰਸਟੈਂਸ ਚੁਣੋ",
 	"Select model": "ਮਾਡਲ ਚੁਣੋ",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "ਚੁਣੇ ਗਏ ਮਾਡਲ(ਆਂ) ਚਿੱਤਰ ਇਨਪੁੱਟਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੇ",
 	"Send": "ਭੇਜੋ",
 	"Send a Message": "ਇੱਕ ਸੁਨੇਹਾ ਭੇਜੋ",
@@ -425,7 +447,6 @@
 	"Set Default Model": "ਮੂਲ ਮਾਡਲ ਸੈੱਟ ਕਰੋ",
 	"Set embedding model (e.g. {{model}})": "ਐਮਬੈੱਡਿੰਗ ਮਾਡਲ ਸੈੱਟ ਕਰੋ (ਉਦਾਹਰਣ ਲਈ {{model}})",
 	"Set Image Size": "ਚਿੱਤਰ ਆਕਾਰ ਸੈੱਟ ਕਰੋ",
-	"Set Model": "ਮਾਡਲ ਸੈੱਟ ਕਰੋ",
 	"Set reranking model (e.g. {{model}})": "ਮੁੜ ਰੈਂਕਿੰਗ ਮਾਡਲ ਸੈੱਟ ਕਰੋ (ਉਦਾਹਰਣ ਲਈ {{model}})",
 	"Set Steps": "ਕਦਮ ਸੈੱਟ ਕਰੋ",
 	"Set Task Model": "ਟਾਸਕ ਮਾਡਲ ਸੈੱਟ ਕਰੋ",
@@ -449,8 +470,8 @@
 	"Source": "ਸਰੋਤ",
 	"Speech recognition error: {{error}}": "ਬੋਲ ਪਛਾਣ ਗਲਤੀ: {{error}}",
 	"Speech-to-Text Engine": "ਬੋਲ-ਤੋਂ-ਪਾਠ ਇੰਜਣ",
-	"SpeechRecognition API is not supported in this browser.": "ਇਸ ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ SpeechRecognition API ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।",
 	"Stop Sequence": "ਰੋਕੋ ਕ੍ਰਮ",
+	"STT Model": "",
 	"STT Settings": "STT ਸੈਟਿੰਗਾਂ",
 	"Submit": "ਜਮ੍ਹਾਂ ਕਰੋ",
 	"Subtitle (e.g. about the Roman Empire)": "ਉਪਸਿਰਲੇਖ (ਉਦਾਹਰਣ ਲਈ ਰੋਮਨ ਸਾਮਰਾਜ ਬਾਰੇ)",
@@ -469,7 +490,9 @@
 	"Thanks for your feedback!": "ਤੁਹਾਡੇ ਫੀਡਬੈਕ ਲਈ ਧੰਨਵਾਦ!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "ਸਕੋਰ 0.0 (0%) ਅਤੇ 1.0 (100%) ਦੇ ਵਿਚਕਾਰ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।",
 	"Theme": "ਥੀਮ",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "ਇਹ ਯਕੀਨੀ ਬਣਾਉਂਦਾ ਹੈ ਕਿ ਤੁਹਾਡੀਆਂ ਕੀਮਤੀ ਗੱਲਾਂ ਤੁਹਾਡੇ ਬੈਕਐਂਡ ਡਾਟਾਬੇਸ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਤੌਰ 'ਤੇ ਸੰਭਾਲੀਆਂ ਗਈਆਂ ਹਨ। ਧੰਨਵਾਦ!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "ਇਹ ਸੈਟਿੰਗ ਬ੍ਰਾਊਜ਼ਰ ਜਾਂ ਡਿਵਾਈਸਾਂ ਵਿੱਚ ਸਿੰਕ ਨਹੀਂ ਹੁੰਦੀ।",
 	"Thorough explanation": "ਵਿਸਥਾਰ ਨਾਲ ਵਿਆਖਿਆ",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "ਸਲਾਹ: ਹਰ ਬਦਲਾਅ ਦੇ ਬਾਅਦ ਗੱਲਬਾਤ ਇਨਪੁਟ ਵਿੱਚ ਟੈਬ ਕੀ ਦਬਾ ਕੇ ਲਗਾਤਾਰ ਕਈ ਵੈਰੀਏਬਲ ਸਲਾਟਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰੋ।",
@@ -481,6 +504,7 @@
 	"to": "ਨੂੰ",
 	"To access the available model names for downloading,": "ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਉਪਲਬਧ ਮਾਡਲ ਨਾਮਾਂ ਤੱਕ ਪਹੁੰਚਣ ਲਈ,",
 	"To access the GGUF models available for downloading,": "ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਉਪਲਬਧ GGUF ਮਾਡਲਾਂ ਤੱਕ ਪਹੁੰਚਣ ਲਈ,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "ਗੱਲਬਾਤ ਇਨਪੁਟ ਲਈ।",
 	"Today": "ਅੱਜ",
 	"Toggle settings": "ਸੈਟਿੰਗਾਂ ਟੌਗਲ ਕਰੋ",
@@ -488,7 +512,9 @@
 	"Top K": "ਸਿਖਰ K",
 	"Top P": "ਸਿਖਰ P",
 	"Trouble accessing Ollama?": "ਓਲਾਮਾ ਤੱਕ ਪਹੁੰਚਣ ਵਿੱਚ ਮੁਸ਼ਕਲ?",
+	"TTS Model": "",
 	"TTS Settings": "TTS ਸੈਟਿੰਗਾਂ",
+	"TTS Voice": "",
 	"Type": "ਕਿਸਮ",
 	"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ਡਾਊਨਲੋਡ) URL ਟਾਈਪ ਕਰੋ",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "ਓਹੋ! {{provider}} ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ।",
@@ -497,6 +523,7 @@
 	"Update password": "ਪਾਸਵਰਡ ਅੱਪਡੇਟ ਕਰੋ",
 	"Upload a GGUF model": "ਇੱਕ GGUF ਮਾਡਲ ਅਪਲੋਡ ਕਰੋ",
 	"Upload Files": "ਫਾਇਲਾਂ ਅੱਪਲੋਡ ਕਰੋ",
+	"Upload Pipeline": "",
 	"Upload Progress": "ਅਪਲੋਡ ਪ੍ਰਗਤੀ",
 	"URL Mode": "URL ਮੋਡ",
 	"Use '#' in the prompt input to load and select your documents.": "ਆਪਣੇ ਡਾਕੂਮੈਂਟ ਲੋਡ ਅਤੇ ਚੁਣਨ ਲਈ ਪ੍ਰੰਪਟ ਇਨਪੁਟ ਵਿੱਚ '#' ਵਰਤੋ।",
@@ -515,6 +542,7 @@
 	"Warning": "ਚੇਤਾਵਨੀ",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "ਚੇਤਾਵਨੀ: ਜੇ ਤੁਸੀਂ ਆਪਣਾ ਐਮਬੈੱਡਿੰਗ ਮਾਡਲ ਅੱਪਡੇਟ ਜਾਂ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਸਾਰੇ ਡਾਕੂਮੈਂਟ ਮੁੜ ਆਯਾਤ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ।",
 	"Web": "ਵੈਬ",
+	"Web API": "",
 	"Web Loader Settings": "ਵੈਬ ਲੋਡਰ ਸੈਟਿੰਗਾਂ",
 	"Web Params": "ਵੈਬ ਪੈਰਾਮੀਟਰ",
 	"Web Search": "ਵੈੱਬ ਖੋਜ",
@@ -525,18 +553,20 @@
 	"WebUI will make requests to": "ਵੈਬਯੂਆਈ ਬੇਨਤੀਆਂ ਕਰੇਗਾ",
 	"What’s New in": "ਨਵਾਂ ਕੀ ਹੈ",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "ਜਦੋਂ ਇਤਿਹਾਸ ਬੰਦ ਹੁੰਦਾ ਹੈ, ਤਾਂ ਇਸ ਬ੍ਰਾਊਜ਼ਰ 'ਤੇ ਨਵੀਆਂ ਗੱਲਾਂ ਤੁਹਾਡੇ ਕਿਸੇ ਵੀ ਜੰਤਰ 'ਤੇ ਤੁਹਾਡੇ ਇਤਿਹਾਸ ਵਿੱਚ ਨਹੀਂ ਆਉਣਗੀਆਂ।",
-	"Whisper (Local)": "ਵਿਸਪਰ (ਸਥਾਨਕ)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "ਕਾਰਜਸਥਲ",
 	"Write a prompt suggestion (e.g. Who are you?)": "ਇੱਕ ਪ੍ਰੰਪਟ ਸੁਝਾਅ ਲਿਖੋ (ਉਦਾਹਰਣ ਲਈ ਤੁਸੀਂ ਕੌਣ ਹੋ?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "50 ਸ਼ਬਦਾਂ ਵਿੱਚ ਇੱਕ ਸੰਖੇਪ ਲਿਖੋ ਜੋ [ਵਿਸ਼ਾ ਜਾਂ ਕੁੰਜੀ ਸ਼ਬਦ] ਨੂੰ ਸੰਖੇਪ ਕਰਦਾ ਹੈ।",
 	"Yesterday": "ਕੱਲ੍ਹ",
 	"You": "ਤੁਸੀਂ",
+	"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 clone a base model": "ਤੁਸੀਂ ਆਧਾਰ ਮਾਡਲ ਨੂੰ ਕਲੋਨ ਨਹੀਂ ਕਰ ਸਕਦੇ",
 	"You have no archived conversations.": "ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਆਰਕਾਈਵ ਕੀਤੀਆਂ ਗੱਲਾਂ ਨਹੀਂ ਹਨ।",
 	"You have shared this chat": "ਤੁਸੀਂ ਇਹ ਗੱਲਬਾਤ ਸਾਂਝੀ ਕੀਤੀ ਹੈ",
 	"You're a helpful assistant.": "ਤੁਸੀਂ ਇੱਕ ਮਦਦਗਾਰ ਸਹਾਇਕ ਹੋ।",
 	"You're now logged in.": "ਤੁਸੀਂ ਹੁਣ ਲੌਗ ਇਨ ਹੋ ਗਏ ਹੋ।",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "ਯੂਟਿਊਬ",
 	"Youtube Loader Settings": "ਯੂਟਿਊਬ ਲੋਡਰ ਸੈਟਿੰਗਾਂ"
 }

+ 38 - 8
src/lib/i18n/locales/pl-PL/translation.json

@@ -12,6 +12,7 @@
 	"a user": "użytkownik",
 	"About": "O nas",
 	"Account": "Konto",
+	"Account Activation Pending": "",
 	"Accurate information": "Dokładna informacja",
 	"Active Users": "",
 	"Add": "Dodaj",
@@ -29,6 +30,7 @@
 	"Add User": "Dodaj użytkownika",
 	"Adjusting these settings will apply changes universally to all users.": "Dostosowanie tych ustawień spowoduje zastosowanie zmian uniwersalnie do wszystkich użytkowników.",
 	"admin": "admin",
+	"Admin": "",
 	"Admin Panel": "Panel administracyjny",
 	"Admin Settings": "Ustawienia administratora",
 	"Advanced Parameters": "Zaawansowane parametry",
@@ -59,7 +61,6 @@
 	"Audio": "Dźwięk",
 	"August": "Sierpień",
 	"Auto-playback response": "Odtwarzanie automatyczne odpowiedzi",
-	"Auto-send input after 3 sec.": "Wysyłanie automatyczne po 3 sek.",
 	"AUTOMATIC1111 Base URL": "Podstawowy adres URL AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "Podstawowy adres URL AUTOMATIC1111 jest wymagany.",
 	"available!": "dostępny!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Jest leniwy",
 	"Brave Search API Key": "Klucz API wyszukiwania Brave",
 	"Bypass SSL verification for Websites": "Pomiń weryfikację SSL dla stron webowych",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Anuluj",
 	"Capabilities": "Możliwości",
 	"Change Password": "Zmień hasło",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parametry bloku",
 	"Chunk Size": "Rozmiar bloku",
 	"Citation": "Cytat",
+	"Clear memory": "",
 	"Click here for help.": "Kliknij tutaj, aby uzyskać pomoc.",
 	"Click here to": "Kliknij tutaj, żeby",
 	"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.": "",
 	"Click here to select documents.": "Kliknij tutaj, aby wybrać dokumenty.",
 	"click here.": "kliknij tutaj.",
 	"Click on the user role button to change a user's role.": "Kliknij przycisk roli użytkownika, aby zmienić rolę użytkownika.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Równoczesne żądania",
 	"Confirm Password": "Potwierdź hasło",
 	"Connections": "Połączenia",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Zawartość",
 	"Context Length": "Długość kontekstu",
 	"Continue Response": "Kontynuuj odpowiedź",
-	"Conversation Mode": "Tryb rozmowy",
 	"Copied shared chat URL to clipboard!": "Skopiowano URL czatu do schowka!",
 	"Copy": "Kopiuj",
 	"Copy last code block": "Skopiuj ostatni blok kodu",
 	"Copy last response": "Skopiuj ostatnią odpowiedź",
 	"Copy Link": "Kopiuj link",
 	"Copying to clipboard was successful!": "Kopiowanie do schowka zakończone powodzeniem!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Utwórz zwięzłą frazę składającą się z 3-5 słów jako nagłówek dla następującego zapytania, ściśle przestrzegając limitu od 3 do 5 słów i unikając użycia słowa 'tytuł':",
 	"Create a model": "Tworzenie modelu",
 	"Create Account": "Utwórz konto",
 	"Create new key": "Utwórz nowy klucz",
@@ -127,12 +132,12 @@
 	"Custom": "Niestandardowy",
 	"Customize models for a specific purpose": "Dostosowywanie modeli do określonego celu",
 	"Dark": "Ciemny",
+	"Dashboard": "",
 	"Database": "Baza danych",
 	"December": "Grudzień",
 	"Default": "Domyślny",
 	"Default (Automatic1111)": "Domyślny (Automatic1111)",
 	"Default (SentenceTransformers)": "Domyślny (SentenceTransformers)",
-	"Default (Web API)": "Domyślny (Web API)",
 	"Default Model": "Model domyślny",
 	"Default model updated": "Domyślny model zaktualizowany",
 	"Default Prompt Suggestions": "Domyślne sugestie promptów",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Odkryj prompt",
 	"Discover, download, and explore custom prompts": "Odkryj, pobierz i eksploruj niestandardowe prompty",
 	"Discover, download, and explore model presets": "Odkryj, pobierz i eksploruj ustawienia modeli",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Wyświetl nazwę użytkownika zamiast Ty w czacie",
 	"Document": "Dokument",
 	"Document Settings": "Ustawienia dokumentu",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Eksportuj mapowanie dokumentów",
 	"Export Models": "Eksportuj modele",
 	"Export Prompts": "Eksportuj prompty",
+	"External Models": "",
 	"Failed to create API Key.": "Nie udało się utworzyć klucza API.",
 	"Failed to read clipboard contents": "Nie udało się odczytać zawartości schowka",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Kara za częstotliwość",
 	"General": "Ogólne",
 	"General Settings": "Ogólne ustawienia",
+	"Generate Image": "",
 	"Generating search query": "Generowanie zapytania",
 	"Generation Info": "Informacja o generacji",
 	"Good Response": "Dobra odpowiedź",
@@ -252,6 +260,7 @@
 	"Info": "Informacji",
 	"Input commands": "Wprowadź komendy",
 	"Install from Github URL": "Instalowanie z adresu URL usługi Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interfejs",
 	"Invalid Tag": "Nieprawidłowy tag",
 	"January": "Styczeń",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Zachowaj łączność",
 	"Keyboard shortcuts": "Skróty klawiszowe",
+	"Knowledge": "",
 	"Language": "Język",
 	"Last Active": "Ostatnio aktywny",
 	"Light": "Jasny",
-	"Listening...": "Nasłuchiwanie...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMy mogą popełniać błędy. Zweryfikuj ważne informacje.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Stworzone przez społeczność OpenWebUI",
 	"Make sure to enclose them with": "Upewnij się, że są one zamknięte w",
+	"Manage": "",
 	"Manage Models": "Zarządzaj modelami",
 	"Manage Ollama Models": "Zarządzaj modelami Ollama",
 	"Manage Pipelines": "Zarządzanie potokami",
@@ -307,6 +319,7 @@
 	"Name your model": "Nazwij swój model",
 	"New Chat": "Nowy czat",
 	"New Password": "Nowe hasło",
+	"No documents found": "",
 	"No results found": "Nie znaleziono rezultatów",
 	"No search query generated": "Nie wygenerowano zapytania wyszukiwania",
 	"No source available": "Źródło nie dostępne",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Interfejs API Ollama wyłączony",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Wersja Ollama",
 	"On": "Włączony",
 	"Only": "Tylko",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Dokument PDF (.pdf)",
 	"PDF Extract Images (OCR)": "PDF Wyodrębnij obrazy (OCR)",
 	"pending": "oczekujące",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Odmowa dostępu do mikrofonu: {{error}}",
 	"Personalization": "Personalizacja",
 	"Pipelines": "Rurociągów",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Czytaj na głos",
 	"Record voice": "Nagraj głos",
 	"Redirecting you to OpenWebUI Community": "Przekierowujemy Cię do społeczności OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Odmówił, kiedy nie powinien",
 	"Regenerate": "Generuj ponownie",
 	"Release Notes": "Notatki wydania",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RLT",
+	"Running": "",
 	"Save": "Zapisz",
 	"Save & Create": "Zapisz i utwórz",
 	"Save & Update": "Zapisz i zaktualizuj",
@@ -398,6 +416,8 @@
 	"Search Documents": "Szukaj dokumentów",
 	"Search Models": "Szukaj modeli",
 	"Search Prompts": "Szukaj promptów",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Liczba wyników wyszukiwania",
 	"Searched {{count}} sites_one": "Wyszukiwano {{count}} sites_one",
 	"Searched {{count}} sites_few": "Wyszukiwano {{count}} sites_few",
@@ -409,12 +429,14 @@
 	"See what's new": "Zobacz co nowego",
 	"Seed": "Seed",
 	"Select a base model": "Wybieranie modelu bazowego",
+	"Select a engine": "",
 	"Select a mode": "Wybierz tryb",
 	"Select a model": "Wybierz model",
 	"Select a pipeline": "Wybieranie potoku",
 	"Select a pipeline url": "Wybieranie adresu URL potoku",
 	"Select an Ollama instance": "Wybierz instancję Ollama",
 	"Select model": "Wybierz model",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Wybrane modele nie obsługują danych wejściowych obrazu",
 	"Send": "Wyślij",
 	"Send a Message": "Wyślij Wiadomość",
@@ -427,7 +449,6 @@
 	"Set Default Model": "Ustaw domyślny model",
 	"Set embedding model (e.g. {{model}})": "Ustaw model osadzania (e.g. {{model}})",
 	"Set Image Size": "Ustaw rozmiar obrazu",
-	"Set Model": "Ustaw model",
 	"Set reranking model (e.g. {{model}})": "Ustaw zmianę rankingu modelu (e.g. {{model}})",
 	"Set Steps": "Ustaw kroki",
 	"Set Task Model": "Ustawianie modelu zadań",
@@ -451,8 +472,8 @@
 	"Source": "Źródło",
 	"Speech recognition error: {{error}}": "Błąd rozpoznawania mowy: {{error}}",
 	"Speech-to-Text Engine": "Silnik mowy na tekst",
-	"SpeechRecognition API is not supported in this browser.": "API Rozpoznawania Mowy nie jest obsługiwane w tej przeglądarce.",
 	"Stop Sequence": "Zatrzymaj sekwencję",
+	"STT Model": "",
 	"STT Settings": "Ustawienia STT",
 	"Submit": "Zatwierdź",
 	"Subtitle (e.g. about the Roman Empire)": "Podtytuł (np. o Imperium Rzymskim)",
@@ -471,7 +492,9 @@
 	"Thanks for your feedback!": "Dzięki za informację zwrotną!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Wynik powinien być wartością pomiędzy 0.0 (0%) a 1.0 (100%).",
 	"Theme": "Motyw",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "To zapewnia, że Twoje cenne rozmowy są bezpiecznie zapisywane w bazie danych backendowej. Dziękujemy!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "To ustawienie nie synchronizuje się między przeglądarkami ani urządzeniami.",
 	"Thorough explanation": "Dokładne wyjaśnienie",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Porada: Aktualizuj wiele zmiennych kolejno, naciskając klawisz tabulatora w polu wprowadzania czatu po każdej zmianie.",
@@ -483,6 +506,7 @@
 	"to": "do",
 	"To access the available model names for downloading,": "Aby uzyskać dostęp do dostępnych nazw modeli do pobrania,",
 	"To access the GGUF models available for downloading,": "Aby uzyskać dostęp do dostępnych modeli GGUF do pobrania,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "do pola wprowadzania czatu.",
 	"Today": "Dzisiaj",
 	"Toggle settings": "Przełącz ustawienia",
@@ -490,7 +514,9 @@
 	"Top K": "Najlepsze K",
 	"Top P": "Najlepsze P",
 	"Trouble accessing Ollama?": "Problemy z dostępem do Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Ustawienia TTS",
+	"TTS Voice": "",
 	"Type": "Typ",
 	"Type Hugging Face Resolve (Download) URL": "Wprowadź adres URL do pobrania z Hugging Face",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "O nie! Wystąpił problem z połączeniem z {{provider}}.",
@@ -499,6 +525,7 @@
 	"Update password": "Aktualizacja hasła",
 	"Upload a GGUF model": "Prześlij model GGUF",
 	"Upload Files": "Prześlij pliki",
+	"Upload Pipeline": "",
 	"Upload Progress": "Postęp przesyłania",
 	"URL Mode": "Tryb adresu URL",
 	"Use '#' in the prompt input to load and select your documents.": "Użyj '#' w polu wprowadzania polecenia, aby załadować i wybrać swoje dokumenty.",
@@ -517,6 +544,7 @@
 	"Warning": "Ostrzeżenie",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Uwaga: Jeśli uaktualnisz lub zmienisz model osadzania, będziesz musiał ponownie zaimportować wszystkie dokumenty.",
 	"Web": "Sieć",
+	"Web API": "",
 	"Web Loader Settings": "Ustawienia pobierania z sieci",
 	"Web Params": "Parametry sieci",
 	"Web Search": "Wyszukiwarka w Internecie",
@@ -527,18 +555,20 @@
 	"WebUI will make requests to": "Interfejs sieciowy będzie wysyłał żądania do",
 	"What’s New in": "Co nowego w",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Kiedy historia jest wyłączona, nowe czaty na tej przeglądarce nie będą widoczne w historii na żadnym z twoich urządzeń.",
-	"Whisper (Local)": "Whisper (Lokalnie)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Obszar roboczy",
 	"Write a prompt suggestion (e.g. Who are you?)": "Napisz sugestię do polecenia (np. Kim jesteś?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Napisz podsumowanie w 50 słowach, które podsumowuje [temat lub słowo kluczowe].",
 	"Yesterday": "Wczoraj",
 	"You": "Ty",
+	"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 clone a base model": "Nie można sklonować modelu podstawowego",
 	"You have no archived conversations.": "Nie masz zarchiwizowanych rozmów.",
 	"You have shared this chat": "Udostępniłeś ten czat",
 	"You're a helpful assistant.": "Jesteś pomocnym asystentem.",
 	"You're now logged in.": "Jesteś teraz zalogowany.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Ustawienia pobierania z Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/pt-BR/translation.json

@@ -12,6 +12,7 @@
 	"a user": "um usuário",
 	"About": "Sobre",
 	"Account": "Conta",
+	"Account Activation Pending": "",
 	"Accurate information": "Informações precisas",
 	"Active Users": "",
 	"Add": "Adicionar",
@@ -29,6 +30,7 @@
 	"Add User": "Adicionar Usuário",
 	"Adjusting these settings will apply changes universally to all users.": "Ajustar essas configurações aplicará alterações universalmente a todos os usuários.",
 	"admin": "administrador",
+	"Admin": "",
 	"Admin Panel": "Painel do Administrador",
 	"Admin Settings": "Configurações do Administrador",
 	"Advanced Parameters": "Parâmetros Avançados",
@@ -59,7 +61,6 @@
 	"Audio": "Áudio",
 	"August": "Agosto",
 	"Auto-playback response": "Reprodução automática da resposta",
-	"Auto-send input after 3 sec.": "Enviar entrada automaticamente após 3 segundos.",
 	"AUTOMATIC1111 Base URL": "URL Base do AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "A URL Base do AUTOMATIC1111 é obrigatória.",
 	"available!": "disponível!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Ser preguiçoso",
 	"Brave Search API Key": "Chave da API de pesquisa do Brave",
 	"Bypass SSL verification for Websites": "Ignorar verificação SSL para sites",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Cancelar",
 	"Capabilities": "Capacidades",
 	"Change Password": "Alterar Senha",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
 	"Citation": "Citação",
+	"Clear memory": "",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here to": "Clique aqui para",
 	"Click here to select": "Clique aqui para selecionar",
 	"Click here to select a csv file.": "Clique aqui para selecionar um arquivo csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Clique aqui para selecionar documentos.",
 	"click here.": "clique aqui.",
 	"Click on the user role button to change a user's role.": "Clique no botão de função do usuário para alterar a função de um usuário.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Solicitações simultâneas",
 	"Confirm Password": "Confirmar Senha",
 	"Connections": "Conexões",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Conteúdo",
 	"Context Length": "Comprimento do Contexto",
 	"Continue Response": "Continuar resposta",
-	"Conversation Mode": "Modo de Conversa",
 	"Copied shared chat URL to clipboard!": "URL de bate-papo compartilhado copiada com sucesso!",
 	"Copy": "Copiar",
 	"Copy last code block": "Copiar último bloco de código",
 	"Copy last response": "Copiar última resposta",
 	"Copy Link": "Copiar link",
 	"Copying to clipboard was successful!": "Cópia para a área de transferência bem-sucedida!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crie uma frase concisa de 3 a 5 palavras como cabeçalho para a seguinte consulta, aderindo estritamente ao limite de 3 a 5 palavras e evitando o uso da palavra 'título':",
 	"Create a model": "Criar um modelo",
 	"Create Account": "Criar Conta",
 	"Create new key": "Criar nova chave",
@@ -127,12 +132,12 @@
 	"Custom": "Personalizado",
 	"Customize models for a specific purpose": "Personalizar modelos para uma finalidade específica",
 	"Dark": "Escuro",
+	"Dashboard": "",
 	"Database": "Banco de dados",
 	"December": "Dezembro",
 	"Default": "Padrão",
 	"Default (Automatic1111)": "Padrão (Automatic1111)",
 	"Default (SentenceTransformers)": "Padrão (SentenceTransformers)",
-	"Default (Web API)": "Padrão (API Web)",
 	"Default Model": "Modelo padrão",
 	"Default model updated": "Modelo padrão atualizado",
 	"Default Prompt Suggestions": "Sugestões de Prompt Padrão",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Descobrir um prompt",
 	"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
 	"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Exibir o nome de usuário em vez de Você no Bate-papo",
 	"Document": "Documento",
 	"Document Settings": "Configurações de Documento",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exportar Mapeamento de Documentos",
 	"Export Models": "Modelos de Exportação",
 	"Export Prompts": "Exportar Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Falha ao criar a Chave da API.",
 	"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Penalidade de Frequência",
 	"General": "Geral",
 	"General Settings": "Configurações Gerais",
+	"Generate Image": "",
 	"Generating search query": "Gerando consulta de pesquisa",
 	"Generation Info": "Informações de Geração",
 	"Good Response": "Boa Resposta",
@@ -252,6 +260,7 @@
 	"Info": "Informação",
 	"Input commands": "Comandos de entrada",
 	"Install from Github URL": "Instalar a partir do URL do Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "Etiqueta Inválida",
 	"January": "Janeiro",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Manter Vivo",
 	"Keyboard shortcuts": "Atalhos de teclado",
+	"Knowledge": "",
 	"Language": "Idioma",
 	"Last Active": "Último Ativo",
 	"Light": "Claro",
-	"Listening...": "Ouvindo...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
 	"Make sure to enclose them with": "Certifique-se de colocá-los entre",
+	"Manage": "",
 	"Manage Models": "Gerenciar Modelos",
 	"Manage Ollama Models": "Gerenciar Modelos Ollama",
 	"Manage Pipelines": "Gerenciar pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Nomeie seu modelo",
 	"New Chat": "Novo Bate-papo",
 	"New Password": "Nova Senha",
+	"No documents found": "",
 	"No results found": "Nenhum resultado encontrado",
 	"No search query generated": "Nenhuma consulta de pesquisa gerada",
 	"No source available": "Nenhuma fonte disponível",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API Ollama desativada",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Versão do Ollama",
 	"On": "Ligado",
 	"Only": "Somente",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Documento PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
 	"pending": "pendente",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
 	"Personalization": "Personalização",
 	"Pipelines": "Pipelines",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Ler em Voz Alta",
 	"Record voice": "Gravar voz",
 	"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Recusado quando não deveria",
 	"Regenerate": "Regenerar",
 	"Release Notes": "Notas de Lançamento",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Salvar",
 	"Save & Create": "Salvar e Criar",
 	"Save & Update": "Salvar e Atualizar",
@@ -398,6 +416,8 @@
 	"Search Documents": "Pesquisar Documentos",
 	"Search Models": "Modelos de Pesquisa",
 	"Search Prompts": "Pesquisar Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Contagem de resultados de pesquisa",
 	"Searched {{count}} sites_one": "Pesquisado {{count}} sites_one",
 	"Searched {{count}} sites_many": "Pesquisado {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Veja o que há de novo",
 	"Seed": "Semente",
 	"Select a base model": "Selecione um modelo base",
+	"Select a engine": "",
 	"Select a mode": "Selecione um modo",
 	"Select a model": "Selecione um modelo",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline url": "Selecione uma URL de pipeline",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select model": "Selecione um modelo",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "O(s) modelo(s) selecionado(s) não suporta(m) entrada(s) de imagem",
 	"Send": "Enviar",
 	"Send a Message": "Enviar uma Mensagem",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Definir Modelo Padrão",
 	"Set embedding model (e.g. {{model}})": "Definir modelo de vetorização (ex.: {{model}})",
 	"Set Image Size": "Definir Tamanho da Imagem",
-	"Set Model": "Definir Modelo",
 	"Set reranking model (e.g. {{model}})": "Definir modelo de reranking (ex.: {{model}})",
 	"Set Steps": "Definir Etapas",
 	"Set Task Model": "Definir modelo de tarefa",
@@ -450,8 +471,8 @@
 	"Source": "Fonte",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
-	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
 	"Stop Sequence": "Sequência de Parada",
+	"STT Model": "",
 	"STT Settings": "Configurações STT",
 	"Submit": "Enviar",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítulo (ex.: sobre o Império Romano)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Obrigado pelo seu feedback!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "O score deve ser um valor entre 0.0 (0%) e 1.0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isso garante que suas conversas valiosas sejam salvas com segurança em seu banco de dados de backend. Obrigado!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Esta configuração não sincroniza entre navegadores ou dispositivos.",
 	"Thorough explanation": "Explicação Completa",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Dica: Atualize vários slots de variáveis consecutivamente pressionando a tecla Tab na entrada de bate-papo após cada substituição.",
@@ -482,6 +505,7 @@
 	"to": "para",
 	"To access the available model names for downloading,": "Para acessar os nomes de modelo disponíveis para download,",
 	"To access the GGUF models available for downloading,": "Para acessar os modelos GGUF disponíveis para download,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "para a entrada de bate-papo.",
 	"Today": "Hoje",
 	"Toggle settings": "Alternar configurações",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemas para acessar o Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Configurações TTS",
+	"TTS Voice": "",
 	"Type": "Tipo",
 	"Type Hugging Face Resolve (Download) URL": "Digite a URL do Hugging Face Resolve (Download)",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Opa! Houve um problema ao conectar-se a {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Atualizar senha",
 	"Upload a GGUF model": "Carregar um modelo GGUF",
 	"Upload Files": "Carregar arquivos",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progresso do Carregamento",
 	"URL Mode": "Modo de URL",
 	"Use '#' in the prompt input to load and select your documents.": "Use '#' na entrada do prompt para carregar e selecionar seus documentos.",
@@ -516,6 +543,7 @@
 	"Warning": "Aviso",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Aviso: Se você atualizar ou alterar seu modelo de incorporação, você precisará reimportar todos os documentos.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Configurações do Carregador da Web",
 	"Web Params": "Parâmetros da Web",
 	"Web Search": "Pesquisa na Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI fará solicitações para",
 	"What’s New in": "O que há de novo em",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando o histórico está desativado, novos bate-papos neste navegador não aparecerão em seu histórico em nenhum dos seus dispositivos.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Espaço de trabalho",
 	"Write a prompt suggestion (e.g. Who are you?)": "Escreva uma sugestão de prompt (por exemplo, Quem é você?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Escreva um resumo em 50 palavras que resuma [tópico ou palavra-chave].",
 	"Yesterday": "Ontem",
 	"You": "Você",
+	"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 clone a base model": "Não é possível clonar um modelo base",
 	"You have no archived conversations.": "Você não tem conversas arquivadas.",
 	"You have shared this chat": "Você compartilhou esta conversa",
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're now logged in.": "Você está conectado agora.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Configurações do carregador do Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/pt-PT/translation.json

@@ -12,6 +12,7 @@
 	"a user": "um usuário",
 	"About": "Sobre",
 	"Account": "Conta",
+	"Account Activation Pending": "",
 	"Accurate information": "Informações precisas",
 	"Active Users": "",
 	"Add": "Adicionar",
@@ -29,6 +30,7 @@
 	"Add User": "Adicionar Usuário",
 	"Adjusting these settings will apply changes universally to all users.": "Ajustar essas configurações aplicará alterações universalmente a todos os usuários.",
 	"admin": "administrador",
+	"Admin": "",
 	"Admin Panel": "Painel do Administrador",
 	"Admin Settings": "Configurações do Administrador",
 	"Advanced Parameters": "Parâmetros Avançados",
@@ -59,7 +61,6 @@
 	"Audio": "Áudio",
 	"August": "Agosto",
 	"Auto-playback response": "Reprodução automática da resposta",
-	"Auto-send input after 3 sec.": "Enviar entrada automaticamente após 3 segundos.",
 	"AUTOMATIC1111 Base URL": "URL Base do AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "A URL Base do AUTOMATIC1111 é obrigatória.",
 	"available!": "disponível!",
@@ -71,6 +72,9 @@
 	"Being lazy": "Ser preguiçoso",
 	"Brave Search API Key": "Chave da API de Pesquisa Admirável",
 	"Bypass SSL verification for Websites": "Ignorar verificação SSL para sites",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Cancelar",
 	"Capabilities": "Capacidades",
 	"Change Password": "Alterar Senha",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
 	"Citation": "Citação",
+	"Clear memory": "",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here to": "Clique aqui para",
 	"Click here to select": "Clique aqui para selecionar",
 	"Click here to select a csv file.": "Clique aqui para selecionar um arquivo csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Clique aqui para selecionar documentos.",
 	"click here.": "clique aqui.",
 	"Click on the user role button to change a user's role.": "Clique no botão de função do usuário para alterar a função de um usuário.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Solicitações simultâneas",
 	"Confirm Password": "Confirmar Senha",
 	"Connections": "Conexões",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Conteúdo",
 	"Context Length": "Comprimento do Contexto",
 	"Continue Response": "Continuar resposta",
-	"Conversation Mode": "Modo de Conversa",
 	"Copied shared chat URL to clipboard!": "URL de bate-papo compartilhado copiada com sucesso!",
 	"Copy": "Copiar",
 	"Copy last code block": "Copiar último bloco de código",
 	"Copy last response": "Copiar última resposta",
 	"Copy Link": "Copiar link",
 	"Copying to clipboard was successful!": "Cópia para a área de transferência bem-sucedida!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crie uma frase concisa de 3 a 5 palavras como cabeçalho para a seguinte consulta, aderindo estritamente ao limite de 3 a 5 palavras e evitando o uso da palavra 'título':",
 	"Create a model": "Criar um modelo",
 	"Create Account": "Criar Conta",
 	"Create new key": "Criar nova chave",
@@ -127,12 +132,12 @@
 	"Custom": "Personalizado",
 	"Customize models for a specific purpose": "Personalizar modelos para uma finalidade específica",
 	"Dark": "Escuro",
+	"Dashboard": "",
 	"Database": "Banco de dados",
 	"December": "Dezembro",
 	"Default": "Padrão",
 	"Default (Automatic1111)": "Padrão (Automatic1111)",
 	"Default (SentenceTransformers)": "Padrão (SentenceTransformers)",
-	"Default (Web API)": "Padrão (API Web)",
 	"Default Model": "Modelo padrão",
 	"Default model updated": "Modelo padrão atualizado",
 	"Default Prompt Suggestions": "Sugestões de Prompt Padrão",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Descobrir um prompt",
 	"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
 	"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Exibir o nome de usuário em vez de Você no Bate-papo",
 	"Document": "Documento",
 	"Document Settings": "Configurações de Documento",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Exportar Mapeamento de Documentos",
 	"Export Models": "Modelos de Exportação",
 	"Export Prompts": "Exportar Prompts",
+	"External Models": "",
 	"Failed to create API Key.": "Falha ao criar a Chave da API.",
 	"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Penalidade de Frequência",
 	"General": "Geral",
 	"General Settings": "Configurações Gerais",
+	"Generate Image": "",
 	"Generating search query": "Gerar consulta de pesquisa",
 	"Generation Info": "Informações de Geração",
 	"Good Response": "Boa Resposta",
@@ -252,6 +260,7 @@
 	"Info": "Informação",
 	"Input commands": "Comandos de entrada",
 	"Install from Github URL": "Instalar a partir do URL do Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Interface",
 	"Invalid Tag": "Etiqueta Inválida",
 	"January": "Janeiro",
@@ -264,14 +273,17 @@
 	"JWT Token": "Token JWT",
 	"Keep Alive": "Manter Vivo",
 	"Keyboard shortcuts": "Atalhos de teclado",
+	"Knowledge": "",
 	"Language": "Idioma",
 	"Last Active": "Último Ativo",
 	"Light": "Claro",
-	"Listening...": "Ouvindo...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
 	"Make sure to enclose them with": "Certifique-se de colocá-los entre",
+	"Manage": "",
 	"Manage Models": "Gerenciar Modelos",
 	"Manage Ollama Models": "Gerenciar Modelos Ollama",
 	"Manage Pipelines": "Gerenciar pipelines",
@@ -307,6 +319,7 @@
 	"Name your model": "Atribua um nome ao seu modelo",
 	"New Chat": "Novo Bate-papo",
 	"New Password": "Nova Senha",
+	"No documents found": "",
 	"No results found": "Nenhum resultado encontrado",
 	"No search query generated": "Nenhuma consulta de pesquisa gerada",
 	"No source available": "Nenhuma fonte disponível",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "API do Ollama desativada",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Versão do Ollama",
 	"On": "Ligado",
 	"Only": "Somente",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "Documento PDF (.pdf)",
 	"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
 	"pending": "pendente",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
 	"Personalization": "Personalização",
 	"Pipelines": "Condutas",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Ler em Voz Alta",
 	"Record voice": "Gravar voz",
 	"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Recusado quando não deveria",
 	"Regenerate": "Regenerar",
 	"Release Notes": "Notas de Lançamento",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Rosé Pine Dawn",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Salvar",
 	"Save & Create": "Salvar e Criar",
 	"Save & Update": "Salvar e Atualizar",
@@ -398,6 +416,8 @@
 	"Search Documents": "Pesquisar Documentos",
 	"Search Models": "Modelos de pesquisa",
 	"Search Prompts": "Pesquisar Prompts",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Contagem de resultados da pesquisa",
 	"Searched {{count}} sites_one": "Pesquisado {{count}} sites_one",
 	"Searched {{count}} sites_many": "Pesquisado {{count}} sites_many",
@@ -408,12 +428,14 @@
 	"See what's new": "Veja o que há de novo",
 	"Seed": "Semente",
 	"Select a base model": "Selecione um modelo base",
+	"Select a engine": "",
 	"Select a mode": "Selecione um modo",
 	"Select a model": "Selecione um modelo",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline url": "Selecione um URL de pipeline",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select model": "Selecione um modelo",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "O(s) modelo(s) selecionado(s) não suporta(m) entradas de imagem",
 	"Send": "Enviar",
 	"Send a Message": "Enviar uma Mensagem",
@@ -426,7 +448,6 @@
 	"Set Default Model": "Definir Modelo Padrão",
 	"Set embedding model (e.g. {{model}})": "Definir modelo de vetorização (ex.: {{model}})",
 	"Set Image Size": "Definir Tamanho da Imagem",
-	"Set Model": "Definir Modelo",
 	"Set reranking model (e.g. {{model}})": "Definir modelo de reranking (ex.: {{model}})",
 	"Set Steps": "Definir Etapas",
 	"Set Task Model": "Definir modelo de tarefa",
@@ -450,8 +471,8 @@
 	"Source": "Fonte",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
-	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
 	"Stop Sequence": "Sequência de Parada",
+	"STT Model": "",
 	"STT Settings": "Configurações STT",
 	"Submit": "Enviar",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítulo (ex.: sobre o Império Romano)",
@@ -470,7 +491,9 @@
 	"Thanks for your feedback!": "Obrigado pelo feedback!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "O score deve ser um valor entre 0.0 (0%) e 1.0 (100%).",
 	"Theme": "Tema",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isso garante que suas conversas valiosas sejam salvas com segurança em seu banco de dados de backend. Obrigado!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Esta configuração não sincroniza entre navegadores ou dispositivos.",
 	"Thorough explanation": "Explicação Completa",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Dica: Atualize vários slots de variáveis consecutivamente pressionando a tecla Tab na entrada de bate-papo após cada substituição.",
@@ -482,6 +505,7 @@
 	"to": "para",
 	"To access the available model names for downloading,": "Para acessar os nomes de modelo disponíveis para download,",
 	"To access the GGUF models available for downloading,": "Para acessar os modelos GGUF disponíveis para download,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "para a entrada de bate-papo.",
 	"Today": "Hoje",
 	"Toggle settings": "Alternar configurações",
@@ -489,7 +513,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Problemas para acessar o Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Configurações TTS",
+	"TTS Voice": "",
 	"Type": "Tipo",
 	"Type Hugging Face Resolve (Download) URL": "Digite a URL do Hugging Face Resolve (Download)",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Opa! Houve um problema ao conectar-se a {{provider}}.",
@@ -498,6 +524,7 @@
 	"Update password": "Atualizar senha",
 	"Upload a GGUF model": "Carregar um modelo GGUF",
 	"Upload Files": "Carregar ficheiros",
+	"Upload Pipeline": "",
 	"Upload Progress": "Progresso do Carregamento",
 	"URL Mode": "Modo de URL",
 	"Use '#' in the prompt input to load and select your documents.": "Use '#' na entrada do prompt para carregar e selecionar seus documentos.",
@@ -516,6 +543,7 @@
 	"Warning": "Advertência",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Aviso: Se você atualizar ou alterar seu modelo de vetorização, você precisará reimportar todos os documentos.",
 	"Web": "Web",
+	"Web API": "",
 	"Web Loader Settings": "Configurações do Carregador da Web",
 	"Web Params": "Parâmetros da Web",
 	"Web Search": "Pesquisa na Web",
@@ -526,18 +554,20 @@
 	"WebUI will make requests to": "WebUI fará solicitações para",
 	"What’s New in": "O que há de novo em",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando o histórico está desativado, novos bate-papos neste navegador não aparecerão em seu histórico em nenhum dos seus dispositivos.",
-	"Whisper (Local)": "Whisper (Local)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Espaço de Trabalho",
 	"Write a prompt suggestion (e.g. Who are you?)": "Escreva uma sugestão de prompt (por exemplo, Quem é você?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Escreva um resumo em 50 palavras que resuma [tópico ou palavra-chave].",
 	"Yesterday": "Ontem",
 	"You": "Você",
+	"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 clone a base model": "Não é possível clonar um modelo base",
 	"You have no archived conversations.": "Você não tem bate-papos arquivados.",
 	"You have shared this chat": "Você compartilhou este bate-papo",
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're now logged in.": "Você está conectado agora.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Configurações do Carregador do Youtube"
 }

+ 38 - 8
src/lib/i18n/locales/ru-RU/translation.json

@@ -12,6 +12,7 @@
 	"a user": "пользователь",
 	"About": "Об",
 	"Account": "Аккаунт",
+	"Account Activation Pending": "",
 	"Accurate information": "Точная информация",
 	"Active Users": "",
 	"Add": "Добавить",
@@ -29,6 +30,7 @@
 	"Add User": "Добавьте пользователя",
 	"Adjusting these settings will apply changes universally to all users.": "Регулирующий этих настроек приведет к изменениям для все пользователей.",
 	"admin": "админ",
+	"Admin": "",
 	"Admin Panel": "Панель админ",
 	"Admin Settings": "Настройки админ",
 	"Advanced Parameters": "Расширенные Параметры",
@@ -59,7 +61,6 @@
 	"Audio": "Аудио",
 	"August": "Август",
 	"Auto-playback response": "Автоматическое воспроизведение ответа",
-	"Auto-send input after 3 sec.": "Автоматическая отправка ввода через 3 секунды.",
 	"AUTOMATIC1111 Base URL": "Базовый адрес URL AUTOMATIC1111",
 	"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Необходима базовый адрес URL.",
 	"available!": "доступный!",
@@ -71,6 +72,9 @@
 	"Being lazy": "ленивый",
 	"Brave Search API Key": "Ключ API поиска Brave",
 	"Bypass SSL verification for Websites": "Обход SSL-проверки для веб-сайтов",
+	"Call": "",
+	"Call feature is not supported when using Web STT engine": "",
+	"Camera": "",
 	"Cancel": "Аннулировать",
 	"Capabilities": "Возможности",
 	"Change Password": "Изменить пароль",
@@ -88,10 +92,12 @@
 	"Chunk Params": "Параметры фрагментов",
 	"Chunk Size": "Размер фрагмента",
 	"Citation": "Цитата",
+	"Clear memory": "",
 	"Click here for help.": "Нажмите здесь для помощи.",
 	"Click here to": "Нажмите здесь чтобы",
 	"Click here to select": "Нажмите тут чтобы выберите",
 	"Click here to select a csv file.": "Нажмите здесь чтобы выбрать файл csv.",
+	"Click here to select a py file.": "",
 	"Click here to select documents.": "Нажмите здесь чтобы выберите документы.",
 	"click here.": "нажмите здесь.",
 	"Click on the user role button to change a user's role.": "Нажмите кнопку роли пользователя чтобы изменить роль пользователя.",
@@ -105,17 +111,16 @@
 	"Concurrent Requests": "Одновременные запросы",
 	"Confirm Password": "Подтвердите пароль",
 	"Connections": "Соединение",
+	"Contact Admin for WebUI Access": "",
 	"Content": "Содержание",
 	"Context Length": "Длина контексту",
 	"Continue Response": "Продолжить ответ",
-	"Conversation Mode": "Режим разговора",
 	"Copied shared chat URL to clipboard!": "Копирование общей ссылки чат в буфер обмена!",
 	"Copy": "Копировать",
 	"Copy last code block": "Копировать последний блок кода",
 	"Copy last response": "Копировать последний ответ",
 	"Copy Link": "Копировать ссылку",
 	"Copying to clipboard was successful!": "Копирование в буфер обмена прошло успешно!",
-	"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Создайте краткую фразу из 3-5 слов в качестве заголовка для следующего запроса, строго придерживаясь ограничения в 3-5 слов и избегая использования слова 'title':",
 	"Create a model": "Создание модели",
 	"Create Account": "Создать аккаунт",
 	"Create new key": "Создать новый ключ",
@@ -127,12 +132,12 @@
 	"Custom": "Пользовательский",
 	"Customize models for a specific purpose": "Настройка моделей для конкретных целей",
 	"Dark": "Тёмный",
+	"Dashboard": "",
 	"Database": "База данных",
 	"December": "Декабрь",
 	"Default": "По умолчанию",
 	"Default (Automatic1111)": "По умолчанию (Automatic1111)",
 	"Default (SentenceTransformers)": "По умолчанию (SentenceTransformers)",
-	"Default (Web API)": "По умолчанию (Web API)",
 	"Default Model": "Модель по умолчанию",
 	"Default model updated": "Модель по умолчанию обновлена",
 	"Default Prompt Suggestions": "Предложения промтов по умолчанию",
@@ -153,6 +158,7 @@
 	"Discover a prompt": "Найти промт",
 	"Discover, download, and explore custom prompts": "Находите, загружайте и исследуйте настраиваемые промты",
 	"Discover, download, and explore model presets": "Находите, загружайте и исследуйте предустановки модели",
+	"Dismissible": "",
 	"Display the username instead of You in the Chat": "Отображать имя пользователя вместо 'Вы' в чате",
 	"Document": "Документ",
 	"Document Settings": "Настройки документа",
@@ -213,6 +219,7 @@
 	"Export Documents Mapping": "Экспортировать отображение документов",
 	"Export Models": "Экспорт моделей",
 	"Export Prompts": "Экспортировать промты",
+	"External Models": "",
 	"Failed to create API Key.": "Не удалось создать ключ API.",
 	"Failed to read clipboard contents": "Не удалось прочитать содержимое буфера обмена",
 	"Failed to update settings": "",
@@ -228,6 +235,7 @@
 	"Frequency Penalty": "Штраф за частоту",
 	"General": "Общее",
 	"General Settings": "Общие настройки",
+	"Generate Image": "",
 	"Generating search query": "Генерация поискового запроса",
 	"Generation Info": "Информация о генерации",
 	"Good Response": "Хороший ответ",
@@ -252,6 +260,7 @@
 	"Info": "Информация",
 	"Input commands": "Введите команды",
 	"Install from Github URL": "Установка с URL-адреса Github",
+	"Instant Auto-Send After Voice Transcription": "",
 	"Interface": "Интерфейс",
 	"Invalid Tag": "Недопустимый тег",
 	"January": "Январь",
@@ -264,14 +273,17 @@
 	"JWT Token": "Токен JWT",
 	"Keep Alive": "Поддерживать активность",
 	"Keyboard shortcuts": "Горячие клавиши",
+	"Knowledge": "",
 	"Language": "Язык",
 	"Last Active": "Последний активный",
 	"Light": "Светлый",
-	"Listening...": "Слушаю...",
+	"Listening...": "",
 	"LLMs can make mistakes. Verify important information.": "LLMs могут допускать ошибки. Проверяйте важную информацию.",
+	"Local Models": "",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Сделано сообществом OpenWebUI",
 	"Make sure to enclose them with": "Убедитесь, что они заключены в",
+	"Manage": "",
 	"Manage Models": "Управление моделями",
 	"Manage Ollama Models": "Управление моделями Ollama",
 	"Manage Pipelines": "Управление конвейерами",
@@ -307,6 +319,7 @@
 	"Name your model": "Присвойте модели имя",
 	"New Chat": "Новый чат",
 	"New Password": "Новый пароль",
+	"No documents found": "",
 	"No results found": "Результатов не найдено",
 	"No search query generated": "Поисковый запрос не сгенерирован",
 	"No source available": "Нет доступных источников",
@@ -323,6 +336,7 @@
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API disabled": "Ollama API отключен",
+	"Ollama API is disabled": "",
 	"Ollama Version": "Версия Ollama",
 	"On": "Включено.",
 	"Only": "Только",
@@ -345,6 +359,8 @@
 	"PDF document (.pdf)": "PDF-документ (.pdf)",
 	"PDF Extract Images (OCR)": "Извлечение изображений из PDF (OCR)",
 	"pending": "ожидание",
+	"Permission denied when accessing media devices": "",
+	"Permission denied when accessing microphone": "",
 	"Permission denied when accessing microphone: {{error}}": "Отказано в доступе к микрофону: {{error}}",
 	"Personalization": "Персонализация",
 	"Pipelines": "Трубопроводов",
@@ -367,6 +383,7 @@
 	"Read Aloud": "Прочитать вслух",
 	"Record voice": "Записать голос",
 	"Redirecting you to OpenWebUI Community": "Перенаправляем вас в сообщество OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
 	"Refused when it shouldn't have": "Отказано в доступе, когда это не должно было произойти.",
 	"Regenerate": "Перезаписать",
 	"Release Notes": "Примечания к выпуску",
@@ -385,6 +402,7 @@
 	"Rosé Pine": "Розовое сосновое дерево",
 	"Rosé Pine Dawn": "Розовое сосновое дерево рассвет",
 	"RTL": "RTL",
+	"Running": "",
 	"Save": "Сохранить",
 	"Save & Create": "Сохранить и создать",
 	"Save & Update": "Сохранить и обновить",
@@ -398,6 +416,8 @@
 	"Search Documents": "Поиск документов",
 	"Search Models": "Поиск моделей",
 	"Search Prompts": "Поиск промтов",
+	"Search Query Generation Prompt": "",
+	"Search Query Generation Prompt Length Threshold": "",
 	"Search Result Count": "Количество результатов поиска",
 	"Searched {{count}} sites_one": "Поиск {{count}} sites_one",
 	"Searched {{count}} sites_few": "Поиск {{count}} sites_few",
@@ -409,12 +429,14 @@
 	"See what's new": "Посмотреть, что нового",
 	"Seed": "Сид",
 	"Select a base model": "Выбор базовой модели",
+	"Select a engine": "",
 	"Select a mode": "Выберите режим",
 	"Select a model": "Выберите модель",
 	"Select a pipeline": "Выбор конвейера",
 	"Select a pipeline url": "Выберите URL-адрес конвейера",
 	"Select an Ollama instance": "Выберите экземпляр Ollama",
 	"Select model": "Выберите модель",
+	"Select only one model to call": "",
 	"Selected model(s) do not support image inputs": "Выбранные модели не поддерживают ввод изображений",
 	"Send": "Отправить",
 	"Send a Message": "Отправить сообщение",
@@ -427,7 +449,6 @@
 	"Set Default Model": "Установить модель по умолчанию",
 	"Set embedding model (e.g. {{model}})": "Установить модель эмбеддинга (например. {{model}})",
 	"Set Image Size": "Установить размер изображения",
-	"Set Model": "Установить модель",
 	"Set reranking model (e.g. {{model}})": "Установить модель реранжирования (например. {{model}})",
 	"Set Steps": "Установить шаги",
 	"Set Task Model": "Задать модель задачи",
@@ -451,8 +472,8 @@
 	"Source": "Источник",
 	"Speech recognition error: {{error}}": "Ошибка распознавания речи: {{error}}",
 	"Speech-to-Text Engine": "Система распознавания речи",
-	"SpeechRecognition API is not supported in this browser.": "API распознавания речи не поддерживается в этом браузере.",
 	"Stop Sequence": "Последовательность остановки",
+	"STT Model": "",
 	"STT Settings": "Настройки распознавания речи",
 	"Submit": "Отправить",
 	"Subtitle (e.g. about the Roman Empire)": "Подзаголовок (например. о Римской империи)",
@@ -471,7 +492,9 @@
 	"Thanks for your feedback!": "Спасибо за ваше мнение!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Оценка должна быть значением между 0,0 (0%) и 1,0 (100%).",
 	"Theme": "Тема",
+	"Thinking...": "",
 	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Это обеспечивает сохранение ваших ценных разговоров в безопасной базе данных на вашем сервере. Спасибо!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
 	"This setting does not sync across browsers or devices.": "Эта настройка не синхронизируется между браузерами или устройствами.",
 	"Thorough explanation": "Повнимательнее",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Совет: Обновляйте несколько переменных подряд, нажимая клавишу Tab в поле ввода чата после каждой замены.",
@@ -483,6 +506,7 @@
 	"to": "в",
 	"To access the available model names for downloading,": "Чтобы получить доступ к доступным для загрузки именам моделей,",
 	"To access the GGUF models available for downloading,": "Чтобы получить доступ к моделям GGUF, доступным для загрузки,",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
 	"to chat input.": "в чате.",
 	"Today": "Сегодня",
 	"Toggle settings": "Переключить настройки",
@@ -490,7 +514,9 @@
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "Проблемы с доступом к Ollama?",
+	"TTS Model": "",
 	"TTS Settings": "Настройки TTS",
+	"TTS Voice": "",
 	"Type": "Тип",
 	"Type Hugging Face Resolve (Download) URL": "Введите URL-адрес Hugging Face Resolve (загрузки)",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "Упс! Возникла проблема подключения к {{provider}}.",
@@ -499,6 +525,7 @@
 	"Update password": "Обновить пароль",
 	"Upload a GGUF model": "Загрузить модель GGUF",
 	"Upload Files": "Загрузка файлов",
+	"Upload Pipeline": "",
 	"Upload Progress": "Прогресс загрузки",
 	"URL Mode": "Режим URL",
 	"Use '#' in the prompt input to load and select your documents.": "Используйте '#' в поле ввода промпта для загрузки и выбора ваших документов.",
@@ -517,6 +544,7 @@
 	"Warning": "Предупреждение",
 	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Предупреждение: Если вы обновите или измените модель эмбеддинга, вам нужно будет повторно импортировать все документы.",
 	"Web": "Веб",
+	"Web API": "",
 	"Web Loader Settings": "Настройки загрузчика Web",
 	"Web Params": "Параметры Web",
 	"Web Search": "Веб-поиск",
@@ -527,18 +555,20 @@
 	"WebUI will make requests to": "WebUI будет отправлять запросы на",
 	"What’s New in": "Что нового в",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Когда история отключена, новые чаты в этом браузере не будут отображаться в вашей истории на любом из ваших устройств.",
-	"Whisper (Local)": "Шепот (локальный)",
+	"Whisper (Local)": "",
 	"Widescreen Mode": "",
 	"Workspace": "Рабочая область",
 	"Write a prompt suggestion (e.g. Who are you?)": "Напишите предложение промпта (например, Кто вы?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Напишите резюме в 50 словах, которое кратко описывает [тему или ключевое слово].",
 	"Yesterday": "Вчера",
 	"You": "Вы",
+	"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 clone a base model": "Клонировать базовую модель невозможно",
 	"You have no archived conversations.": "У вас нет архивированных бесед.",
 	"You have shared this chat": "Вы поделились этим чатом",
 	"You're a helpful assistant.": "Вы полезный ассистент.",
 	"You're now logged in.": "Вы вошли в систему.",
+	"Your account status is currently pending activation.": "",
 	"Youtube": "Ютуб",
 	"Youtube Loader Settings": "Настройки загрузчика YouTube"
 }

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