瀏覽代碼

Merge remote-tracking branch 'upstream/dev' into feat/oauth

Jun Siang Cheah 10 月之前
父節點
當前提交
f26d80dcae
共有 81 個文件被更改,包括 4060 次插入1162 次删除
  1. 3 0
      backend/apps/rag/main.py
  2. 41 0
      backend/apps/rag/search/jina_search.py
  3. 50 0
      backend/apps/webui/internal/migrations/016_add_valves_and_is_active.py
  4. 7 3
      backend/apps/webui/main.py
  5. 116 9
      backend/apps/webui/models/functions.py
  6. 72 0
      backend/apps/webui/models/tools.py
  7. 23 0
      backend/apps/webui/routers/files.py
  8. 219 3
      backend/apps/webui/routers/functions.py
  9. 192 4
      backend/apps/webui/routers/tools.py
  10. 41 3
      backend/apps/webui/utils.py
  11. 6 0
      backend/config.py
  12. 264 108
      backend/main.py
  13. 3 1
      backend/requirements.txt
  14. 4 1
      backend/utils/tools.py
  15. 4 0
      src/app.css
  16. 230 0
      src/lib/apis/functions/index.ts
  17. 198 0
      src/lib/apis/tools/index.ts
  18. 2 1
      src/lib/components/admin/Settings/WebSearch.svelte
  19. 0 43
      src/lib/components/admin/SettingsModal.svelte
  20. 49 1
      src/lib/components/chat/Chat.svelte
  21. 4 2
      src/lib/components/chat/MessageInput.svelte
  22. 1 1
      src/lib/components/chat/MessageInput/CallOverlay.svelte
  23. 1 1
      src/lib/components/chat/Messages/Placeholder.svelte
  24. 27 0
      src/lib/components/chat/Settings/Interface.svelte
  25. 2 2
      src/lib/components/chat/Settings/Personalization.svelte
  26. 245 0
      src/lib/components/chat/Settings/Valves.svelte
  27. 48 16
      src/lib/components/chat/SettingsModal.svelte
  28. 19 0
      src/lib/components/icons/Heart.svelte
  29. 0 0
      src/lib/components/playground/Playground.svelte
  30. 6 2
      src/lib/components/workspace/Documents.svelte
  31. 172 118
      src/lib/components/workspace/Functions.svelte
  32. 117 0
      src/lib/components/workspace/Functions/FunctionMenu.svelte
  33. 13 9
      src/lib/components/workspace/Models.svelte
  34. 49 77
      src/lib/components/workspace/Prompts.svelte
  35. 92 0
      src/lib/components/workspace/Prompts/PromptMenu.svelte
  36. 158 112
      src/lib/components/workspace/Tools.svelte
  37. 117 0
      src/lib/components/workspace/Tools/ToolMenu.svelte
  38. 102 0
      src/lib/components/workspace/common/ManifestModal.svelte
  39. 256 0
      src/lib/components/workspace/common/ValvesModal.svelte
  40. 11 0
      src/lib/i18n/locales/ar-BH/translation.json
  41. 11 0
      src/lib/i18n/locales/bg-BG/translation.json
  42. 11 0
      src/lib/i18n/locales/bn-BD/translation.json
  43. 403 392
      src/lib/i18n/locales/ca-ES/translation.json
  44. 11 0
      src/lib/i18n/locales/ceb-PH/translation.json
  45. 11 0
      src/lib/i18n/locales/de-DE/translation.json
  46. 11 0
      src/lib/i18n/locales/dg-DG/translation.json
  47. 11 0
      src/lib/i18n/locales/en-GB/translation.json
  48. 11 0
      src/lib/i18n/locales/en-US/translation.json
  49. 11 0
      src/lib/i18n/locales/es-ES/translation.json
  50. 11 0
      src/lib/i18n/locales/fa-IR/translation.json
  51. 11 0
      src/lib/i18n/locales/fi-FI/translation.json
  52. 11 0
      src/lib/i18n/locales/fr-CA/translation.json
  53. 11 0
      src/lib/i18n/locales/fr-FR/translation.json
  54. 11 0
      src/lib/i18n/locales/he-IL/translation.json
  55. 11 0
      src/lib/i18n/locales/hi-IN/translation.json
  56. 11 0
      src/lib/i18n/locales/hr-HR/translation.json
  57. 11 0
      src/lib/i18n/locales/it-IT/translation.json
  58. 11 0
      src/lib/i18n/locales/ja-JP/translation.json
  59. 11 0
      src/lib/i18n/locales/ka-GE/translation.json
  60. 11 0
      src/lib/i18n/locales/ko-KR/translation.json
  61. 11 0
      src/lib/i18n/locales/lt-LT/translation.json
  62. 11 0
      src/lib/i18n/locales/nb-NO/translation.json
  63. 11 0
      src/lib/i18n/locales/nl-NL/translation.json
  64. 11 0
      src/lib/i18n/locales/pa-IN/translation.json
  65. 11 0
      src/lib/i18n/locales/pl-PL/translation.json
  66. 11 0
      src/lib/i18n/locales/pt-BR/translation.json
  67. 11 0
      src/lib/i18n/locales/pt-PT/translation.json
  68. 11 0
      src/lib/i18n/locales/ru-RU/translation.json
  69. 11 0
      src/lib/i18n/locales/sr-RS/translation.json
  70. 11 0
      src/lib/i18n/locales/sv-SE/translation.json
  71. 11 0
      src/lib/i18n/locales/tk-TW/translation.json
  72. 11 0
      src/lib/i18n/locales/tr-TR/translation.json
  73. 11 0
      src/lib/i18n/locales/uk-UA/translation.json
  74. 11 0
      src/lib/i18n/locales/vi-VN/translation.json
  75. 17 6
      src/lib/i18n/locales/zh-CN/translation.json
  76. 251 240
      src/lib/i18n/locales/zh-TW/translation.json
  77. 27 4
      src/lib/utils/index.ts
  78. 6 1
      src/routes/(app)/+layout.svelte
  79. 1 1
      src/routes/(app)/playground/+page.svelte
  80. 1 1
      src/routes/(app)/workspace/+layout.svelte
  81. 27 0
      src/routes/+layout.svelte

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

@@ -77,6 +77,7 @@ from apps.rag.search.serpstack import search_serpstack
 from apps.rag.search.serply import search_serply
 from apps.rag.search.serply import search_serply
 from apps.rag.search.duckduckgo import search_duckduckgo
 from apps.rag.search.duckduckgo import search_duckduckgo
 from apps.rag.search.tavily import search_tavily
 from apps.rag.search.tavily import search_tavily
+from apps.rag.search.jina_search import search_jina
 
 
 from utils.misc import (
 from utils.misc import (
     calculate_sha256,
     calculate_sha256,
@@ -856,6 +857,8 @@ def search_web(engine: str, query: str) -> list[SearchResult]:
             )
             )
         else:
         else:
             raise Exception("No TAVILY_API_KEY found in environment variables")
             raise Exception("No TAVILY_API_KEY found in environment variables")
+    elif engine == "jina":
+        return search_jina(query, app.state.config.RAG_WEB_SEARCH_RESULT_COUNT)
     else:
     else:
         raise Exception("No search engine API key found in environment variables")
         raise Exception("No search engine API key found in environment variables")
 
 

+ 41 - 0
backend/apps/rag/search/jina_search.py

@@ -0,0 +1,41 @@
+import logging
+import requests
+from yarl import URL
+
+from apps.rag.search.main import SearchResult
+from config import SRC_LOG_LEVELS
+
+log = logging.getLogger(__name__)
+log.setLevel(SRC_LOG_LEVELS["RAG"])
+
+
+def search_jina(query: str, count: int) -> list[SearchResult]:
+    """
+    Search using Jina's Search API and return the results as a list of SearchResult objects.
+    Args:
+        query (str): The query to search for
+        count (int): The number of results to return
+
+    Returns:
+        List[SearchResult]: A list of search results
+    """
+    jina_search_endpoint = "https://s.jina.ai/"
+    headers = {
+        "Accept": "application/json",
+    }
+    url = str(URL(jina_search_endpoint + query))
+    response = requests.get(url, headers=headers)
+    response.raise_for_status()
+    data = response.json()
+
+    results = []
+    for result in data["data"][:count]:
+        results.append(
+            SearchResult(
+                link=result["url"],
+                title=result.get("title"),
+                snippet=result.get("content"),
+            )
+        )
+
+    return results

+ 50 - 0
backend/apps/webui/internal/migrations/016_add_valves_and_is_active.py

@@ -0,0 +1,50 @@
+"""Peewee migrations -- 009_add_models.py.
+
+Some examples (model - class or model name)::
+
+    > Model = migrator.orm['table_name']            # Return model in current state by name
+    > Model = migrator.ModelClass                   # Return model in current state by name
+
+    > migrator.sql(sql)                             # Run custom SQL
+    > migrator.run(func, *args, **kwargs)           # Run python function with the given args
+    > migrator.create_model(Model)                  # Create a model (could be used as decorator)
+    > migrator.remove_model(model, cascade=True)    # Remove a model
+    > migrator.add_fields(model, **fields)          # Add fields to a model
+    > migrator.change_fields(model, **fields)       # Change fields
+    > migrator.remove_fields(model, *field_names, cascade=True)
+    > migrator.rename_field(model, old_field_name, new_field_name)
+    > migrator.rename_table(model, new_table_name)
+    > migrator.add_index(model, *col_names, unique=False)
+    > migrator.add_not_null(model, *field_names)
+    > migrator.add_default(model, field_name, default)
+    > migrator.add_constraint(model, name, sql)
+    > migrator.drop_index(model, *col_names)
+    > migrator.drop_not_null(model, *field_names)
+    > migrator.drop_constraints(model, *constraints)
+
+"""
+
+from contextlib import suppress
+
+import peewee as pw
+from peewee_migrate import Migrator
+
+
+with suppress(ImportError):
+    import playhouse.postgres_ext as pw_pext
+
+
+def migrate(migrator: Migrator, database: pw.Database, *, fake=False):
+    """Write your migrations here."""
+
+    migrator.add_fields("tool", valves=pw.TextField(null=True))
+    migrator.add_fields("function", valves=pw.TextField(null=True))
+    migrator.add_fields("function", is_active=pw.BooleanField(default=False))
+
+
+def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
+    """Write your rollback migrations here."""
+
+    migrator.remove_fields("tool", "valves")
+    migrator.remove_fields("function", "valves")
+    migrator.remove_fields("function", "is_active")

+ 7 - 3
backend/apps/webui/main.py

@@ -105,13 +105,15 @@ async def get_status():
 
 
 
 
 async def get_pipe_models():
 async def get_pipe_models():
-    pipes = Functions.get_functions_by_type("pipe")
+    pipes = Functions.get_functions_by_type("pipe", active_only=True)
     pipe_models = []
     pipe_models = []
 
 
     for pipe in pipes:
     for pipe in pipes:
         # Check if function is already loaded
         # Check if function is already loaded
         if pipe.id not in app.state.FUNCTIONS:
         if pipe.id not in app.state.FUNCTIONS:
-            function_module, function_type = load_function_module_by_id(pipe.id)
+            function_module, function_type, frontmatter = load_function_module_by_id(
+                pipe.id
+            )
             app.state.FUNCTIONS[pipe.id] = function_module
             app.state.FUNCTIONS[pipe.id] = function_module
         else:
         else:
             function_module = app.state.FUNCTIONS[pipe.id]
             function_module = app.state.FUNCTIONS[pipe.id]
@@ -132,7 +134,9 @@ async def get_pipe_models():
                     manifold_pipe_name = p["name"]
                     manifold_pipe_name = p["name"]
 
 
                     if hasattr(function_module, "name"):
                     if hasattr(function_module, "name"):
-                        manifold_pipe_name = f"{pipe.name}{manifold_pipe_name}"
+                        manifold_pipe_name = (
+                            f"{function_module.name}{manifold_pipe_name}"
+                        )
 
 
                     pipe_models.append(
                     pipe_models.append(
                         {
                         {

+ 116 - 9
backend/apps/webui/models/functions.py

@@ -5,8 +5,11 @@ from typing import List, Union, Optional
 import time
 import time
 import logging
 import logging
 from apps.webui.internal.db import DB, JSONField
 from apps.webui.internal.db import DB, JSONField
+from apps.webui.models.users import Users
 
 
 import json
 import json
+import copy
+
 
 
 from config import SRC_LOG_LEVELS
 from config import SRC_LOG_LEVELS
 
 
@@ -25,6 +28,8 @@ class Function(Model):
     type = TextField()
     type = TextField()
     content = TextField()
     content = TextField()
     meta = JSONField()
     meta = JSONField()
+    valves = JSONField()
+    is_active = BooleanField(default=False)
     updated_at = BigIntegerField()
     updated_at = BigIntegerField()
     created_at = BigIntegerField()
     created_at = BigIntegerField()
 
 
@@ -34,6 +39,7 @@ class Function(Model):
 
 
 class FunctionMeta(BaseModel):
 class FunctionMeta(BaseModel):
     description: Optional[str] = None
     description: Optional[str] = None
+    manifest: Optional[dict] = {}
 
 
 
 
 class FunctionModel(BaseModel):
 class FunctionModel(BaseModel):
@@ -43,6 +49,7 @@ class FunctionModel(BaseModel):
     type: str
     type: str
     content: str
     content: str
     meta: FunctionMeta
     meta: FunctionMeta
+    is_active: bool = False
     updated_at: int  # timestamp in epoch
     updated_at: int  # timestamp in epoch
     created_at: int  # timestamp in epoch
     created_at: int  # timestamp in epoch
 
 
@@ -58,6 +65,7 @@ class FunctionResponse(BaseModel):
     type: str
     type: str
     name: str
     name: str
     meta: FunctionMeta
     meta: FunctionMeta
+    is_active: bool
     updated_at: int  # timestamp in epoch
     updated_at: int  # timestamp in epoch
     created_at: int  # timestamp in epoch
     created_at: int  # timestamp in epoch
 
 
@@ -69,6 +77,10 @@ class FunctionForm(BaseModel):
     meta: FunctionMeta
     meta: FunctionMeta
 
 
 
 
+class FunctionValves(BaseModel):
+    valves: Optional[dict] = None
+
+
 class FunctionsTable:
 class FunctionsTable:
     def __init__(self, db):
     def __init__(self, db):
         self.db = db
         self.db = db
@@ -104,16 +116,98 @@ class FunctionsTable:
         except:
         except:
             return None
             return None
 
 
-    def get_functions(self) -> List[FunctionModel]:
-        return [
-            FunctionModel(**model_to_dict(function)) for function in Function.select()
-        ]
+    def get_functions(self, active_only=False) -> List[FunctionModel]:
+        if active_only:
+            return [
+                FunctionModel(**model_to_dict(function))
+                for function in Function.select().where(Function.is_active == True)
+            ]
+        else:
+            return [
+                FunctionModel(**model_to_dict(function))
+                for function in Function.select()
+            ]
+
+    def get_functions_by_type(
+        self, type: str, active_only=False
+    ) -> List[FunctionModel]:
+        if active_only:
+            return [
+                FunctionModel(**model_to_dict(function))
+                for function in Function.select().where(
+                    Function.type == type, Function.is_active == True
+                )
+            ]
+        else:
+            return [
+                FunctionModel(**model_to_dict(function))
+                for function in Function.select().where(Function.type == type)
+            ]
+
+    def get_function_valves_by_id(self, id: str) -> Optional[dict]:
+        try:
+            function = Function.get(Function.id == id)
+            return function.valves if function.valves else {}
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
 
 
-    def get_functions_by_type(self, type: str) -> List[FunctionModel]:
-        return [
-            FunctionModel(**model_to_dict(function))
-            for function in Function.select().where(Function.type == type)
-        ]
+    def update_function_valves_by_id(
+        self, id: str, valves: dict
+    ) -> Optional[FunctionValves]:
+        try:
+            query = Function.update(
+                **{"valves": valves},
+                updated_at=int(time.time()),
+            ).where(Function.id == id)
+            query.execute()
+
+            function = Function.get(Function.id == id)
+            return FunctionValves(**model_to_dict(function))
+        except:
+            return None
+
+    def get_user_valves_by_id_and_user_id(
+        self, id: str, user_id: str
+    ) -> Optional[dict]:
+        try:
+            user = Users.get_user_by_id(user_id)
+            user_settings = user.settings.model_dump()
+
+            # Check if user has "functions" and "valves" settings
+            if "functions" not in user_settings:
+                user_settings["functions"] = {}
+            if "valves" not in user_settings["functions"]:
+                user_settings["functions"]["valves"] = {}
+
+            return user_settings["functions"]["valves"].get(id, {})
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
+
+    def update_user_valves_by_id_and_user_id(
+        self, id: str, user_id: str, valves: dict
+    ) -> Optional[dict]:
+        try:
+            user = Users.get_user_by_id(user_id)
+            user_settings = user.settings.model_dump()
+
+            # Check if user has "functions" and "valves" settings
+            if "functions" not in user_settings:
+                user_settings["functions"] = {}
+            if "valves" not in user_settings["functions"]:
+                user_settings["functions"]["valves"] = {}
+
+            user_settings["functions"]["valves"][id] = valves
+
+            # Update the user settings in the database
+            query = Users.update_user_by_id(user_id, {"settings": user_settings})
+            query.execute()
+
+            return user_settings["functions"]["valves"][id]
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
 
 
     def update_function_by_id(self, id: str, updated: dict) -> Optional[FunctionModel]:
     def update_function_by_id(self, id: str, updated: dict) -> Optional[FunctionModel]:
         try:
         try:
@@ -128,6 +222,19 @@ class FunctionsTable:
         except:
         except:
             return None
             return None
 
 
+    def deactivate_all_functions(self) -> Optional[bool]:
+        try:
+            query = Function.update(
+                **{"is_active": False},
+                updated_at=int(time.time()),
+            )
+
+            query.execute()
+
+            return True
+        except:
+            return None
+
     def delete_function_by_id(self, id: str) -> bool:
     def delete_function_by_id(self, id: str) -> bool:
         try:
         try:
             query = Function.delete().where((Function.id == id))
             query = Function.delete().where((Function.id == id))

+ 72 - 0
backend/apps/webui/models/tools.py

@@ -5,8 +5,11 @@ from typing import List, Union, Optional
 import time
 import time
 import logging
 import logging
 from apps.webui.internal.db import DB, JSONField
 from apps.webui.internal.db import DB, JSONField
+from apps.webui.models.users import Users
 
 
 import json
 import json
+import copy
+
 
 
 from config import SRC_LOG_LEVELS
 from config import SRC_LOG_LEVELS
 
 
@@ -25,6 +28,7 @@ class Tool(Model):
     content = TextField()
     content = TextField()
     specs = JSONField()
     specs = JSONField()
     meta = JSONField()
     meta = JSONField()
+    valves = JSONField()
     updated_at = BigIntegerField()
     updated_at = BigIntegerField()
     created_at = BigIntegerField()
     created_at = BigIntegerField()
 
 
@@ -34,6 +38,7 @@ class Tool(Model):
 
 
 class ToolMeta(BaseModel):
 class ToolMeta(BaseModel):
     description: Optional[str] = None
     description: Optional[str] = None
+    manifest: Optional[dict] = {}
 
 
 
 
 class ToolModel(BaseModel):
 class ToolModel(BaseModel):
@@ -68,6 +73,10 @@ class ToolForm(BaseModel):
     meta: ToolMeta
     meta: ToolMeta
 
 
 
 
+class ToolValves(BaseModel):
+    valves: Optional[dict] = None
+
+
 class ToolsTable:
 class ToolsTable:
     def __init__(self, db):
     def __init__(self, db):
         self.db = db
         self.db = db
@@ -106,6 +115,69 @@ class ToolsTable:
     def get_tools(self) -> List[ToolModel]:
     def get_tools(self) -> List[ToolModel]:
         return [ToolModel(**model_to_dict(tool)) for tool in Tool.select()]
         return [ToolModel(**model_to_dict(tool)) for tool in Tool.select()]
 
 
+    def get_tool_valves_by_id(self, id: str) -> Optional[dict]:
+        try:
+            tool = Tool.get(Tool.id == id)
+            return tool.valves if tool.valves else {}
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
+
+    def update_tool_valves_by_id(self, id: str, valves: dict) -> Optional[ToolValves]:
+        try:
+            query = Tool.update(
+                **{"valves": valves},
+                updated_at=int(time.time()),
+            ).where(Tool.id == id)
+            query.execute()
+
+            tool = Tool.get(Tool.id == id)
+            return ToolValves(**model_to_dict(tool))
+        except:
+            return None
+
+    def get_user_valves_by_id_and_user_id(
+        self, id: str, user_id: str
+    ) -> Optional[dict]:
+        try:
+            user = Users.get_user_by_id(user_id)
+            user_settings = user.settings.model_dump()
+
+            # Check if user has "tools" and "valves" settings
+            if "tools" not in user_settings:
+                user_settings["tools"] = {}
+            if "valves" not in user_settings["tools"]:
+                user_settings["tools"]["valves"] = {}
+
+            return user_settings["tools"]["valves"].get(id, {})
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
+
+    def update_user_valves_by_id_and_user_id(
+        self, id: str, user_id: str, valves: dict
+    ) -> Optional[dict]:
+        try:
+            user = Users.get_user_by_id(user_id)
+            user_settings = user.settings.model_dump()
+
+            # Check if user has "tools" and "valves" settings
+            if "tools" not in user_settings:
+                user_settings["tools"] = {}
+            if "valves" not in user_settings["tools"]:
+                user_settings["tools"]["valves"] = {}
+
+            user_settings["tools"]["valves"][id] = valves
+
+            # Update the user settings in the database
+            query = Users.update_user_by_id(user_id, {"settings": user_settings})
+            query.execute()
+
+            return user_settings["tools"]["valves"][id]
+        except Exception as e:
+            print(f"An error occurred: {e}")
+            return None
+
     def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]:
     def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]:
         try:
         try:
             query = Tool.update(
             query = Tool.update(

+ 23 - 0
backend/apps/webui/routers/files.py

@@ -194,6 +194,29 @@ async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
         )
         )
 
 
 
 
+@router.get("/{id}/content/{file_name}", response_model=Optional[FileModel])
+async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
+    file = Files.get_file_by_id(id)
+
+    if file:
+        file_path = Path(file.meta["path"])
+
+        # Check if the file already exists in the cache
+        if file_path.is_file():
+            print(f"file_path: {file_path}")
+            return FileResponse(file_path)
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_404_NOT_FOUND,
+                detail=ERROR_MESSAGES.NOT_FOUND,
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_404_NOT_FOUND,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
 ############################
 ############################
 # Delete File By Id
 # Delete File By Id
 ############################
 ############################

+ 219 - 3
backend/apps/webui/routers/functions.py

@@ -69,7 +69,10 @@ async def create_new_function(
             with open(function_path, "w") as function_file:
             with open(function_path, "w") as function_file:
                 function_file.write(form_data.content)
                 function_file.write(form_data.content)
 
 
-            function_module, function_type = load_function_module_by_id(form_data.id)
+            function_module, function_type, frontmatter = load_function_module_by_id(
+                form_data.id
+            )
+            form_data.meta.manifest = frontmatter
 
 
             FUNCTIONS = request.app.state.FUNCTIONS
             FUNCTIONS = request.app.state.FUNCTIONS
             FUNCTIONS[form_data.id] = function_module
             FUNCTIONS[form_data.id] = function_module
@@ -117,13 +120,40 @@ async def get_function_by_id(id: str, user=Depends(get_admin_user)):
         )
         )
 
 
 
 
+############################
+# ToggleFunctionById
+############################
+
+
+@router.post("/id/{id}/toggle", response_model=Optional[FunctionModel])
+async def toggle_function_by_id(id: str, user=Depends(get_admin_user)):
+    function = Functions.get_function_by_id(id)
+    if function:
+        function = Functions.update_function_by_id(
+            id, {"is_active": not function.is_active}
+        )
+
+        if function:
+            return function
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_400_BAD_REQUEST,
+                detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
 ############################
 ############################
 # UpdateFunctionById
 # UpdateFunctionById
 ############################
 ############################
 
 
 
 
 @router.post("/id/{id}/update", response_model=Optional[FunctionModel])
 @router.post("/id/{id}/update", response_model=Optional[FunctionModel])
-async def update_toolkit_by_id(
+async def update_function_by_id(
     request: Request, id: str, form_data: FunctionForm, user=Depends(get_admin_user)
     request: Request, id: str, form_data: FunctionForm, user=Depends(get_admin_user)
 ):
 ):
     function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
     function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
@@ -132,7 +162,8 @@ async def update_toolkit_by_id(
         with open(function_path, "w") as function_file:
         with open(function_path, "w") as function_file:
             function_file.write(form_data.content)
             function_file.write(form_data.content)
 
 
-        function_module, function_type = load_function_module_by_id(id)
+        function_module, function_type, frontmatter = load_function_module_by_id(id)
+        form_data.meta.manifest = frontmatter
 
 
         FUNCTIONS = request.app.state.FUNCTIONS
         FUNCTIONS = request.app.state.FUNCTIONS
         FUNCTIONS[id] = function_module
         FUNCTIONS[id] = function_module
@@ -178,3 +209,188 @@ async def delete_function_by_id(
         os.remove(function_path)
         os.remove(function_path)
 
 
     return result
     return result
+
+
+############################
+# GetFunctionValves
+############################
+
+
+@router.get("/id/{id}/valves", response_model=Optional[dict])
+async def get_function_valves_by_id(id: str, user=Depends(get_admin_user)):
+    function = Functions.get_function_by_id(id)
+    if function:
+        try:
+            valves = Functions.get_function_valves_by_id(id)
+            return valves
+        except Exception as e:
+            raise HTTPException(
+                status_code=status.HTTP_400_BAD_REQUEST,
+                detail=ERROR_MESSAGES.DEFAULT(e),
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# GetFunctionValvesSpec
+############################
+
+
+@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
+async def get_function_valves_spec_by_id(
+    request: Request, id: str, user=Depends(get_admin_user)
+):
+    function = Functions.get_function_by_id(id)
+    if function:
+        if id in request.app.state.FUNCTIONS:
+            function_module = request.app.state.FUNCTIONS[id]
+        else:
+            function_module, function_type, frontmatter = load_function_module_by_id(id)
+            request.app.state.FUNCTIONS[id] = function_module
+
+        if hasattr(function_module, "Valves"):
+            Valves = function_module.Valves
+            return Valves.schema()
+        return None
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# UpdateFunctionValves
+############################
+
+
+@router.post("/id/{id}/valves/update", response_model=Optional[dict])
+async def update_function_valves_by_id(
+    request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
+):
+    function = Functions.get_function_by_id(id)
+    if function:
+
+        if id in request.app.state.FUNCTIONS:
+            function_module = request.app.state.FUNCTIONS[id]
+        else:
+            function_module, function_type, frontmatter = load_function_module_by_id(id)
+            request.app.state.FUNCTIONS[id] = function_module
+
+        if hasattr(function_module, "Valves"):
+            Valves = function_module.Valves
+
+            try:
+                form_data = {k: v for k, v in form_data.items() if v is not None}
+                valves = Valves(**form_data)
+                Functions.update_function_valves_by_id(id, valves.model_dump())
+                return valves.model_dump()
+            except Exception as e:
+                print(e)
+                raise HTTPException(
+                    status_code=status.HTTP_400_BAD_REQUEST,
+                    detail=ERROR_MESSAGES.DEFAULT(e),
+                )
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail=ERROR_MESSAGES.NOT_FOUND,
+            )
+
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# FunctionUserValves
+############################
+
+
+@router.get("/id/{id}/valves/user", response_model=Optional[dict])
+async def get_function_user_valves_by_id(id: str, user=Depends(get_verified_user)):
+    function = Functions.get_function_by_id(id)
+    if function:
+        try:
+            user_valves = Functions.get_user_valves_by_id_and_user_id(id, user.id)
+            return user_valves
+        except Exception as e:
+            raise HTTPException(
+                status_code=status.HTTP_400_BAD_REQUEST,
+                detail=ERROR_MESSAGES.DEFAULT(e),
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict])
+async def get_function_user_valves_spec_by_id(
+    request: Request, id: str, user=Depends(get_verified_user)
+):
+    function = Functions.get_function_by_id(id)
+    if function:
+        if id in request.app.state.FUNCTIONS:
+            function_module = request.app.state.FUNCTIONS[id]
+        else:
+            function_module, function_type, frontmatter = load_function_module_by_id(id)
+            request.app.state.FUNCTIONS[id] = function_module
+
+        if hasattr(function_module, "UserValves"):
+            UserValves = function_module.UserValves
+            return UserValves.schema()
+        return None
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+@router.post("/id/{id}/valves/user/update", response_model=Optional[dict])
+async def update_function_user_valves_by_id(
+    request: Request, id: str, form_data: dict, user=Depends(get_verified_user)
+):
+    function = Functions.get_function_by_id(id)
+
+    if function:
+        if id in request.app.state.FUNCTIONS:
+            function_module = request.app.state.FUNCTIONS[id]
+        else:
+            function_module, function_type, frontmatter = load_function_module_by_id(id)
+            request.app.state.FUNCTIONS[id] = function_module
+
+        if hasattr(function_module, "UserValves"):
+            UserValves = function_module.UserValves
+
+            try:
+                form_data = {k: v for k, v in form_data.items() if v is not None}
+                user_valves = UserValves(**form_data)
+                Functions.update_user_valves_by_id_and_user_id(
+                    id, user.id, user_valves.model_dump()
+                )
+                return user_valves.model_dump()
+            except Exception as e:
+                print(e)
+                raise HTTPException(
+                    status_code=status.HTTP_400_BAD_REQUEST,
+                    detail=ERROR_MESSAGES.DEFAULT(e),
+                )
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail=ERROR_MESSAGES.NOT_FOUND,
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )

+ 192 - 4
backend/apps/webui/routers/tools.py

@@ -6,10 +6,12 @@ from fastapi import APIRouter
 from pydantic import BaseModel
 from pydantic import BaseModel
 import json
 import json
 
 
+
+from apps.webui.models.users import Users
 from apps.webui.models.tools import Tools, ToolForm, ToolModel, ToolResponse
 from apps.webui.models.tools import Tools, ToolForm, ToolModel, ToolResponse
 from apps.webui.utils import load_toolkit_module_by_id
 from apps.webui.utils import load_toolkit_module_by_id
 
 
-from utils.utils import get_current_user, get_admin_user
+from utils.utils import get_admin_user, get_verified_user
 from utils.tools import get_tools_specs
 from utils.tools import get_tools_specs
 from constants import ERROR_MESSAGES
 from constants import ERROR_MESSAGES
 
 
@@ -32,7 +34,7 @@ router = APIRouter()
 
 
 
 
 @router.get("/", response_model=List[ToolResponse])
 @router.get("/", response_model=List[ToolResponse])
-async def get_toolkits(user=Depends(get_current_user)):
+async def get_toolkits(user=Depends(get_verified_user)):
     toolkits = [toolkit for toolkit in Tools.get_tools()]
     toolkits = [toolkit for toolkit in Tools.get_tools()]
     return toolkits
     return toolkits
 
 
@@ -72,7 +74,8 @@ async def create_new_toolkit(
             with open(toolkit_path, "w") as tool_file:
             with open(toolkit_path, "w") as tool_file:
                 tool_file.write(form_data.content)
                 tool_file.write(form_data.content)
 
 
-            toolkit_module = load_toolkit_module_by_id(form_data.id)
+            toolkit_module, frontmatter = load_toolkit_module_by_id(form_data.id)
+            form_data.meta.manifest = frontmatter
 
 
             TOOLS = request.app.state.TOOLS
             TOOLS = request.app.state.TOOLS
             TOOLS[form_data.id] = toolkit_module
             TOOLS[form_data.id] = toolkit_module
@@ -136,7 +139,8 @@ async def update_toolkit_by_id(
         with open(toolkit_path, "w") as tool_file:
         with open(toolkit_path, "w") as tool_file:
             tool_file.write(form_data.content)
             tool_file.write(form_data.content)
 
 
-        toolkit_module = load_toolkit_module_by_id(id)
+        toolkit_module, frontmatter = load_toolkit_module_by_id(id)
+        form_data.meta.manifest = frontmatter
 
 
         TOOLS = request.app.state.TOOLS
         TOOLS = request.app.state.TOOLS
         TOOLS[id] = toolkit_module
         TOOLS[id] = toolkit_module
@@ -185,3 +189,187 @@ async def delete_toolkit_by_id(request: Request, id: str, user=Depends(get_admin
         os.remove(toolkit_path)
         os.remove(toolkit_path)
 
 
     return result
     return result
+
+
+############################
+# GetToolValves
+############################
+
+
+@router.get("/id/{id}/valves", response_model=Optional[dict])
+async def get_toolkit_valves_by_id(id: str, user=Depends(get_admin_user)):
+    toolkit = Tools.get_tool_by_id(id)
+    if toolkit:
+        try:
+            valves = Tools.get_tool_valves_by_id(id)
+            return valves
+        except Exception as e:
+            raise HTTPException(
+                status_code=status.HTTP_400_BAD_REQUEST,
+                detail=ERROR_MESSAGES.DEFAULT(e),
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# GetToolValvesSpec
+############################
+
+
+@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
+async def get_toolkit_valves_spec_by_id(
+    request: Request, id: str, user=Depends(get_admin_user)
+):
+    toolkit = Tools.get_tool_by_id(id)
+    if toolkit:
+        if id in request.app.state.TOOLS:
+            toolkit_module = request.app.state.TOOLS[id]
+        else:
+            toolkit_module, frontmatter = load_toolkit_module_by_id(id)
+            request.app.state.TOOLS[id] = toolkit_module
+
+        if hasattr(toolkit_module, "Valves"):
+            Valves = toolkit_module.Valves
+            return Valves.schema()
+        return None
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# UpdateToolValves
+############################
+
+
+@router.post("/id/{id}/valves/update", response_model=Optional[dict])
+async def update_toolkit_valves_by_id(
+    request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
+):
+    toolkit = Tools.get_tool_by_id(id)
+    if toolkit:
+        if id in request.app.state.TOOLS:
+            toolkit_module = request.app.state.TOOLS[id]
+        else:
+            toolkit_module, frontmatter = load_toolkit_module_by_id(id)
+            request.app.state.TOOLS[id] = toolkit_module
+
+        if hasattr(toolkit_module, "Valves"):
+            Valves = toolkit_module.Valves
+
+            try:
+                form_data = {k: v for k, v in form_data.items() if v is not None}
+                valves = Valves(**form_data)
+                Tools.update_tool_valves_by_id(id, valves.model_dump())
+                return valves.model_dump()
+            except Exception as e:
+                print(e)
+                raise HTTPException(
+                    status_code=status.HTTP_400_BAD_REQUEST,
+                    detail=ERROR_MESSAGES.DEFAULT(e),
+                )
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail=ERROR_MESSAGES.NOT_FOUND,
+            )
+
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+############################
+# ToolUserValves
+############################
+
+
+@router.get("/id/{id}/valves/user", response_model=Optional[dict])
+async def get_toolkit_user_valves_by_id(id: str, user=Depends(get_verified_user)):
+    toolkit = Tools.get_tool_by_id(id)
+    if toolkit:
+        try:
+            user_valves = Tools.get_user_valves_by_id_and_user_id(id, user.id)
+            return user_valves
+        except Exception as e:
+            raise HTTPException(
+                status_code=status.HTTP_400_BAD_REQUEST,
+                detail=ERROR_MESSAGES.DEFAULT(e),
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict])
+async def get_toolkit_user_valves_spec_by_id(
+    request: Request, id: str, user=Depends(get_verified_user)
+):
+    toolkit = Tools.get_tool_by_id(id)
+    if toolkit:
+        if id in request.app.state.TOOLS:
+            toolkit_module = request.app.state.TOOLS[id]
+        else:
+            toolkit_module, frontmatter = load_toolkit_module_by_id(id)
+            request.app.state.TOOLS[id] = toolkit_module
+
+        if hasattr(toolkit_module, "UserValves"):
+            UserValves = toolkit_module.UserValves
+            return UserValves.schema()
+        return None
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )
+
+
+@router.post("/id/{id}/valves/user/update", response_model=Optional[dict])
+async def update_toolkit_user_valves_by_id(
+    request: Request, id: str, form_data: dict, user=Depends(get_verified_user)
+):
+    toolkit = Tools.get_tool_by_id(id)
+
+    if toolkit:
+        if id in request.app.state.TOOLS:
+            toolkit_module = request.app.state.TOOLS[id]
+        else:
+            toolkit_module, frontmatter = load_toolkit_module_by_id(id)
+            request.app.state.TOOLS[id] = toolkit_module
+
+        if hasattr(toolkit_module, "UserValves"):
+            UserValves = toolkit_module.UserValves
+
+            try:
+                form_data = {k: v for k, v in form_data.items() if v is not None}
+                user_valves = UserValves(**form_data)
+                Tools.update_user_valves_by_id_and_user_id(
+                    id, user.id, user_valves.model_dump()
+                )
+                return user_valves.model_dump()
+            except Exception as e:
+                print(e)
+                raise HTTPException(
+                    status_code=status.HTTP_400_BAD_REQUEST,
+                    detail=ERROR_MESSAGES.DEFAULT(e),
+                )
+        else:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail=ERROR_MESSAGES.NOT_FOUND,
+            )
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.NOT_FOUND,
+        )

+ 41 - 3
backend/apps/webui/utils.py

@@ -1,19 +1,56 @@
 from importlib import util
 from importlib import util
 import os
 import os
+import re
 
 
 from config import TOOLS_DIR, FUNCTIONS_DIR
 from config import TOOLS_DIR, FUNCTIONS_DIR
 
 
 
 
+def extract_frontmatter(file_path):
+    """
+    Extract frontmatter as a dictionary from the specified file path.
+    """
+    frontmatter = {}
+    frontmatter_started = False
+    frontmatter_ended = False
+    frontmatter_pattern = re.compile(r"^\s*([a-z_]+):\s*(.*)\s*$", re.IGNORECASE)
+
+    try:
+        with open(file_path, "r", encoding="utf-8") as file:
+            for line in file:
+                if '"""' in line:
+                    if not frontmatter_started:
+                        frontmatter_started = True
+                        continue  # skip the line with the opening triple quotes
+                    else:
+                        frontmatter_ended = True
+                        break
+
+                if frontmatter_started and not frontmatter_ended:
+                    match = frontmatter_pattern.match(line)
+                    if match:
+                        key, value = match.groups()
+                        frontmatter[key.strip()] = value.strip()
+    except FileNotFoundError:
+        print(f"Error: The file {file_path} does not exist.")
+        return {}
+    except Exception as e:
+        print(f"An error occurred: {e}")
+        return {}
+
+    return frontmatter
+
+
 def load_toolkit_module_by_id(toolkit_id):
 def load_toolkit_module_by_id(toolkit_id):
     toolkit_path = os.path.join(TOOLS_DIR, f"{toolkit_id}.py")
     toolkit_path = os.path.join(TOOLS_DIR, f"{toolkit_id}.py")
     spec = util.spec_from_file_location(toolkit_id, toolkit_path)
     spec = util.spec_from_file_location(toolkit_id, toolkit_path)
     module = util.module_from_spec(spec)
     module = util.module_from_spec(spec)
+    frontmatter = extract_frontmatter(toolkit_path)
 
 
     try:
     try:
         spec.loader.exec_module(module)
         spec.loader.exec_module(module)
         print(f"Loaded module: {module.__name__}")
         print(f"Loaded module: {module.__name__}")
         if hasattr(module, "Tools"):
         if hasattr(module, "Tools"):
-            return module.Tools()
+            return module.Tools(), frontmatter
         else:
         else:
             raise Exception("No Tools class found")
             raise Exception("No Tools class found")
     except Exception as e:
     except Exception as e:
@@ -28,14 +65,15 @@ def load_function_module_by_id(function_id):
 
 
     spec = util.spec_from_file_location(function_id, function_path)
     spec = util.spec_from_file_location(function_id, function_path)
     module = util.module_from_spec(spec)
     module = util.module_from_spec(spec)
+    frontmatter = extract_frontmatter(function_path)
 
 
     try:
     try:
         spec.loader.exec_module(module)
         spec.loader.exec_module(module)
         print(f"Loaded module: {module.__name__}")
         print(f"Loaded module: {module.__name__}")
         if hasattr(module, "Pipe"):
         if hasattr(module, "Pipe"):
-            return module.Pipe(), "pipe"
+            return module.Pipe(), "pipe", frontmatter
         elif hasattr(module, "Filter"):
         elif hasattr(module, "Filter"):
-            return module.Filter(), "filter"
+            return module.Filter(), "filter", frontmatter
         else:
         else:
             raise Exception("No Function class found")
             raise Exception("No Function class found")
     except Exception as e:
     except Exception as e:

+ 6 - 0
backend/config.py

@@ -167,6 +167,12 @@ for version in soup.find_all("h2"):
 CHANGELOG = changelog_json
 CHANGELOG = changelog_json
 
 
 
 
+####################################
+# SAFE_MODE
+####################################
+
+SAFE_MODE = os.environ.get("SAFE_MODE", "false").lower() == "true"
+
 ####################################
 ####################################
 # WEBUI_BUILD_HASH
 # WEBUI_BUILD_HASH
 ####################################
 ####################################

+ 264 - 108
backend/main.py

@@ -62,9 +62,7 @@ from apps.webui.models.functions import Functions
 from apps.webui.models.users import Users
 from apps.webui.models.users import Users
 
 
 from apps.webui.utils import load_toolkit_module_by_id, load_function_module_by_id
 from apps.webui.utils import load_toolkit_module_by_id, load_function_module_by_id
-from apps.webui.utils import load_toolkit_module_by_id
 
 
-from utils.misc import parse_duration
 from utils.utils import (
 from utils.utils import (
     get_admin_user,
     get_admin_user,
     get_verified_user,
     get_verified_user,
@@ -82,6 +80,7 @@ from utils.misc import (
     get_last_user_message,
     get_last_user_message,
     add_or_update_system_message,
     add_or_update_system_message,
     stream_message_template,
     stream_message_template,
+    parse_duration,
 )
 )
 
 
 from apps.rag.utils import get_rag_context, rag_template
 from apps.rag.utils import get_rag_context, rag_template
@@ -113,6 +112,7 @@ from config import (
     SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
     SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
     SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
     SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
     TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
     TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
+    SAFE_MODE,
     OAUTH_PROVIDERS,
     OAUTH_PROVIDERS,
     ENABLE_OAUTH_SIGNUP,
     ENABLE_OAUTH_SIGNUP,
     OAUTH_MERGE_ACCOUNTS_BY_EMAIL,
     OAUTH_MERGE_ACCOUNTS_BY_EMAIL,
@@ -124,6 +124,11 @@ from config import (
 from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
 from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
 from utils.webhook import post_webhook
 from utils.webhook import post_webhook
 
 
+if SAFE_MODE:
+    print("SAFE MODE ENABLED")
+    Functions.deactivate_all_functions()
+
+
 logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
 logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
 log.setLevel(SRC_LOG_LEVELS["MAIN"])
 log.setLevel(SRC_LOG_LEVELS["MAIN"])
@@ -271,7 +276,7 @@ async def get_function_call_response(
                 if tool_id in webui_app.state.TOOLS:
                 if tool_id in webui_app.state.TOOLS:
                     toolkit_module = webui_app.state.TOOLS[tool_id]
                     toolkit_module = webui_app.state.TOOLS[tool_id]
                 else:
                 else:
-                    toolkit_module = load_toolkit_module_by_id(tool_id)
+                    toolkit_module, frontmatter = load_toolkit_module_by_id(tool_id)
                     webui_app.state.TOOLS[tool_id] = toolkit_module
                     webui_app.state.TOOLS[tool_id] = toolkit_module
 
 
                 file_handler = False
                 file_handler = False
@@ -280,6 +285,14 @@ async def get_function_call_response(
                     file_handler = True
                     file_handler = True
                     print("file_handler: ", file_handler)
                     print("file_handler: ", file_handler)
 
 
+                if hasattr(toolkit_module, "valves") and hasattr(
+                    toolkit_module, "Valves"
+                ):
+                    valves = Tools.get_tool_valves_by_id(tool_id)
+                    toolkit_module.valves = toolkit_module.Valves(
+                        **(valves if valves else {})
+                    )
+
                 function = getattr(toolkit_module, result["name"])
                 function = getattr(toolkit_module, result["name"])
                 function_result = None
                 function_result = None
                 try:
                 try:
@@ -289,16 +302,24 @@ async def get_function_call_response(
 
 
                     if "__user__" in sig.parameters:
                     if "__user__" in sig.parameters:
                         # Call the function with the '__user__' parameter included
                         # Call the function with the '__user__' parameter included
-                        params = {
-                            **params,
-                            "__user__": {
-                                "id": user.id,
-                                "email": user.email,
-                                "name": user.name,
-                                "role": user.role,
-                            },
+                        __user__ = {
+                            "id": user.id,
+                            "email": user.email,
+                            "name": user.name,
+                            "role": user.role,
                         }
                         }
 
 
+                        try:
+                            if hasattr(toolkit_module, "UserValves"):
+                                __user__["valves"] = toolkit_module.UserValves(
+                                    **Tools.get_user_valves_by_id_and_user_id(
+                                        tool_id, user.id
+                                    )
+                                )
+                        except Exception as e:
+                            print(e)
+
+                        params = {**params, "__user__": __user__}
                     if "__messages__" in sig.parameters:
                     if "__messages__" in sig.parameters:
                         # Call the function with the '__messages__' parameter included
                         # Call the function with the '__messages__' parameter included
                         params = {
                         params = {
@@ -386,54 +407,94 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
                 )
                 )
             model = app.state.MODELS[model_id]
             model = app.state.MODELS[model_id]
 
 
+            def get_priority(function_id):
+                function = Functions.get_function_by_id(function_id)
+                if function is not None and hasattr(function, "valves"):
+                    return (function.valves if function.valves else {}).get(
+                        "priority", 0
+                    )
+                return 0
+
+            filter_ids = [
+                function.id
+                for function in Functions.get_functions_by_type(
+                    "filter", active_only=True
+                )
+            ]
             # Check if the model has any filters
             # Check if the model has any filters
             if "info" in model and "meta" in model["info"]:
             if "info" in model and "meta" in model["info"]:
-                for filter_id in model["info"]["meta"].get("filterIds", []):
-                    filter = Functions.get_function_by_id(filter_id)
-                    if filter:
-                        if filter_id in webui_app.state.FUNCTIONS:
-                            function_module = webui_app.state.FUNCTIONS[filter_id]
-                        else:
-                            function_module, function_type = load_function_module_by_id(
-                                filter_id
-                            )
-                            webui_app.state.FUNCTIONS[filter_id] = function_module
+                filter_ids.extend(model["info"]["meta"].get("filterIds", []))
+                filter_ids = list(set(filter_ids))
+
+            filter_ids.sort(key=get_priority)
+            for filter_id in filter_ids:
+                filter = Functions.get_function_by_id(filter_id)
+                if filter:
+                    if filter_id in webui_app.state.FUNCTIONS:
+                        function_module = webui_app.state.FUNCTIONS[filter_id]
+                    else:
+                        function_module, function_type, frontmatter = (
+                            load_function_module_by_id(filter_id)
+                        )
+                        webui_app.state.FUNCTIONS[filter_id] = function_module
+
+                    # Check if the function has a file_handler variable
+                    if hasattr(function_module, "file_handler"):
+                        skip_files = function_module.file_handler
+
+                    if hasattr(function_module, "valves") and hasattr(
+                        function_module, "Valves"
+                    ):
+                        valves = Functions.get_function_valves_by_id(filter_id)
+                        function_module.valves = function_module.Valves(
+                            **(valves if valves else {})
+                        )
 
 
-                        # Check if the function has a file_handler variable
-                        if hasattr(function_module, "file_handler"):
-                            skip_files = function_module.file_handler
+                    try:
+                        if hasattr(function_module, "inlet"):
+                            inlet = function_module.inlet
 
 
-                        try:
-                            if hasattr(function_module, "inlet"):
-                                inlet = function_module.inlet
-
-                                if inspect.iscoroutinefunction(inlet):
-                                    data = await inlet(
-                                        data,
-                                        {
-                                            "id": user.id,
-                                            "email": user.email,
-                                            "name": user.name,
-                                            "role": user.role,
-                                        },
-                                    )
-                                else:
-                                    data = inlet(
-                                        data,
-                                        {
-                                            "id": user.id,
-                                            "email": user.email,
-                                            "name": user.name,
-                                            "role": user.role,
-                                        },
-                                    )
+                            # Get the signature of the function
+                            sig = inspect.signature(inlet)
+                            params = {"body": data}
 
 
-                        except Exception as e:
-                            print(f"Error: {e}")
-                            return JSONResponse(
-                                status_code=status.HTTP_400_BAD_REQUEST,
-                                content={"detail": str(e)},
-                            )
+                            if "__user__" in sig.parameters:
+                                __user__ = {
+                                    "id": user.id,
+                                    "email": user.email,
+                                    "name": user.name,
+                                    "role": user.role,
+                                }
+
+                                try:
+                                    if hasattr(function_module, "UserValves"):
+                                        __user__["valves"] = function_module.UserValves(
+                                            **Functions.get_user_valves_by_id_and_user_id(
+                                                filter_id, user.id
+                                            )
+                                        )
+                                except Exception as e:
+                                    print(e)
+
+                                params = {**params, "__user__": __user__}
+
+                            if "__id__" in sig.parameters:
+                                params = {
+                                    **params,
+                                    "__id__": filter_id,
+                                }
+
+                            if inspect.iscoroutinefunction(inlet):
+                                data = await inlet(**params)
+                            else:
+                                data = inlet(**params)
+
+                    except Exception as e:
+                        print(f"Error: {e}")
+                        return JSONResponse(
+                            status_code=status.HTTP_400_BAD_REQUEST,
+                            content={"detail": str(e)},
+                        )
 
 
             # Set the task model
             # Set the task model
             task_model_id = data["model"]
             task_model_id = data["model"]
@@ -857,12 +918,6 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
 
 
     pipe = model.get("pipe")
     pipe = model.get("pipe")
     if pipe:
     if pipe:
-        form_data["user"] = {
-            "id": user.id,
-            "email": user.email,
-            "name": user.name,
-            "role": user.role,
-        }
 
 
         async def job():
         async def job():
             pipe_id = form_data["model"]
             pipe_id = form_data["model"]
@@ -870,14 +925,62 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
                 pipe_id, sub_pipe_id = pipe_id.split(".", 1)
                 pipe_id, sub_pipe_id = pipe_id.split(".", 1)
             print(pipe_id)
             print(pipe_id)
 
 
-            pipe = webui_app.state.FUNCTIONS[pipe_id].pipe
+            # Check if function is already loaded
+            if pipe_id not in webui_app.state.FUNCTIONS:
+                function_module, function_type, frontmatter = (
+                    load_function_module_by_id(pipe_id)
+                )
+                webui_app.state.FUNCTIONS[pipe_id] = function_module
+            else:
+                function_module = webui_app.state.FUNCTIONS[pipe_id]
+
+            if hasattr(function_module, "valves") and hasattr(
+                function_module, "Valves"
+            ):
+
+                valves = Functions.get_function_valves_by_id(pipe_id)
+                function_module.valves = function_module.Valves(
+                    **(valves if valves else {})
+                )
+
+            pipe = function_module.pipe
+
+            # Get the signature of the function
+            sig = inspect.signature(pipe)
+            params = {"body": form_data}
+
+            if "__user__" in sig.parameters:
+                __user__ = {
+                    "id": user.id,
+                    "email": user.email,
+                    "name": user.name,
+                    "role": user.role,
+                }
+
+                try:
+                    if hasattr(function_module, "UserValves"):
+                        __user__["valves"] = function_module.UserValves(
+                            **Functions.get_user_valves_by_id_and_user_id(
+                                pipe_id, user.id
+                            )
+                        )
+                except Exception as e:
+                    print(e)
+
+                params = {**params, "__user__": __user__}
+
             if form_data["stream"]:
             if form_data["stream"]:
 
 
                 async def stream_content():
                 async def stream_content():
-                    if inspect.iscoroutinefunction(pipe):
-                        res = await pipe(body=form_data)
-                    else:
-                        res = pipe(body=form_data)
+                    try:
+                        if inspect.iscoroutinefunction(pipe):
+                            res = await pipe(**params)
+                        else:
+                            res = pipe(**params)
+                    except Exception as e:
+                        print(f"Error: {e}")
+                        yield f"data: {json.dumps({'error': {'detail':str(e)}})}\n\n"
+                        return
 
 
                     if isinstance(res, str):
                     if isinstance(res, str):
                         message = stream_message_template(form_data["model"], res)
                         message = stream_message_template(form_data["model"], res)
@@ -922,10 +1025,20 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
                     stream_content(), media_type="text/event-stream"
                     stream_content(), media_type="text/event-stream"
                 )
                 )
             else:
             else:
+
+                try:
+                    if inspect.iscoroutinefunction(pipe):
+                        res = await pipe(**params)
+                    else:
+                        res = pipe(**params)
+                except Exception as e:
+                    print(f"Error: {e}")
+                    return {"error": {"detail": str(e)}}
+
                 if inspect.iscoroutinefunction(pipe):
                 if inspect.iscoroutinefunction(pipe):
-                    res = await pipe(body=form_data)
+                    res = await pipe(**params)
                 else:
                 else:
-                    res = pipe(body=form_data)
+                    res = pipe(**params)
 
 
                 if isinstance(res, dict):
                 if isinstance(res, dict):
                     return res
                     return res
@@ -1008,7 +1121,12 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
                     f"{url}/{filter['id']}/filter/outlet",
                     f"{url}/{filter['id']}/filter/outlet",
                     headers=headers,
                     headers=headers,
                     json={
                     json={
-                        "user": {"id": user.id, "name": user.name, "role": user.role},
+                        "user": {
+                            "id": user.id,
+                            "name": user.name,
+                            "email": user.email,
+                            "role": user.role,
+                        },
                         "body": data,
                         "body": data,
                     },
                     },
                 )
                 )
@@ -1033,49 +1151,88 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
             else:
             else:
                 pass
                 pass
 
 
+    def get_priority(function_id):
+        function = Functions.get_function_by_id(function_id)
+        if function is not None and hasattr(function, "valves"):
+            return (function.valves if function.valves else {}).get("priority", 0)
+        return 0
+
+    filter_ids = [
+        function.id
+        for function in Functions.get_functions_by_type("filter", active_only=True)
+    ]
     # Check if the model has any filters
     # Check if the model has any filters
     if "info" in model and "meta" in model["info"]:
     if "info" in model and "meta" in model["info"]:
-        for filter_id in model["info"]["meta"].get("filterIds", []):
-            filter = Functions.get_function_by_id(filter_id)
-            if filter:
-                if filter_id in webui_app.state.FUNCTIONS:
-                    function_module = webui_app.state.FUNCTIONS[filter_id]
-                else:
-                    function_module, function_type = load_function_module_by_id(
-                        filter_id
-                    )
-                    webui_app.state.FUNCTIONS[filter_id] = function_module
+        filter_ids.extend(model["info"]["meta"].get("filterIds", []))
+        filter_ids = list(set(filter_ids))
 
 
-                try:
-                    if hasattr(function_module, "outlet"):
-                        outlet = function_module.outlet
-                        if inspect.iscoroutinefunction(outlet):
-                            data = await outlet(
-                                data,
-                                {
-                                    "id": user.id,
-                                    "email": user.email,
-                                    "name": user.name,
-                                    "role": user.role,
-                                },
-                            )
-                        else:
-                            data = outlet(
-                                data,
-                                {
-                                    "id": user.id,
-                                    "email": user.email,
-                                    "name": user.name,
-                                    "role": user.role,
-                                },
-                            )
+    # Sort filter_ids by priority, using the get_priority function
+    filter_ids.sort(key=get_priority)
 
 
-                except Exception as e:
-                    print(f"Error: {e}")
-                    return JSONResponse(
-                        status_code=status.HTTP_400_BAD_REQUEST,
-                        content={"detail": str(e)},
-                    )
+    for filter_id in filter_ids:
+        filter = Functions.get_function_by_id(filter_id)
+        if filter:
+            if filter_id in webui_app.state.FUNCTIONS:
+                function_module = webui_app.state.FUNCTIONS[filter_id]
+            else:
+                function_module, function_type, frontmatter = (
+                    load_function_module_by_id(filter_id)
+                )
+                webui_app.state.FUNCTIONS[filter_id] = function_module
+
+            if hasattr(function_module, "valves") and hasattr(
+                function_module, "Valves"
+            ):
+                valves = Functions.get_function_valves_by_id(filter_id)
+                function_module.valves = function_module.Valves(
+                    **(valves if valves else {})
+                )
+
+            try:
+                if hasattr(function_module, "outlet"):
+                    outlet = function_module.outlet
+
+                    # Get the signature of the function
+                    sig = inspect.signature(outlet)
+                    params = {"body": data}
+
+                    if "__user__" in sig.parameters:
+                        __user__ = {
+                            "id": user.id,
+                            "email": user.email,
+                            "name": user.name,
+                            "role": user.role,
+                        }
+
+                        try:
+                            if hasattr(function_module, "UserValves"):
+                                __user__["valves"] = function_module.UserValves(
+                                    **Functions.get_user_valves_by_id_and_user_id(
+                                        filter_id, user.id
+                                    )
+                                )
+                        except Exception as e:
+                            print(e)
+
+                        params = {**params, "__user__": __user__}
+
+                    if "__id__" in sig.parameters:
+                        params = {
+                            **params,
+                            "__id__": filter_id,
+                        }
+
+                    if inspect.iscoroutinefunction(outlet):
+                        data = await outlet(**params)
+                    else:
+                        data = outlet(**params)
+
+            except Exception as e:
+                print(f"Error: {e}")
+                return JSONResponse(
+                    status_code=status.HTTP_400_BAD_REQUEST,
+                    content={"detail": str(e)},
+                )
 
 
     return data
     return data
 
 
@@ -1989,7 +2146,6 @@ async def get_manifest_json():
         "start_url": "/",
         "start_url": "/",
         "display": "standalone",
         "display": "standalone",
         "background_color": "#343541",
         "background_color": "#343541",
-        "theme_color": "#343541",
         "orientation": "portrait-primary",
         "orientation": "portrait-primary",
         "icons": [{"src": "/static/logo.png", "type": "image/png", "sizes": "500x500"}],
         "icons": [{"src": "/static/logo.png", "type": "image/png", "sizes": "500x500"}],
     }
     }

+ 3 - 1
backend/requirements.txt

@@ -17,7 +17,9 @@ peewee-migrate==1.12.2
 psycopg2-binary==2.9.9
 psycopg2-binary==2.9.9
 PyMySQL==1.1.1
 PyMySQL==1.1.1
 bcrypt==4.1.3
 bcrypt==4.1.3
-
+SQLAlchemy
+pymongo
+redis
 boto3==1.34.110
 boto3==1.34.110
 
 
 argon2-cffi==23.1.0
 argon2-cffi==23.1.0

+ 4 - 1
backend/utils/tools.py

@@ -20,7 +20,9 @@ def get_tools_specs(tools) -> List[dict]:
     function_list = [
     function_list = [
         {"name": func, "function": getattr(tools, func)}
         {"name": func, "function": getattr(tools, func)}
         for func in dir(tools)
         for func in dir(tools)
-        if callable(getattr(tools, func)) and not func.startswith("__")
+        if callable(getattr(tools, func))
+        and not func.startswith("__")
+        and not inspect.isclass(getattr(tools, func))
     ]
     ]
 
 
     specs = []
     specs = []
@@ -65,6 +67,7 @@ def get_tools_specs(tools) -> List[dict]:
                             function
                             function
                         ).parameters.items()
                         ).parameters.items()
                         if param.default is param.empty
                         if param.default is param.empty
+                        and not (name.startswith("__") and name.endswith("__"))
                     ],
                     ],
                 },
                 },
             }
             }

+ 4 - 0
src/app.css

@@ -32,6 +32,10 @@ math {
 	@apply underline;
 	@apply underline;
 }
 }
 
 
+iframe {
+	@apply rounded-lg;
+}
+
 ol > li {
 ol > li {
 	counter-increment: list-number;
 	counter-increment: list-number;
 	display: block;
 	display: block;

+ 230 - 0
src/lib/apis/functions/index.ts

@@ -191,3 +191,233 @@ export const deleteFunctionById = async (token: string, id: string) => {
 
 
 	return res;
 	return res;
 };
 };
+
+export const toggleFunctionById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/toggle`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getFunctionValvesById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getFunctionValvesSpecById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/spec`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const updateFunctionValvesById = async (token: string, id: string, valves: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/update`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			...valves
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getUserValvesById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getUserValvesSpecById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/spec`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const updateUserValvesById = async (token: string, id: string, valves: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/update`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			...valves
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};

+ 198 - 0
src/lib/apis/tools/index.ts

@@ -191,3 +191,201 @@ export const deleteToolById = async (token: string, id: string) => {
 
 
 	return res;
 	return res;
 };
 };
+
+export const getToolValvesById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getToolValvesSpecById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/spec`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const updateToolValvesById = async (token: string, id: string, valves: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/update`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			...valves
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getUserValvesById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const getUserValvesSpecById = async (token: string, id: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/spec`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
+export const updateUserValvesById = async (token: string, id: string, valves: object) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/update`, {
+		method: 'POST',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			authorization: `Bearer ${token}`
+		},
+		body: JSON.stringify({
+			...valves
+		})
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err.detail;
+
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};

+ 2 - 1
src/lib/components/admin/Settings/WebSearch.svelte

@@ -19,7 +19,8 @@
 		'serper',
 		'serper',
 		'serply',
 		'serply',
 		'duckduckgo',
 		'duckduckgo',
-		'tavily'
+		'tavily',
+		'jina'
 	];
 	];
 
 
 	let youtubeLanguage = 'en';
 	let youtubeLanguage = 'en';

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

@@ -1,43 +0,0 @@
-<script>
-	import { getContext } from 'svelte';
-	import Modal from '../common/Modal.svelte';
-	import Database from './Settings/Database.svelte';
-
-	import General from './Settings/General.svelte';
-	import Users from './Settings/Users.svelte';
-
-	import Banners from '$lib/components/admin/Settings/Banners.svelte';
-	import { toast } from 'svelte-sonner';
-	import Pipelines from './Settings/Pipelines.svelte';
-
-	const i18n = getContext('i18n');
-
-	export let show = false;
-
-	let selectedTab = 'general';
-</script>
-
-<Modal bind:show>
-	<div>
-		<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
-			<div class=" text-lg font-medium self-center">{$i18n.t('Admin Settings')}</div>
-			<button
-				class="self-center"
-				on:click={() => {
-					show = false;
-				}}
-			>
-				<svg
-					xmlns="http://www.w3.org/2000/svg"
-					viewBox="0 0 20 20"
-					fill="currentColor"
-					class="w-5 h-5"
-				>
-					<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>
-</Modal>

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

@@ -127,6 +127,42 @@
 	}
 	}
 
 
 	onMount(async () => {
 	onMount(async () => {
+		const onMessageHandler = async (event) => {
+			if (event.origin === window.origin) {
+				// Replace with your iframe's origin
+				console.log('Message received from iframe:', event.data);
+				if (event.data.type === 'input:prompt') {
+					console.log(event.data.text);
+
+					const inputElement = document.getElementById('chat-textarea');
+
+					if (inputElement) {
+						prompt = event.data.text;
+						inputElement.focus();
+					}
+				}
+
+				if (event.data.type === 'action:submit') {
+					console.log(event.data.text);
+
+					if (prompt !== '') {
+						await tick();
+						submitPrompt(prompt);
+					}
+				}
+
+				if (event.data.type === 'input:prompt:submit') {
+					console.log(event.data.text);
+
+					if (prompt !== '') {
+						await tick();
+						submitPrompt(event.data.text);
+					}
+				}
+			}
+		};
+		window.addEventListener('message', onMessageHandler);
+
 		if (!$chatId) {
 		if (!$chatId) {
 			chatId.subscribe(async (value) => {
 			chatId.subscribe(async (value) => {
 				if (!value) {
 				if (!value) {
@@ -138,6 +174,10 @@
 				await goto('/');
 				await goto('/');
 			}
 			}
 		}
 		}
+
+		return () => {
+			window.removeEventListener('message', onMessageHandler);
+		};
 	});
 	});
 
 
 	//////////////////////////
 	//////////////////////////
@@ -600,10 +640,14 @@
 			files = model.info.meta.knowledge;
 			files = model.info.meta.knowledge;
 		}
 		}
 		const lastUserMessage = messages.filter((message) => message.role === 'user').at(-1);
 		const lastUserMessage = messages.filter((message) => message.role === 'user').at(-1);
+
 		files = [
 		files = [
 			...files,
 			...files,
 			...(lastUserMessage?.files?.filter((item) =>
 			...(lastUserMessage?.files?.filter((item) =>
 				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
 				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
+			) ?? []),
+			...(responseMessage?.files?.filter((item) =>
+				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
 			) ?? [])
 			) ?? [])
 		].filter(
 		].filter(
 			// Remove duplicates
 			// Remove duplicates
@@ -844,6 +888,9 @@
 			...files,
 			...files,
 			...(lastUserMessage?.files?.filter((item) =>
 			...(lastUserMessage?.files?.filter((item) =>
 				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
 				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
+			) ?? []),
+			...(responseMessage?.files?.filter((item) =>
+				['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
 			) ?? [])
 			) ?? [])
 		].filter(
 		].filter(
 			// Remove duplicates
 			// Remove duplicates
@@ -1213,6 +1260,7 @@
 
 
 	const getWebSearchResults = async (model: string, parentId: string, responseId: string) => {
 	const getWebSearchResults = async (model: string, parentId: string, responseId: string) => {
 		const responseMessage = history.messages[responseId];
 		const responseMessage = history.messages[responseId];
+		const userMessage = history.messages[parentId];
 
 
 		responseMessage.statusHistory = [
 		responseMessage.statusHistory = [
 			{
 			{
@@ -1223,7 +1271,7 @@
 		];
 		];
 		messages = messages;
 		messages = messages;
 
 
-		const prompt = history.messages[parentId].content;
+		const prompt = userMessage.content;
 		let searchQuery = await generateSearchQuery(localStorage.token, model, messages, prompt).catch(
 		let searchQuery = await generateSearchQuery(localStorage.token, model, messages, prompt).catch(
 			(error) => {
 			(error) => {
 				console.log(error);
 				console.log(error);

+ 4 - 2
src/lib/components/chat/MessageInput.svelte

@@ -321,9 +321,11 @@
 		<div class="flex flex-col max-w-6xl px-2.5 md:px-6 w-full">
 		<div class="flex flex-col max-w-6xl px-2.5 md:px-6 w-full">
 			<div class="relative">
 			<div class="relative">
 				{#if autoScroll === false && messages.length > 0}
 				{#if autoScroll === false && messages.length > 0}
-					<div class=" absolute -top-12 left-0 right-0 flex justify-center z-30">
+					<div
+						class=" absolute -top-12 left-0 right-0 flex justify-center z-30 pointer-events-none"
+					>
 						<button
 						<button
-							class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
+							class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full pointer-events-auto"
 							on:click={() => {
 							on:click={() => {
 								autoScroll = true;
 								autoScroll = true;
 								scrollToBottom();
 								scrollToBottom();

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

@@ -271,7 +271,7 @@
 					return;
 					return;
 				}
 				}
 
 
-				if (assistantSpeaking) {
+				if (assistantSpeaking && !($settings?.voiceInterruption ?? false)) {
 					// Mute the audio if the assistant is speaking
 					// Mute the audio if the assistant is speaking
 					analyser.maxDecibels = 0;
 					analyser.maxDecibels = 0;
 					analyser.minDecibels = -1;
 					analyser.minDecibels = -1;

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

@@ -33,7 +33,7 @@
 </script>
 </script>
 
 
 {#key mounted}
 {#key mounted}
-	<div class="m-auto w-full max-w-6xl px-8 lg:px-24 pb-10">
+	<div class="m-auto w-full max-w-6xl px-8 lg:px-20 pb-10">
 		<div class="flex justify-start">
 		<div class="flex justify-start">
 			<div class="flex -space-x-4 mb-1" in:fade={{ duration: 200 }}>
 			<div class="flex -space-x-4 mb-1" in:fade={{ duration: 200 }}>
 				{#each models as model, modelIdx}
 				{#each models as model, modelIdx}

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

@@ -32,6 +32,7 @@
 	let chatDirection: 'LTR' | 'RTL' = 'LTR';
 	let chatDirection: 'LTR' | 'RTL' = 'LTR';
 
 
 	let showEmojiInCall = false;
 	let showEmojiInCall = false;
+	let voiceInterruption = false;
 
 
 	const toggleSplitLargeChunks = async () => {
 	const toggleSplitLargeChunks = async () => {
 		splitLargeChunks = !splitLargeChunks;
 		splitLargeChunks = !splitLargeChunks;
@@ -58,6 +59,11 @@
 		saveSettings({ showEmojiInCall: showEmojiInCall });
 		saveSettings({ showEmojiInCall: showEmojiInCall });
 	};
 	};
 
 
+	const toggleVoiceInterruption = async () => {
+		voiceInterruption = !voiceInterruption;
+		saveSettings({ voiceInterruption: voiceInterruption });
+	};
+
 	const toggleUserLocation = async () => {
 	const toggleUserLocation = async () => {
 		userLocation = !userLocation;
 		userLocation = !userLocation;
 
 
@@ -128,6 +134,7 @@
 		showUsername = $settings.showUsername ?? false;
 		showUsername = $settings.showUsername ?? false;
 
 
 		showEmojiInCall = $settings.showEmojiInCall ?? false;
 		showEmojiInCall = $settings.showEmojiInCall ?? false;
+		voiceInterruption = $settings.voiceInterruption ?? false;
 
 
 		chatBubble = $settings.chatBubble ?? true;
 		chatBubble = $settings.chatBubble ?? true;
 		widescreenMode = $settings.widescreenMode ?? false;
 		widescreenMode = $settings.widescreenMode ?? false;
@@ -399,6 +406,26 @@
 
 
 			<div class=" my-1.5 text-sm font-medium">{$i18n.t('Voice')}</div>
 			<div class=" my-1.5 text-sm font-medium">{$i18n.t('Voice')}</div>
 
 
+			<div>
+				<div class=" py-0.5 flex w-full justify-between">
+					<div class=" self-center text-xs">{$i18n.t('Allow Voice Interruption in Call')}</div>
+
+					<button
+						class="p-1 px-3 text-xs flex rounded transition"
+						on:click={() => {
+							toggleVoiceInterruption();
+						}}
+						type="button"
+					>
+						{#if voiceInterruption === 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>
 			<div>
 				<div class=" py-0.5 flex w-full justify-between">
 				<div class=" py-0.5 flex w-full justify-between">
 					<div class=" self-center text-xs">{$i18n.t('Display Emoji in Call')}</div>
 					<div class=" self-center text-xs">{$i18n.t('Display Emoji in Call')}</div>

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

@@ -31,7 +31,7 @@
 		dispatch('save');
 		dispatch('save');
 	}}
 	}}
 >
 >
-	<div class="  pr-1.5 overflow-y-scroll max-h-[25rem]">
+	<div class="  pr-1.5 py-1 overflow-y-scroll max-h-[25rem]">
 		<div>
 		<div>
 			<div class="flex items-center justify-between mb-1">
 			<div class="flex items-center justify-between mb-1">
 				<Tooltip
 				<Tooltip
@@ -46,7 +46,7 @@
 					</div>
 					</div>
 				</Tooltip>
 				</Tooltip>
 
 
-				<div class="mt-1">
+				<div class="">
 					<Switch
 					<Switch
 						bind:state={enableMemory}
 						bind:state={enableMemory}
 						on:change={async () => {
 						on:change={async () => {

+ 245 - 0
src/lib/components/chat/Settings/Valves.svelte

@@ -0,0 +1,245 @@
+<script lang="ts">
+	import { toast } from 'svelte-sonner';
+
+	import { config, functions, models, settings, tools, user } from '$lib/stores';
+	import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
+
+	import {
+		getUserValvesSpecById as getToolUserValvesSpecById,
+		getUserValvesById as getToolUserValvesById,
+		updateUserValvesById as updateToolUserValvesById
+	} from '$lib/apis/tools';
+	import {
+		getUserValvesSpecById as getFunctionUserValvesSpecById,
+		getUserValvesById as getFunctionUserValvesById,
+		updateUserValvesById as updateFunctionUserValvesById
+	} from '$lib/apis/functions';
+
+	import ManageModal from './Personalization/ManageModal.svelte';
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Spinner from '$lib/components/common/Spinner.svelte';
+
+	const dispatch = createEventDispatcher();
+
+	const i18n = getContext('i18n');
+
+	export let saveSettings: Function;
+
+	let tab = 'tools';
+	let selectedId = '';
+
+	let loading = false;
+
+	let valvesSpec = null;
+	let valves = {};
+
+	const getUserValves = async () => {
+		loading = true;
+		if (tab === 'tools') {
+			valves = await getToolUserValvesById(localStorage.token, selectedId);
+			valvesSpec = await getToolUserValvesSpecById(localStorage.token, selectedId);
+		} else if (tab === 'functions') {
+			valves = await getFunctionUserValvesById(localStorage.token, selectedId);
+			valvesSpec = await getFunctionUserValvesSpecById(localStorage.token, selectedId);
+		}
+
+		if (valvesSpec) {
+			// Convert array to string
+			for (const property in valvesSpec.properties) {
+				if (valvesSpec.properties[property]?.type === 'array') {
+					valves[property] = (valves[property] ?? []).join(',');
+				}
+			}
+		}
+
+		loading = false;
+	};
+
+	const submitHandler = async () => {
+		if (valvesSpec) {
+			// Convert string to array
+			for (const property in valvesSpec.properties) {
+				if (valvesSpec.properties[property]?.type === 'array') {
+					valves[property] = (valves[property] ?? '').split(',').map((v) => v.trim());
+				}
+			}
+
+			if (tab === 'tools') {
+				const res = await updateToolUserValvesById(localStorage.token, selectedId, valves).catch(
+					(error) => {
+						toast.error(error);
+						return null;
+					}
+				);
+
+				if (res) {
+					toast.success('Valves updated');
+					valves = res;
+				}
+			} else if (tab === 'functions') {
+				const res = await updateFunctionUserValvesById(
+					localStorage.token,
+					selectedId,
+					valves
+				).catch((error) => {
+					toast.error(error);
+					return null;
+				});
+
+				if (res) {
+					toast.success('Valves updated');
+					valves = res;
+				}
+			}
+		}
+	};
+
+	$: if (tab) {
+		selectedId = '';
+	}
+
+	$: if (selectedId) {
+		getUserValves();
+	}
+</script>
+
+<form
+	class="flex flex-col h-full justify-between space-y-3 text-sm"
+	on:submit|preventDefault={() => {
+		submitHandler();
+		dispatch('save');
+	}}
+>
+	<div class="flex flex-col pr-1.5 overflow-y-scroll max-h-[25rem]">
+		<div>
+			<div class="flex items-center justify-between mb-2">
+				<Tooltip content="">
+					<div class="text-sm font-medium">
+						{$i18n.t('Manage Valves')}
+					</div>
+				</Tooltip>
+
+				<div class=" self-end">
+					<select
+						class=" dark:bg-gray-900 w-fit pr-8 rounded text-xs bg-transparent outline-none text-right"
+						bind:value={tab}
+						placeholder="Select"
+					>
+						<option value="tools">{$i18n.t('Tools')}</option>
+						<option value="functions">{$i18n.t('Functions')}</option>
+					</select>
+				</div>
+			</div>
+		</div>
+
+		<div class="space-y-1">
+			<div class="flex gap-2">
+				<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={selectedId}
+						on:change={async () => {
+							await tick();
+						}}
+					>
+						{#if tab === 'tools'}
+							<option value="" selected disabled class="bg-gray-100 dark:bg-gray-700"
+								>{$i18n.t('Select a tool')}</option
+							>
+
+							{#each $tools as tool, toolIdx}
+								<option value={tool.id} class="bg-gray-100 dark:bg-gray-700">{tool.name}</option>
+							{/each}
+						{:else if tab === 'functions'}
+							<option value="" selected disabled class="bg-gray-100 dark:bg-gray-700"
+								>{$i18n.t('Select a function')}</option
+							>
+
+							{#each $functions as func, funcIdx}
+								<option value={func.id} class="bg-gray-100 dark:bg-700">{func.name}</option>
+							{/each}
+						{/if}
+					</select>
+				</div>
+			</div>
+		</div>
+
+		{#if selectedId}
+			<hr class="dark:border-gray-800 my-3 w-full" />
+
+			<div>
+				{#if !loading}
+					{#if valvesSpec}
+						{#each Object.keys(valvesSpec.properties) as property, idx}
+							<div class=" py-0.5 w-full justify-between">
+								<div class="flex w-full justify-between">
+									<div class=" self-center text-xs font-medium">
+										{valvesSpec.properties[property].title}
+
+										{#if (valvesSpec?.required ?? []).includes(property)}
+											<span class=" text-gray-500">*required</span>
+										{/if}
+									</div>
+
+									<button
+										class="p-1 px-3 text-xs flex rounded transition"
+										type="button"
+										on:click={() => {
+											valves[property] = (valves[property] ?? null) === null ? '' : null;
+										}}
+									>
+										{#if (valves[property] ?? null) === null}
+											<span class="ml-2 self-center">
+												{#if (valvesSpec?.required ?? []).includes(property)}
+													{$i18n.t('None')}
+												{:else}
+													{$i18n.t('Default')}
+												{/if}
+											</span>
+										{:else}
+											<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
+										{/if}
+									</button>
+								</div>
+
+								{#if (valves[property] ?? null) !== null}
+									<div class="flex mt-0.5 mb-1.5 space-x-2">
+										<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={valvesSpec.properties[property].title}
+												bind:value={valves[property]}
+												autocomplete="off"
+												required
+											/>
+										</div>
+									</div>
+								{/if}
+
+								{#if (valvesSpec.properties[property]?.description ?? null) !== null}
+									<div class="text-xs text-gray-500">
+										{valvesSpec.properties[property].description}
+									</div>
+								{/if}
+							</div>
+						{/each}
+					{:else}
+						<div>No valves</div>
+					{/if}
+				{:else}
+					<Spinner className="size-5" />
+				{/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>

+ 48 - 16
src/lib/components/chat/SettingsModal.svelte

@@ -16,6 +16,7 @@
 	import Personalization from './Settings/Personalization.svelte';
 	import Personalization from './Settings/Personalization.svelte';
 	import { updateUserSettings } from '$lib/apis/users';
 	import { updateUserSettings } from '$lib/apis/users';
 	import { goto } from '$app/navigation';
 	import { goto } from '$app/navigation';
+	import Valves from './Settings/Valves.svelte';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
@@ -65,8 +66,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'general'
 					'general'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'general';
 						selectedTab = 'general';
 					}}
 					}}
@@ -91,8 +92,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'interface'
 					'interface'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'interface';
 						selectedTab = 'interface';
 					}}
 					}}
@@ -117,8 +118,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'personalization'
 					'personalization'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'personalization';
 						selectedTab = 'personalization';
 					}}
 					}}
@@ -132,8 +133,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'audio'
 					'audio'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'audio';
 						selectedTab = 'audio';
 					}}
 					}}
@@ -156,11 +157,35 @@
 					<div class=" self-center">{$i18n.t('Audio')}</div>
 					<div class=" self-center">{$i18n.t('Audio')}</div>
 				</button>
 				</button>
 
 
+				<button
+					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
+					'valves'
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
+					on:click={() => {
+						selectedTab = 'valves';
+					}}
+				>
+					<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="M18.75 12.75h1.5a.75.75 0 0 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM12 6a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 6ZM12 18a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 18ZM3.75 6.75h1.5a.75.75 0 1 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM5.25 18.75h-1.5a.75.75 0 0 1 0-1.5h1.5a.75.75 0 0 1 0 1.5ZM3 12a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 3 12ZM9 3.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5ZM12.75 12a2.25 2.25 0 1 1 4.5 0 2.25 2.25 0 0 1-4.5 0ZM9 15.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"
+							/>
+						</svg>
+					</div>
+					<div class=" self-center">{$i18n.t('Valves')}</div>
+				</button>
+
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'chats'
 					'chats'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'chats';
 						selectedTab = 'chats';
 					}}
 					}}
@@ -185,8 +210,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'account'
 					'account'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'account';
 						selectedTab = 'account';
 					}}
 					}}
@@ -212,8 +237,8 @@
 					<button
 					<button
 						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 						class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 						'admin'
 						'admin'
-							? 'bg-gray-200 dark:bg-gray-700'
-							: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+							? 'bg-gray-200 dark:bg-gray-800'
+							: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 						on:click={async () => {
 						on:click={async () => {
 							await goto('/admin/settings');
 							await goto('/admin/settings');
 							show = false;
 							show = false;
@@ -240,8 +265,8 @@
 				<button
 				<button
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
 					'about'
 					'about'
-						? 'bg-gray-200 dark:bg-gray-700'
-						: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
+						? 'bg-gray-200 dark:bg-gray-800'
+						: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
 					on:click={() => {
 					on:click={() => {
 						selectedTab = 'about';
 						selectedTab = 'about';
 					}}
 					}}
@@ -293,6 +318,13 @@
 							toast.success($i18n.t('Settings saved successfully!'));
 							toast.success($i18n.t('Settings saved successfully!'));
 						}}
 						}}
 					/>
 					/>
+				{:else if selectedTab === 'valves'}
+					<Valves
+						{saveSettings}
+						on:save={() => {
+							toast.success($i18n.t('Settings saved successfully!'));
+						}}
+					/>
 				{:else if selectedTab === 'chats'}
 				{:else if selectedTab === 'chats'}
 					<Chats {saveSettings} />
 					<Chats {saveSettings} />
 				{:else if selectedTab === 'account'}
 				{:else if selectedTab === 'account'}

+ 19 - 0
src/lib/components/icons/Heart.svelte

@@ -0,0 +1,19 @@
+<script lang="ts">
+	export let className = 'size-4';
+	export let strokeWidth = '1.5';
+</script>
+
+<svg
+	xmlns="http://www.w3.org/2000/svg"
+	fill="none"
+	viewBox="0 0 24 24"
+	stroke-width={strokeWidth}
+	stroke="currentColor"
+	class={className}
+>
+	<path
+		stroke-linecap="round"
+		stroke-linejoin="round"
+		d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"
+	/>
+</svg>

+ 0 - 0
src/lib/components/workspace/Playground.svelte → src/lib/components/playground/Playground.svelte


+ 6 - 2
src/lib/components/workspace/Documents.svelte

@@ -538,7 +538,9 @@
 				documentsImportInputElement.click();
 				documentsImportInputElement.click();
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Import Documents Mapping')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">
+				{$i18n.t('Import Documents Mapping')}
+			</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -565,7 +567,9 @@
 				saveAs(blob, `documents-mapping-export-${Date.now()}.json`);
 				saveAs(blob, `documents-mapping-export-${Date.now()}.json`);
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Export Documents Mapping')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">
+				{$i18n.t('Export Documents Mapping')}
+			</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg

+ 172 - 118
src/lib/components/workspace/Functions.svelte

@@ -13,13 +13,20 @@
 		deleteFunctionById,
 		deleteFunctionById,
 		exportFunctions,
 		exportFunctions,
 		getFunctionById,
 		getFunctionById,
-		getFunctions
+		getFunctions,
+		toggleFunctionById
 	} from '$lib/apis/functions';
 	} from '$lib/apis/functions';
 
 
 	import ArrowDownTray from '../icons/ArrowDownTray.svelte';
 	import ArrowDownTray from '../icons/ArrowDownTray.svelte';
 	import Tooltip from '../common/Tooltip.svelte';
 	import Tooltip from '../common/Tooltip.svelte';
 	import ConfirmDialog from '../common/ConfirmDialog.svelte';
 	import ConfirmDialog from '../common/ConfirmDialog.svelte';
 	import { getModels } from '$lib/apis';
 	import { getModels } from '$lib/apis';
+	import FunctionMenu from './Functions/FunctionMenu.svelte';
+	import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
+	import Switch from '../common/Switch.svelte';
+	import ValvesModal from './common/ValvesModal.svelte';
+	import ManifestModal from './common/ManifestModal.svelte';
+	import Heart from '../icons/Heart.svelte';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
@@ -28,6 +35,58 @@
 
 
 	let showConfirm = false;
 	let showConfirm = false;
 	let query = '';
 	let query = '';
+
+	let showManifestModal = false;
+	let showValvesModal = false;
+	let selectedFunction = null;
+
+	const shareHandler = async (tool) => {
+		console.log(tool);
+	};
+
+	const cloneHandler = async (func) => {
+		const _function = await getFunctionById(localStorage.token, func.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (_function) {
+			sessionStorage.function = JSON.stringify({
+				..._function,
+				id: `${_function.id}_clone`,
+				name: `${_function.name} (Clone)`
+			});
+			goto('/workspace/functions/create');
+		}
+	};
+
+	const exportHandler = async (func) => {
+		const _function = await getFunctionById(localStorage.token, func.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (_function) {
+			let blob = new Blob([JSON.stringify([_function])], {
+				type: 'application/json'
+			});
+			saveAs(blob, `function-${_function.id}-export-${Date.now()}.json`);
+		}
+	};
+
+	const deleteHandler = async (func) => {
+		const res = await deleteFunctionById(localStorage.token, func.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res) {
+			toast.success('Function deleted successfully');
+
+			functions.set(await getFunctions(localStorage.token));
+			models.set(await getModels(localStorage.token));
+		}
+	};
 </script>
 </script>
 
 
 <svelte:head>
 <svelte:head>
@@ -87,18 +146,14 @@
 	{#each $functions.filter((f) => query === '' || f.name
 	{#each $functions.filter((f) => query === '' || f.name
 				.toLowerCase()
 				.toLowerCase()
 				.includes(query.toLowerCase()) || f.id.toLowerCase().includes(query.toLowerCase())) as func}
 				.includes(query.toLowerCase()) || f.id.toLowerCase().includes(query.toLowerCase())) as func}
-		<button
+		<div
 			class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
 			class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
-			type="button"
-			on:click={() => {
-				goto(`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`);
-			}}
 		>
 		>
-			<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
-				<a
-					href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
-					class="flex items-center text-left"
-				>
+			<a
+				class=" flex flex-1 space-x-3.5 cursor-pointer w-full"
+				href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
+			>
+				<div class="flex items-center text-left">
 					<div class=" flex-1 self-center pl-1">
 					<div class=" flex-1 self-center pl-1">
 						<div class=" font-semibold flex items-center gap-1.5">
 						<div class=" font-semibold flex items-center gap-1.5">
 							<div
 							<div
@@ -107,67 +162,52 @@
 								{func.type}
 								{func.type}
 							</div>
 							</div>
 
 
-							<div>
+							{#if func?.meta?.manifest?.version}
+								<div
+									class="text-xs font-black px-1 rounded line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200"
+								>
+									v{func?.meta?.manifest?.version ?? ''}
+								</div>
+							{/if}
+
+							<div class=" line-clamp-1">
 								{func.name}
 								{func.name}
 							</div>
 							</div>
 						</div>
 						</div>
 
 
 						<div class="flex gap-1.5 px-1">
 						<div class="flex gap-1.5 px-1">
-							<div class=" text-gray-500 text-xs font-medium">{func.id}</div>
+							<div class=" text-gray-500 text-xs font-medium flex-shrink-0">{func.id}</div>
 
 
 							<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 							<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 								{func.meta.description}
 								{func.meta.description}
 							</div>
 							</div>
 						</div>
 						</div>
 					</div>
 					</div>
-				</a>
-			</div>
-			<div class="flex flex-row space-x-1 self-center">
-				<Tooltip content="Edit">
-					<a
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-						type="button"
-						href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
-					>
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							fill="none"
-							viewBox="0 0 24 24"
-							stroke-width="1.5"
-							stroke="currentColor"
-							class="w-4 h-4"
+				</div>
+			</a>
+			<div class="flex flex-row gap-0.5 self-center">
+				{#if func?.meta?.manifest?.funding_url ?? false}
+					<Tooltip content="Support">
+						<button
+							class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
+							type="button"
+							on:click={() => {
+								selectedFunction = func;
+								showManifestModal = true;
+							}}
 						>
 						>
-							<path
-								stroke-linecap="round"
-								stroke-linejoin="round"
-								d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
-							/>
-						</svg>
-					</a>
-				</Tooltip>
+							<Heart />
+						</button>
+					</Tooltip>
+				{/if}
 
 
-				<Tooltip content="Clone">
+				<Tooltip content="Valves">
 					<button
 					<button
 						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						type="button"
 						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const _function = await getFunctionById(localStorage.token, func.id).catch(
-								(error) => {
-									toast.error(error);
-									return null;
-								}
-							);
-
-							if (_function) {
-								sessionStorage.function = JSON.stringify({
-									..._function,
-									id: `${_function.id}_clone`,
-									name: `${_function.name} (Clone)`
-								});
-								goto('/workspace/functions/create');
-							}
+						on:click={() => {
+							selectedFunction = func;
+							showValvesModal = true;
 						}}
 						}}
 					>
 					>
 						<svg
 						<svg
@@ -176,81 +216,59 @@
 							viewBox="0 0 24 24"
 							viewBox="0 0 24 24"
 							stroke-width="1.5"
 							stroke-width="1.5"
 							stroke="currentColor"
 							stroke="currentColor"
-							class="w-4 h-4"
+							class="size-4"
 						>
 						>
 							<path
 							<path
 								stroke-linecap="round"
 								stroke-linecap="round"
 								stroke-linejoin="round"
 								stroke-linejoin="round"
-								d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
+								d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
 							/>
 							/>
 						</svg>
 						</svg>
 					</button>
 					</button>
 				</Tooltip>
 				</Tooltip>
 
 
-				<Tooltip content="Export">
+				<FunctionMenu
+					editHandler={() => {
+						goto(`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`);
+					}}
+					shareHandler={() => {
+						shareHandler(func);
+					}}
+					cloneHandler={() => {
+						cloneHandler(func);
+					}}
+					exportHandler={() => {
+						exportHandler(func);
+					}}
+					deleteHandler={async () => {
+						deleteHandler(func);
+					}}
+					onClose={() => {}}
+				>
 					<button
 					<button
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
+						class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						type="button"
 						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const _function = await getFunctionById(localStorage.token, func.id).catch(
-								(error) => {
-									toast.error(error);
-									return null;
-								}
-							);
-
-							if (_function) {
-								let blob = new Blob([JSON.stringify([_function])], {
-									type: 'application/json'
-								});
-								saveAs(blob, `function-${_function.id}-export-${Date.now()}.json`);
-							}
-						}}
 					>
 					>
-						<ArrowDownTray />
+						<EllipsisHorizontal className="size-5" />
 					</button>
 					</button>
-				</Tooltip>
-
-				<Tooltip content="Delete">
-					<button
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const res = await deleteFunctionById(localStorage.token, func.id).catch((error) => {
-								toast.error(error);
-								return null;
-							});
-
-							if (res) {
-								toast.success('Function deleted successfully');
-
-								functions.set(await getFunctions(localStorage.token));
-								models.set(await getModels(localStorage.token));
-							}
+				</FunctionMenu>
+
+				<div class=" self-center mx-1">
+					<Switch
+						bind:state={func.is_active}
+						on:change={async (e) => {
+							toggleFunctionById(localStorage.token, func.id);
+							models.set(await getModels(localStorage.token));
 						}}
 						}}
-					>
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							fill="none"
-							viewBox="0 0 24 24"
-							stroke-width="1.5"
-							stroke="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								stroke-linecap="round"
-								stroke-linejoin="round"
-								d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
-							/>
-						</svg>
-					</button>
-				</Tooltip>
+					/>
+				</div>
 			</div>
 			</div>
-		</button>
+		</div>
 	{/each}
 	{/each}
 </div>
 </div>
 
 
@@ -281,7 +299,7 @@
 				functionsImportInputElement.click();
 				functionsImportInputElement.click();
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Import Functions')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Functions')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -315,7 +333,7 @@
 				}
 				}
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Export Functions')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Functions')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -335,6 +353,42 @@
 	</div>
 	</div>
 </div>
 </div>
 
 
+<div class=" my-16">
+	<div class=" text-lg font-semibold mb-3 line-clamp-1">
+		{$i18n.t('Made by OpenWebUI Community')}
+	</div>
+
+	<a
+		class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
+		href="https://openwebui.com/"
+		target="_blank"
+	>
+		<div class=" self-center w-10 flex-shrink-0">
+			<div
+				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
+			>
+				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6">
+					<path
+						fill-rule="evenodd"
+						d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+		</div>
+
+		<div class=" self-center">
+			<div class=" font-bold line-clamp-1">{$i18n.t('Discover a function')}</div>
+			<div class=" text-sm line-clamp-1">
+				{$i18n.t('Discover, download, and explore custom functions')}
+			</div>
+		</div>
+	</a>
+</div>
+
+<ManifestModal bind:show={showManifestModal} manifest={selectedFunction?.meta?.manifest ?? {}} />
+<ValvesModal bind:show={showValvesModal} type="function" id={selectedFunction?.id ?? null} />
+
 <ConfirmDialog
 <ConfirmDialog
 	bind:show={showConfirm}
 	bind:show={showConfirm}
 	on:confirm={() => {
 	on:confirm={() => {

+ 117 - 0
src/lib/components/workspace/Functions/FunctionMenu.svelte

@@ -0,0 +1,117 @@
+<script lang="ts">
+	import { DropdownMenu } from 'bits-ui';
+	import { flyAndScale } from '$lib/utils/transitions';
+	import { getContext } from 'svelte';
+
+	import Dropdown from '$lib/components/common/Dropdown.svelte';
+	import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
+	import Pencil from '$lib/components/icons/Pencil.svelte';
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Tags from '$lib/components/chat/Tags.svelte';
+	import Share from '$lib/components/icons/Share.svelte';
+	import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
+	import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
+	import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
+
+	const i18n = getContext('i18n');
+
+	export let editHandler: Function;
+	export let shareHandler: Function;
+	export let cloneHandler: Function;
+	export let exportHandler: Function;
+	export let deleteHandler: Function;
+	export let onClose: Function;
+
+	let show = false;
+</script>
+
+<Dropdown
+	bind:show
+	on:change={(e) => {
+		if (e.detail === false) {
+			onClose();
+		}
+	}}
+>
+	<Tooltip content={$i18n.t('More')}>
+		<slot />
+	</Tooltip>
+
+	<div slot="content">
+		<DropdownMenu.Content
+			class="w-full max-w-[160px] rounded-xl 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"
+			sideOffset={-2}
+			side="bottom"
+			align="start"
+			transition={flyAndScale}
+		>
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800  rounded-md"
+				on:click={() => {
+					editHandler();
+				}}
+			>
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					fill="none"
+					viewBox="0 0 24 24"
+					stroke-width="1.5"
+					stroke="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						stroke-linecap="round"
+						stroke-linejoin="round"
+						d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
+					/>
+				</svg>
+
+				<div class="flex items-center">{$i18n.t('Edit')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800  rounded-md"
+				on:click={() => {
+					shareHandler();
+				}}
+			>
+				<Share />
+				<div class="flex items-center">{$i18n.t('Share')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					cloneHandler();
+				}}
+			>
+				<DocumentDuplicate />
+
+				<div class="flex items-center">{$i18n.t('Clone')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					exportHandler();
+				}}
+			>
+				<ArrowDownTray />
+
+				<div class="flex items-center">{$i18n.t('Export')}</div>
+			</DropdownMenu.Item>
+
+			<hr class="border-gray-100 dark:border-gray-800 my-1" />
+
+			<DropdownMenu.Item
+				class="flex  gap-2  items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					deleteHandler();
+				}}
+			>
+				<GarbageBin strokeWidth="2" />
+				<div class="flex items-center">{$i18n.t('Delete')}</div>
+			</DropdownMenu.Item>
+		</DropdownMenu.Content>
+	</div>
+</Dropdown>

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

@@ -256,7 +256,7 @@
 <hr class=" dark:border-gray-850 my-2.5" />
 <hr class=" dark:border-gray-850 my-2.5" />
 
 
 <a class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2" href="/workspace/models/create">
 <a class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2" href="/workspace/models/create">
-	<div class=" self-center w-10">
+	<div class=" self-center w-10 flex-shrink-0">
 		<div
 		<div
 			class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 			class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 		>
 		>
@@ -271,8 +271,8 @@
 	</div>
 	</div>
 
 
 	<div class=" self-center">
 	<div class=" self-center">
-		<div class=" font-bold">{$i18n.t('Create a model')}</div>
-		<div class=" text-sm">{$i18n.t('Customize models for a specific purpose')}</div>
+		<div class=" font-bold line-clamp-1">{$i18n.t('Create a model')}</div>
+		<div class=" text-sm line-clamp-1">{$i18n.t('Customize models for a specific purpose')}</div>
 	</div>
 	</div>
 </a>
 </a>
 
 
@@ -412,7 +412,7 @@
 				modelsImportInputElement.click();
 				modelsImportInputElement.click();
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Import Models')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Models')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -436,7 +436,7 @@
 				downloadModels($models);
 				downloadModels($models);
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Export Models')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Models')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -494,14 +494,16 @@
 </div>
 </div>
 
 
 <div class=" my-16">
 <div class=" my-16">
-	<div class=" text-lg font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
+	<div class=" text-lg font-semibold mb-3 line-clamp-1">
+		{$i18n.t('Made by OpenWebUI Community')}
+	</div>
 
 
 	<a
 	<a
 		class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
 		class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
 		href="https://openwebui.com/"
 		href="https://openwebui.com/"
 		target="_blank"
 		target="_blank"
 	>
 	>
-		<div class=" self-center w-10">
+		<div class=" self-center w-10 flex-shrink-0">
 			<div
 			<div
 				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 			>
 			>
@@ -516,8 +518,10 @@
 		</div>
 		</div>
 
 
 		<div class=" self-center">
 		<div class=" self-center">
-			<div class=" font-bold">{$i18n.t('Discover a model')}</div>
-			<div class=" text-sm">{$i18n.t('Discover, download, and explore model presets')}</div>
+			<div class=" font-bold line-clamp-1">{$i18n.t('Discover a model')}</div>
+			<div class=" text-sm line-clamp-1">
+				{$i18n.t('Discover, download, and explore model presets')}
+			</div>
 		</div>
 		</div>
 	</a>
 	</a>
 </div>
 </div>

+ 49 - 77
src/lib/components/workspace/Prompts.svelte

@@ -8,13 +8,16 @@
 	import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts';
 	import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts';
 	import { error } from '@sveltejs/kit';
 	import { error } from '@sveltejs/kit';
 	import { goto } from '$app/navigation';
 	import { goto } from '$app/navigation';
+	import PromptMenu from './Prompts/PromptMenu.svelte';
+	import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
 	let importFiles = '';
 	let importFiles = '';
 	let query = '';
 	let query = '';
 	let promptsImportInputElement: HTMLInputElement;
 	let promptsImportInputElement: HTMLInputElement;
-	const sharePrompt = async (prompt) => {
+
+	const shareHandler = async (prompt) => {
 		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
 		toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
 
 
 		const url = 'https://openwebui.com';
 		const url = 'https://openwebui.com';
@@ -32,7 +35,20 @@
 		);
 		);
 	};
 	};
 
 
-	const deletePrompt = async (command) => {
+	const cloneHandler = async (prompt) => {
+		sessionStorage.prompt = JSON.stringify(prompt);
+		goto('/workspace/prompts/create');
+	};
+
+	const exportHandler = async (prompt) => {
+		let blob = new Blob([JSON.stringify([prompt])], {
+			type: 'application/json'
+		});
+		saveAs(blob, `prompt-export-${Date.now()}.json`);
+	};
+
+	const deleteHandler = async (prompt) => {
+		const command = prompt.command;
 		await deletePromptByCommand(localStorage.token, command);
 		await deletePromptByCommand(localStorage.token, command);
 		await prompts.set(await getPrompts(localStorage.token));
 		await prompts.set(await getPrompts(localStorage.token));
 	};
 	};
@@ -99,14 +115,14 @@
 			<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
 			<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
 				<a href={`/workspace/prompts/edit?command=${encodeURIComponent(prompt.command)}`}>
 				<a href={`/workspace/prompts/edit?command=${encodeURIComponent(prompt.command)}`}>
 					<div class=" flex-1 self-center pl-5">
 					<div class=" flex-1 self-center pl-5">
-						<div class=" font-bold">{prompt.command}</div>
+						<div class=" font-bold line-clamp-1">{prompt.command}</div>
 						<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 						<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 							{prompt.title}
 							{prompt.title}
 						</div>
 						</div>
 					</div>
 					</div>
 				</a>
 				</a>
 			</div>
 			</div>
-			<div class="flex flex-row space-x-1 self-center">
+			<div class="flex flex-row gap-0.5 self-center">
 				<a
 				<a
 					class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 					class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 					type="button"
 					type="button"
@@ -128,76 +144,28 @@
 					</svg>
 					</svg>
 				</a>
 				</a>
 
 
-				<button
-					class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-					type="button"
-					on:click={() => {
-						// console.log(modelfile);
-						sessionStorage.prompt = JSON.stringify(prompt);
-						goto('/workspace/prompts/create');
+				<PromptMenu
+					shareHandler={() => {
+						shareHandler(prompt);
 					}}
 					}}
-				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						fill="none"
-						viewBox="0 0 24 24"
-						stroke-width="1.5"
-						stroke="currentColor"
-						class="w-4 h-4"
-					>
-						<path
-							stroke-linecap="round"
-							stroke-linejoin="round"
-							d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
-						/>
-					</svg>
-				</button>
-
-				<button
-					class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-					type="button"
-					on:click={() => {
-						sharePrompt(prompt);
+					cloneHandler={() => {
+						cloneHandler(prompt);
 					}}
 					}}
-				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						fill="none"
-						viewBox="0 0 24 24"
-						stroke-width="1.5"
-						stroke="currentColor"
-						class="w-4 h-4"
-					>
-						<path
-							stroke-linecap="round"
-							stroke-linejoin="round"
-							d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z"
-						/>
-					</svg>
-				</button>
-
-				<button
-					class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-					type="button"
-					on:click={() => {
-						deletePrompt(prompt.command);
+					exportHandler={() => {
+						exportHandler(prompt);
+					}}
+					deleteHandler={async () => {
+						deleteHandler(prompt);
 					}}
 					}}
+					onClose={() => {}}
 				>
 				>
-					<svg
-						xmlns="http://www.w3.org/2000/svg"
-						fill="none"
-						viewBox="0 0 24 24"
-						stroke-width="1.5"
-						stroke="currentColor"
-						class="w-4 h-4"
+					<button
+						class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
+						type="button"
 					>
 					>
-						<path
-							stroke-linecap="round"
-							stroke-linejoin="round"
-							d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
-						/>
-					</svg>
-				</button>
+						<EllipsisHorizontal className="size-5" />
+					</button>
+				</PromptMenu>
 			</div>
 			</div>
 		</div>
 		</div>
 	{/each}
 	{/each}
@@ -245,7 +213,7 @@
 				promptsImportInputElement.click();
 				promptsImportInputElement.click();
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Import Prompts')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Prompts')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -273,7 +241,7 @@
 				saveAs(blob, `prompts-export-${Date.now()}.json`);
 				saveAs(blob, `prompts-export-${Date.now()}.json`);
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Export Prompts')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Prompts')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -302,14 +270,16 @@
 </div>
 </div>
 
 
 <div class=" my-16">
 <div class=" my-16">
-	<div class=" text-lg font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
+	<div class=" text-lg font-semibold mb-3 line-clamp-1">
+		{$i18n.t('Made by OpenWebUI Community')}
+	</div>
 
 
 	<a
 	<a
-		class=" flex space-x-4 cursor-pointer w-full mb-3 px-3 py-2"
-		href="https://openwebui.com/?type=prompts"
+		class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
+		href="https://openwebui.com/"
 		target="_blank"
 		target="_blank"
 	>
 	>
-		<div class=" self-center w-10">
+		<div class=" self-center w-10 flex-shrink-0">
 			<div
 			<div
 				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
 			>
 			>
@@ -324,8 +294,10 @@
 		</div>
 		</div>
 
 
 		<div class=" self-center">
 		<div class=" self-center">
-			<div class=" font-bold">{$i18n.t('Discover a prompt')}</div>
-			<div class=" text-sm">{$i18n.t('Discover, download, and explore custom prompts')}</div>
+			<div class=" font-bold line-clamp-1">{$i18n.t('Discover a prompt')}</div>
+			<div class=" text-sm line-clamp-1">
+				{$i18n.t('Discover, download, and explore custom prompts')}
+			</div>
 		</div>
 		</div>
 	</a>
 	</a>
 </div>
 </div>

+ 92 - 0
src/lib/components/workspace/Prompts/PromptMenu.svelte

@@ -0,0 +1,92 @@
+<script lang="ts">
+	import { DropdownMenu } from 'bits-ui';
+	import { flyAndScale } from '$lib/utils/transitions';
+	import { getContext } from 'svelte';
+
+	import Dropdown from '$lib/components/common/Dropdown.svelte';
+	import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
+	import Pencil from '$lib/components/icons/Pencil.svelte';
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Tags from '$lib/components/chat/Tags.svelte';
+	import Share from '$lib/components/icons/Share.svelte';
+	import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
+	import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
+	import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
+
+	const i18n = getContext('i18n');
+
+	export let shareHandler: Function;
+	export let cloneHandler: Function;
+	export let exportHandler: Function;
+	export let deleteHandler: Function;
+	export let onClose: Function;
+
+	let show = false;
+</script>
+
+<Dropdown
+	bind:show
+	on:change={(e) => {
+		if (e.detail === false) {
+			onClose();
+		}
+	}}
+>
+	<Tooltip content={$i18n.t('More')}>
+		<slot />
+	</Tooltip>
+
+	<div slot="content">
+		<DropdownMenu.Content
+			class="w-full max-w-[160px] rounded-xl 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"
+			sideOffset={-2}
+			side="bottom"
+			align="start"
+			transition={flyAndScale}
+		>
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800  rounded-md"
+				on:click={() => {
+					shareHandler();
+				}}
+			>
+				<Share />
+				<div class="flex items-center">{$i18n.t('Share')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					cloneHandler();
+				}}
+			>
+				<DocumentDuplicate />
+
+				<div class="flex items-center">{$i18n.t('Clone')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					exportHandler();
+				}}
+			>
+				<ArrowDownTray />
+
+				<div class="flex items-center">{$i18n.t('Export')}</div>
+			</DropdownMenu.Item>
+
+			<hr class="border-gray-100 dark:border-gray-800 my-1" />
+
+			<DropdownMenu.Item
+				class="flex  gap-2  items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					deleteHandler();
+				}}
+			>
+				<GarbageBin strokeWidth="2" />
+				<div class="flex items-center">{$i18n.t('Delete')}</div>
+			</DropdownMenu.Item>
+		</DropdownMenu.Content>
+	</div>
+</Dropdown>

+ 158 - 112
src/lib/components/workspace/Tools.svelte

@@ -18,6 +18,11 @@
 	import ArrowDownTray from '../icons/ArrowDownTray.svelte';
 	import ArrowDownTray from '../icons/ArrowDownTray.svelte';
 	import Tooltip from '../common/Tooltip.svelte';
 	import Tooltip from '../common/Tooltip.svelte';
 	import ConfirmDialog from '../common/ConfirmDialog.svelte';
 	import ConfirmDialog from '../common/ConfirmDialog.svelte';
+	import ToolMenu from './Tools/ToolMenu.svelte';
+	import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
+	import ValvesModal from './common/ValvesModal.svelte';
+	import ManifestModal from './common/ManifestModal.svelte';
+	import Heart from '../icons/Heart.svelte';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
@@ -26,6 +31,56 @@
 
 
 	let showConfirm = false;
 	let showConfirm = false;
 	let query = '';
 	let query = '';
+
+	let showManifestModal = false;
+	let showValvesModal = false;
+	let selectedTool = null;
+
+	const shareHandler = async (tool) => {
+		console.log(tool);
+	};
+
+	const cloneHandler = async (tool) => {
+		const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (_tool) {
+			sessionStorage.tool = JSON.stringify({
+				..._tool,
+				id: `${_tool.id}_clone`,
+				name: `${_tool.name} (Clone)`
+			});
+			goto('/workspace/tools/create');
+		}
+	};
+
+	const exportHandler = async (tool) => {
+		const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (_tool) {
+			let blob = new Blob([JSON.stringify([_tool])], {
+				type: 'application/json'
+			});
+			saveAs(blob, `tool-${_tool.id}-export-${Date.now()}.json`);
+		}
+	};
+
+	const deleteHandler = async (tool) => {
+		const res = await deleteToolById(localStorage.token, tool.id).catch((error) => {
+			toast.error(error);
+			return null;
+		});
+
+		if (res) {
+			toast.success('Tool deleted successfully');
+			tools.set(await getTools(localStorage.token));
+		}
+	};
 </script>
 </script>
 
 
 <svelte:head>
 <svelte:head>
@@ -85,18 +140,14 @@
 	{#each $tools.filter((t) => query === '' || t.name
 	{#each $tools.filter((t) => query === '' || t.name
 				.toLowerCase()
 				.toLowerCase()
 				.includes(query.toLowerCase()) || t.id.toLowerCase().includes(query.toLowerCase())) as tool}
 				.includes(query.toLowerCase()) || t.id.toLowerCase().includes(query.toLowerCase())) as tool}
-		<button
+		<div
 			class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
 			class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
-			type="button"
-			on:click={() => {
-				goto(`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`);
-			}}
 		>
 		>
-			<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
-				<a
-					href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
-					class="flex items-center text-left"
-				>
+			<a
+				class=" flex flex-1 space-x-3.5 cursor-pointer w-full"
+				href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
+			>
+				<div class="flex items-center text-left">
 					<div class=" flex-1 self-center pl-1">
 					<div class=" flex-1 self-center pl-1">
 						<div class=" font-semibold flex items-center gap-1.5">
 						<div class=" font-semibold flex items-center gap-1.5">
 							<div
 							<div
@@ -105,65 +156,52 @@
 								TOOL
 								TOOL
 							</div>
 							</div>
 
 
-							<div>
+							{#if tool?.meta?.manifest?.version}
+								<div
+									class="text-xs font-black px-1 rounded line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200"
+								>
+									v{tool?.meta?.manifest?.version ?? ''}
+								</div>
+							{/if}
+
+							<div class="line-clamp-1">
 								{tool.name}
 								{tool.name}
 							</div>
 							</div>
 						</div>
 						</div>
 
 
 						<div class="flex gap-1.5 px-1">
 						<div class="flex gap-1.5 px-1">
-							<div class=" text-gray-500 text-xs font-medium">{tool.id}</div>
+							<div class=" text-gray-500 text-xs font-medium flex-shrink-0">{tool.id}</div>
 
 
 							<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 							<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
 								{tool.meta.description}
 								{tool.meta.description}
 							</div>
 							</div>
 						</div>
 						</div>
 					</div>
 					</div>
-				</a>
-			</div>
-			<div class="flex flex-row space-x-1 self-center">
-				<Tooltip content="Edit">
-					<a
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-						type="button"
-						href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
-					>
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							fill="none"
-							viewBox="0 0 24 24"
-							stroke-width="1.5"
-							stroke="currentColor"
-							class="w-4 h-4"
+				</div>
+			</a>
+			<div class="flex flex-row gap-0.5 self-center">
+				{#if tool?.meta?.manifest?.funding_url ?? false}
+					<Tooltip content="Support">
+						<button
+							class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
+							type="button"
+							on:click={() => {
+								selectedTool = tool;
+								showManifestModal = true;
+							}}
 						>
 						>
-							<path
-								stroke-linecap="round"
-								stroke-linejoin="round"
-								d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
-							/>
-						</svg>
-					</a>
-				</Tooltip>
+							<Heart />
+						</button>
+					</Tooltip>
+				{/if}
 
 
-				<Tooltip content="Clone">
+				<Tooltip content="Valves">
 					<button
 					<button
 						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						type="button"
 						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
-								toast.error(error);
-								return null;
-							});
-
-							if (_tool) {
-								sessionStorage.tool = JSON.stringify({
-									..._tool,
-									id: `${_tool.id}_clone`,
-									name: `${_tool.name} (Clone)`
-								});
-								goto('/workspace/tools/create');
-							}
+						on:click={() => {
+							selectedTool = tool;
+							showValvesModal = true;
 						}}
 						}}
 					>
 					>
 						<svg
 						<svg
@@ -172,77 +210,49 @@
 							viewBox="0 0 24 24"
 							viewBox="0 0 24 24"
 							stroke-width="1.5"
 							stroke-width="1.5"
 							stroke="currentColor"
 							stroke="currentColor"
-							class="w-4 h-4"
+							class="size-4"
 						>
 						>
 							<path
 							<path
 								stroke-linecap="round"
 								stroke-linecap="round"
 								stroke-linejoin="round"
 								stroke-linejoin="round"
-								d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
+								d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
 							/>
 							/>
 						</svg>
 						</svg>
 					</button>
 					</button>
 				</Tooltip>
 				</Tooltip>
 
 
-				<Tooltip content="Export">
-					<button
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
-						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
-								toast.error(error);
-								return null;
-							});
-
-							if (_tool) {
-								let blob = new Blob([JSON.stringify([_tool])], {
-									type: 'application/json'
-								});
-								saveAs(blob, `tool-${_tool.id}-export-${Date.now()}.json`);
-							}
-						}}
-					>
-						<ArrowDownTray />
-					</button>
-				</Tooltip>
-
-				<Tooltip content="Delete">
+				<ToolMenu
+					editHandler={() => {
+						goto(`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`);
+					}}
+					shareHandler={() => {
+						shareHandler(tool);
+					}}
+					cloneHandler={() => {
+						cloneHandler(tool);
+					}}
+					exportHandler={() => {
+						exportHandler(tool);
+					}}
+					deleteHandler={async () => {
+						deleteHandler(tool);
+					}}
+					onClose={() => {}}
+				>
 					<button
 					<button
-						class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
+						class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
 						type="button"
 						type="button"
-						on:click={async (e) => {
-							e.stopPropagation();
-
-							const res = await deleteToolById(localStorage.token, tool.id).catch((error) => {
-								toast.error(error);
-								return null;
-							});
-
-							if (res) {
-								toast.success('Tool deleted successfully');
-								tools.set(await getTools(localStorage.token));
-							}
-						}}
 					>
 					>
-						<svg
-							xmlns="http://www.w3.org/2000/svg"
-							fill="none"
-							viewBox="0 0 24 24"
-							stroke-width="1.5"
-							stroke="currentColor"
-							class="w-4 h-4"
-						>
-							<path
-								stroke-linecap="round"
-								stroke-linejoin="round"
-								d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
-							/>
-						</svg>
+						<EllipsisHorizontal className="size-5" />
 					</button>
 					</button>
-				</Tooltip>
+				</ToolMenu>
 			</div>
 			</div>
-		</button>
+		</div>
 	{/each}
 	{/each}
 </div>
 </div>
 
 
@@ -273,7 +283,7 @@
 				toolsImportInputElement.click();
 				toolsImportInputElement.click();
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Import Tools')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Tools')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -307,7 +317,7 @@
 				}
 				}
 			}}
 			}}
 		>
 		>
-			<div class=" self-center mr-2 font-medium">{$i18n.t('Export Tools')}</div>
+			<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Tools')}</div>
 
 
 			<div class=" self-center">
 			<div class=" self-center">
 				<svg
 				<svg
@@ -327,6 +337,42 @@
 	</div>
 	</div>
 </div>
 </div>
 
 
+<div class=" my-16">
+	<div class=" text-lg font-semibold mb-3 line-clamp-1">
+		{$i18n.t('Made by OpenWebUI Community')}
+	</div>
+
+	<a
+		class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
+		href="https://openwebui.com/"
+		target="_blank"
+	>
+		<div class=" self-center w-10 flex-shrink-0">
+			<div
+				class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
+			>
+				<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6">
+					<path
+						fill-rule="evenodd"
+						d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
+						clip-rule="evenodd"
+					/>
+				</svg>
+			</div>
+		</div>
+
+		<div class=" self-center">
+			<div class=" font-bold line-clamp-1">{$i18n.t('Discover a tool')}</div>
+			<div class=" text-sm line-clamp-1">
+				{$i18n.t('Discover, download, and explore custom tools')}
+			</div>
+		</div>
+	</a>
+</div>
+
+<ValvesModal bind:show={showValvesModal} type="tool" id={selectedTool?.id ?? null} />
+<ManifestModal bind:show={showManifestModal} manifest={selectedTool?.meta?.manifest ?? {}} />
+
 <ConfirmDialog
 <ConfirmDialog
 	bind:show={showConfirm}
 	bind:show={showConfirm}
 	on:confirm={() => {
 	on:confirm={() => {

+ 117 - 0
src/lib/components/workspace/Tools/ToolMenu.svelte

@@ -0,0 +1,117 @@
+<script lang="ts">
+	import { DropdownMenu } from 'bits-ui';
+	import { flyAndScale } from '$lib/utils/transitions';
+	import { getContext } from 'svelte';
+
+	import Dropdown from '$lib/components/common/Dropdown.svelte';
+	import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
+	import Pencil from '$lib/components/icons/Pencil.svelte';
+	import Tooltip from '$lib/components/common/Tooltip.svelte';
+	import Tags from '$lib/components/chat/Tags.svelte';
+	import Share from '$lib/components/icons/Share.svelte';
+	import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
+	import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
+	import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
+
+	const i18n = getContext('i18n');
+
+	export let editHandler: Function;
+	export let shareHandler: Function;
+	export let cloneHandler: Function;
+	export let exportHandler: Function;
+	export let deleteHandler: Function;
+	export let onClose: Function;
+
+	let show = false;
+</script>
+
+<Dropdown
+	bind:show
+	on:change={(e) => {
+		if (e.detail === false) {
+			onClose();
+		}
+	}}
+>
+	<Tooltip content={$i18n.t('More')}>
+		<slot />
+	</Tooltip>
+
+	<div slot="content">
+		<DropdownMenu.Content
+			class="w-full max-w-[160px] rounded-xl 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"
+			sideOffset={-2}
+			side="bottom"
+			align="start"
+			transition={flyAndScale}
+		>
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800  rounded-md"
+				on:click={() => {
+					editHandler();
+				}}
+			>
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					fill="none"
+					viewBox="0 0 24 24"
+					stroke-width="1.5"
+					stroke="currentColor"
+					class="w-4 h-4"
+				>
+					<path
+						stroke-linecap="round"
+						stroke-linejoin="round"
+						d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
+					/>
+				</svg>
+
+				<div class="flex items-center">{$i18n.t('Edit')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800  rounded-md"
+				on:click={() => {
+					shareHandler();
+				}}
+			>
+				<Share />
+				<div class="flex items-center">{$i18n.t('Share')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					cloneHandler();
+				}}
+			>
+				<DocumentDuplicate />
+
+				<div class="flex items-center">{$i18n.t('Clone')}</div>
+			</DropdownMenu.Item>
+
+			<DropdownMenu.Item
+				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					exportHandler();
+				}}
+			>
+				<ArrowDownTray />
+
+				<div class="flex items-center">{$i18n.t('Export')}</div>
+			</DropdownMenu.Item>
+
+			<hr class="border-gray-100 dark:border-gray-800 my-1" />
+
+			<DropdownMenu.Item
+				class="flex  gap-2  items-center px-3 py-2 text-sm  font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
+				on:click={() => {
+					deleteHandler();
+				}}
+			>
+				<GarbageBin strokeWidth="2" />
+				<div class="flex items-center">{$i18n.t('Delete')}</div>
+			</DropdownMenu.Item>
+		</DropdownMenu.Content>
+	</div>
+</Dropdown>

+ 102 - 0
src/lib/components/workspace/common/ManifestModal.svelte

@@ -0,0 +1,102 @@
+<script lang="ts">
+	import { toast } from 'svelte-sonner';
+	import { createEventDispatcher } from 'svelte';
+	import { onMount, getContext } from 'svelte';
+
+	import Modal from '../../common/Modal.svelte';
+
+	const i18n = getContext('i18n');
+	const dispatch = createEventDispatcher();
+
+	export let show = false;
+	export let manifest = {};
+</script>
+
+<Modal size="sm" bind:show>
+	<div>
+		<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
+			<div class=" text-lg font-medium self-center">{$i18n.t('Show your support!')}</div>
+			<button
+				class="self-center"
+				on:click={() => {
+					show = false;
+				}}
+			>
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 20 20"
+					fill="currentColor"
+					class="w-5 h-5"
+				>
+					<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 class="flex flex-col md:flex-row w-full px-5 pb-4 md:space-x-4 dark:text-gray-200">
+			<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
+				<form
+					class="flex flex-col w-full"
+					on:submit|preventDefault={() => {
+						show = false;
+					}}
+				>
+					<div class="px-1 text-sm">
+						<div class=" my-2">
+							The developers behind this plugin are passionate volunteers from the community. If you
+							find this plugin helpful, please consider contributing to its development.
+						</div>
+
+						<div class=" my-2">
+							Your entire contribution will go directly to the plugin developer; Open WebUI does not
+							take any percentage. However, the chosen funding platform might have its own fees.
+						</div>
+
+						<hr class=" dark:border-gray-800 my-3" />
+
+						<div class="my-2">
+							Support this plugin: <a
+								href={manifest.funding_url}
+								target="_blank"
+								class=" underline text-blue-400 hover:text-blue-300">{manifest.funding_url}</a
+							>
+						</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 flex flex-row space-x-1 items-center"
+							type="submit"
+						>
+							{$i18n.t('Done')}
+						</button>
+					</div>
+				</form>
+			</div>
+		</div>
+	</div>
+</Modal>
+
+<style>
+	input::-webkit-outer-spin-button,
+	input::-webkit-inner-spin-button {
+		/* display: none; <- Crashes Chrome on hover */
+		-webkit-appearance: none;
+		margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
+	}
+
+	.tabs::-webkit-scrollbar {
+		display: none; /* for Chrome, Safari and Opera */
+	}
+
+	.tabs {
+		-ms-overflow-style: none; /* IE and Edge */
+		scrollbar-width: none; /* Firefox */
+	}
+
+	input[type='number'] {
+		-moz-appearance: textfield; /* Firefox */
+	}
+</style>

+ 256 - 0
src/lib/components/workspace/common/ValvesModal.svelte

@@ -0,0 +1,256 @@
+<script lang="ts">
+	import { toast } from 'svelte-sonner';
+	import { createEventDispatcher } from 'svelte';
+	import { onMount, getContext } from 'svelte';
+	import { addUser } from '$lib/apis/auths';
+
+	import Modal from '../../common/Modal.svelte';
+	import {
+		getFunctionValvesById,
+		getFunctionValvesSpecById,
+		updateFunctionValvesById
+	} from '$lib/apis/functions';
+	import { getToolValvesById, getToolValvesSpecById, updateToolValvesById } from '$lib/apis/tools';
+	import Spinner from '../../common/Spinner.svelte';
+
+	const i18n = getContext('i18n');
+	const dispatch = createEventDispatcher();
+
+	export let show = false;
+
+	export let type = 'tool';
+	export let id = null;
+
+	let saving = false;
+	let loading = false;
+
+	let valvesSpec = null;
+	let valves = {};
+
+	const submitHandler = async () => {
+		saving = true;
+
+		if (valvesSpec) {
+			// Convert string to array
+			for (const property in valvesSpec.properties) {
+				if (valvesSpec.properties[property]?.type === 'array') {
+					valves[property] = (valves[property] ?? '').split(',').map((v) => v.trim());
+				}
+			}
+
+			let res = null;
+
+			if (type === 'tool') {
+				res = await updateToolValvesById(localStorage.token, id, valves).catch((error) => {
+					toast.error(error);
+				});
+			} else if (type === 'function') {
+				res = await updateFunctionValvesById(localStorage.token, id, valves).catch((error) => {
+					toast.error(error);
+				});
+			}
+
+			if (res) {
+				toast.success('Valves updated successfully');
+			}
+		}
+
+		saving = false;
+	};
+
+	const initHandler = async () => {
+		loading = true;
+		valves = {};
+		valvesSpec = null;
+
+		if (type === 'tool') {
+			valves = await getToolValvesById(localStorage.token, id);
+			valvesSpec = await getToolValvesSpecById(localStorage.token, id);
+		} else if (type === 'function') {
+			valves = await getFunctionValvesById(localStorage.token, id);
+			valvesSpec = await getFunctionValvesSpecById(localStorage.token, id);
+		}
+
+		if (!valves) {
+			valves = {};
+		}
+
+		if (valvesSpec) {
+			// Convert array to string
+			for (const property in valvesSpec.properties) {
+				if (valvesSpec.properties[property]?.type === 'array') {
+					valves[property] = (valves[property] ?? []).join(',');
+				}
+			}
+		}
+
+		loading = false;
+	};
+
+	$: if (show) {
+		initHandler();
+	}
+</script>
+
+<Modal size="sm" bind:show>
+	<div>
+		<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
+			<div class=" text-lg font-medium self-center">{$i18n.t('Valves')}</div>
+			<button
+				class="self-center"
+				on:click={() => {
+					show = false;
+				}}
+			>
+				<svg
+					xmlns="http://www.w3.org/2000/svg"
+					viewBox="0 0 20 20"
+					fill="currentColor"
+					class="w-5 h-5"
+				>
+					<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 class="flex flex-col md:flex-row w-full px-5 pb-4 md:space-x-4 dark:text-gray-200">
+			<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
+				<form
+					class="flex flex-col w-full"
+					on:submit|preventDefault={() => {
+						submitHandler();
+					}}
+				>
+					<div class="px-1">
+						{#if !loading}
+							{#if valvesSpec}
+								{#each Object.keys(valvesSpec.properties) as property, idx}
+									<div class=" py-0.5 w-full justify-between">
+										<div class="flex w-full justify-between">
+											<div class=" self-center text-xs font-medium">
+												{valvesSpec.properties[property].title}
+
+												{#if (valvesSpec?.required ?? []).includes(property)}
+													<span class=" text-gray-500">*required</span>
+												{/if}
+											</div>
+
+											<button
+												class="p-1 px-3 text-xs flex rounded transition"
+												type="button"
+												on:click={() => {
+													valves[property] = (valves[property] ?? null) === null ? '' : null;
+												}}
+											>
+												{#if (valves[property] ?? null) === null}
+													<span class="ml-2 self-center">
+														{#if (valvesSpec?.required ?? []).includes(property)}
+															{$i18n.t('None')}
+														{:else}
+															{$i18n.t('Default')}
+														{/if}
+													</span>
+												{:else}
+													<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
+												{/if}
+											</button>
+										</div>
+
+										{#if (valves[property] ?? null) !== null}
+											<div class="flex mt-0.5 mb-1.5 space-x-2">
+												<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={valvesSpec.properties[property].title}
+														bind:value={valves[property]}
+														autocomplete="off"
+														required
+													/>
+												</div>
+											</div>
+										{/if}
+
+										{#if (valvesSpec.properties[property]?.description ?? null) !== null}
+											<div class="text-xs text-gray-500">
+												{valvesSpec.properties[property].description}
+											</div>
+										{/if}
+									</div>
+								{/each}
+							{:else}
+								<div class="text-sm">No valves</div>
+							{/if}
+						{:else}
+							<Spinner className="size-5" />
+						{/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 flex flex-row space-x-1 items-center {saving
+								? ' cursor-not-allowed'
+								: ''}"
+							type="submit"
+							disabled={saving}
+						>
+							{$i18n.t('Save')}
+
+							{#if saving}
+								<div class="ml-2 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>
+							{/if}
+						</button>
+					</div>
+				</form>
+			</div>
+		</div>
+	</div>
+</Modal>
+
+<style>
+	input::-webkit-outer-spin-button,
+	input::-webkit-inner-spin-button {
+		/* display: none; <- Crashes Chrome on hover */
+		-webkit-appearance: none;
+		margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
+	}
+
+	.tabs::-webkit-scrollbar {
+		display: none; /* for Chrome, Safari and Opera */
+	}
+
+	.tabs {
+		-ms-overflow-style: none; /* IE and Edge */
+		scrollbar-width: none; /* Firefox */
+	}
+
+	input[type='number'] {
+		-moz-appearance: textfield; /* Firefox */
+	}
+</style>

+ 11 - 0
src/lib/i18n/locales/ar-BH/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "يستطيع حذف المحادثات",
 	"Allow Chat Deletion": "يستطيع حذف المحادثات",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "الأحرف الأبجدية الرقمية والواصلات",
 	"alphanumeric characters and hyphens": "الأحرف الأبجدية الرقمية والواصلات",
 	"Already have an account?": "هل تملك حساب ؟",
 	"Already have an account?": "هل تملك حساب ؟",
 	"an assistant": "مساعد",
 	"an assistant": "مساعد",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "حذف {{name}}",
 	"Deleted {{name}}": "حذف {{name}}",
 	"Description": "وصف",
 	"Description": "وصف",
 	"Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل",
 	"Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل",
+	"Discover a function": "",
 	"Discover a model": "اكتشف نموذجا",
 	"Discover a model": "اكتشف نموذجا",
 	"Discover a prompt": "اكتشاف موجه",
 	"Discover a prompt": "اكتشاف موجه",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "اكتشاف وتنزيل واستكشاف المطالبات المخصصة",
 	"Discover, download, and explore custom prompts": "اكتشاف وتنزيل واستكشاف المطالبات المخصصة",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "اكتشاف وتنزيل واستكشاف الإعدادات المسبقة للنموذج",
 	"Discover, download, and explore model presets": "اكتشاف وتنزيل واستكشاف الإعدادات المسبقة للنموذج",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "لا تسمح بذلك",
 	"Don't Allow": "لا تسمح بذلك",
 	"Don't have an account?": "ليس لديك حساب؟",
 	"Don't have an account?": "ليس لديك حساب؟",
 	"Don't like the style": "لا أحب النمط",
 	"Don't like the style": "لا أحب النمط",
+	"Done": "",
 	"Download": "تحميل",
 	"Download": "تحميل",
 	"Download canceled": "تم اللغاء التحميل",
 	"Download canceled": "تم اللغاء التحميل",
 	"Download Database": "تحميل قاعدة البيانات",
 	"Download Database": "تحميل قاعدة البيانات",
@@ -312,6 +318,7 @@
 	"Manage Models": "إدارة النماذج",
 	"Manage Models": "إدارة النماذج",
 	"Manage Ollama Models": "Ollama إدارة موديلات ",
 	"Manage Ollama Models": "Ollama إدارة موديلات ",
 	"Manage Pipelines": "إدارة خطوط الأنابيب",
 	"Manage Pipelines": "إدارة خطوط الأنابيب",
+	"Manage Valves": "",
 	"March": "مارس",
 	"March": "مارس",
 	"Max Tokens (num_predict)": "ماكس توكنز (num_predict)",
 	"Max Tokens (num_predict)": "ماكس توكنز (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "يمكن تنزيل 3 نماذج كحد أقصى في وقت واحد. الرجاء معاودة المحاولة في وقت لاحق.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "يمكن تنزيل 3 نماذج كحد أقصى في وقت واحد. الرجاء معاودة المحاولة في وقت لاحق.",
@@ -463,10 +470,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "حدد نموذجا أساسيا",
 	"Select a base model": "حدد نموذجا أساسيا",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "أختار موديل",
 	"Select a mode": "أختار موديل",
 	"Select a model": "أختار الموديل",
 	"Select a model": "أختار الموديل",
 	"Select a pipeline": "حدد مسارا",
 	"Select a pipeline": "حدد مسارا",
 	"Select a pipeline url": "حدد عنوان URL لخط الأنابيب",
 	"Select a pipeline url": "حدد عنوان URL لخط الأنابيب",
+	"Select a tool": "",
 	"Select an Ollama instance": "أختار سيرفر ",
 	"Select an Ollama instance": "أختار سيرفر ",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": " أختار موديل",
 	"Select model": " أختار موديل",
@@ -499,6 +508,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "إظهار الاختصارات",
 	"Show shortcuts": "إظهار الاختصارات",
+	"Show your support!": "",
 	"Showcased creativity": "أظهر الإبداع",
 	"Showcased creativity": "أظهر الإبداع",
 	"sidebar": "الشريط الجانبي",
 	"sidebar": "الشريط الجانبي",
 	"Sign in": "تسجيل الدخول",
 	"Sign in": "تسجيل الدخول",
@@ -587,6 +597,7 @@
 	"Users": "المستخدمين",
 	"Users": "المستخدمين",
 	"Utilize": "يستخدم",
 	"Utilize": "يستخدم",
 	"Valid time units:": "وحدات زمنية صالحة:",
 	"Valid time units:": "وحدات زمنية صالحة:",
+	"Valves": "",
 	"variable": "المتغير",
 	"variable": "المتغير",
 	"variable to have them replaced with clipboard content.": "متغير لاستبدالها بمحتوى الحافظة.",
 	"variable to have them replaced with clipboard content.": "متغير لاستبدالها بمحتوى الحافظة.",
 	"Version": "إصدار",
 	"Version": "إصدار",

+ 11 - 0
src/lib/i18n/locales/bg-BG/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Позволи Изтриване на Чат",
 	"Allow Chat Deletion": "Позволи Изтриване на Чат",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "алфанумерични знаци и тире",
 	"alphanumeric characters and hyphens": "алфанумерични знаци и тире",
 	"Already have an account?": "Вече имате акаунт? ",
 	"Already have an account?": "Вече имате акаунт? ",
 	"an assistant": "асистент",
 	"an assistant": "асистент",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Изтрито {{име}}",
 	"Deleted {{name}}": "Изтрито {{име}}",
 	"Description": "Описание",
 	"Description": "Описание",
 	"Didn't fully follow instructions": "Не следва инструкциите",
 	"Didn't fully follow instructions": "Не следва инструкциите",
+	"Discover a function": "",
 	"Discover a model": "Открийте модел",
 	"Discover a model": "Открийте модел",
 	"Discover a prompt": "Откриване на промпт",
 	"Discover a prompt": "Откриване на промпт",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Откриване, сваляне и преглед на персонализирани промптове",
 	"Discover, download, and explore custom prompts": "Откриване, сваляне и преглед на персонализирани промптове",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Откриване, сваляне и преглед на пресетове на модели",
 	"Discover, download, and explore model presets": "Откриване, сваляне и преглед на пресетове на модели",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Не Позволявай",
 	"Don't Allow": "Не Позволявай",
 	"Don't have an account?": "Нямате акаунт?",
 	"Don't have an account?": "Нямате акаунт?",
 	"Don't like the style": "Не харесваш стила?",
 	"Don't like the style": "Не харесваш стила?",
+	"Done": "",
 	"Download": "Изтегляне отменено",
 	"Download": "Изтегляне отменено",
 	"Download canceled": "Изтегляне отменено",
 	"Download canceled": "Изтегляне отменено",
 	"Download Database": "Сваляне на база данни",
 	"Download Database": "Сваляне на база данни",
@@ -312,6 +318,7 @@
 	"Manage Models": "Управление на Моделите",
 	"Manage Models": "Управление на Моделите",
 	"Manage Ollama Models": "Управление на Ollama Моделите",
 	"Manage Ollama Models": "Управление на Ollama Моделите",
 	"Manage Pipelines": "Управление на тръбопроводи",
 	"Manage Pipelines": "Управление на тръбопроводи",
+	"Manage Valves": "",
 	"March": "Март",
 	"March": "Март",
 	"Max Tokens (num_predict)": "Макс токени (num_predict)",
 	"Max Tokens (num_predict)": "Макс токени (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 модели могат да бъдат сваляни едновременно. Моля, опитайте отново по-късно.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 модели могат да бъдат сваляни едновременно. Моля, опитайте отново по-късно.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Изберете базов модел",
 	"Select a base model": "Изберете базов модел",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Изберете режим",
 	"Select a mode": "Изберете режим",
 	"Select a model": "Изберете модел",
 	"Select a model": "Изберете модел",
 	"Select a pipeline": "Изберете тръбопровод",
 	"Select a pipeline": "Изберете тръбопровод",
 	"Select a pipeline url": "Избор на URL адрес на канал",
 	"Select a pipeline url": "Избор на URL адрес на канал",
+	"Select a tool": "",
 	"Select an Ollama instance": "Изберете Ollama инстанция",
 	"Select an Ollama instance": "Изберете Ollama инстанция",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Изберете модел",
 	"Select model": "Изберете модел",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Покажи",
 	"Show shortcuts": "Покажи",
+	"Show your support!": "",
 	"Showcased creativity": "Показана креативност",
 	"Showcased creativity": "Показана креативност",
 	"sidebar": "sidebar",
 	"sidebar": "sidebar",
 	"Sign in": "Вписване",
 	"Sign in": "Вписване",
@@ -583,6 +593,7 @@
 	"Users": "Потребители",
 	"Users": "Потребители",
 	"Utilize": "Използване",
 	"Utilize": "Използване",
 	"Valid time units:": "Валидни единици за време:",
 	"Valid time units:": "Валидни единици за време:",
+	"Valves": "",
 	"variable": "променлива",
 	"variable": "променлива",
 	"variable to have them replaced with clipboard content.": "променливи да се заменят съдържанието от клипборд.",
 	"variable to have them replaced with clipboard content.": "променливи да се заменят съдържанието от клипборд.",
 	"Version": "Версия",
 	"Version": "Версия",

+ 11 - 0
src/lib/i18n/locales/bn-BD/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "চ্যাট ডিলিট করতে দিন",
 	"Allow Chat Deletion": "চ্যাট ডিলিট করতে দিন",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "ইংরেজি অক্ষর, সংখ্যা এবং হাইফেন",
 	"alphanumeric characters and hyphens": "ইংরেজি অক্ষর, সংখ্যা এবং হাইফেন",
 	"Already have an account?": "আগে থেকেই একাউন্ট আছে?",
 	"Already have an account?": "আগে থেকেই একাউন্ট আছে?",
 	"an assistant": "একটা এসিস্ট্যান্ট",
 	"an assistant": "একটা এসিস্ট্যান্ট",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}} মোছা হয়েছে",
 	"Deleted {{name}}": "{{name}} মোছা হয়েছে",
 	"Description": "বিবরণ",
 	"Description": "বিবরণ",
 	"Didn't fully follow instructions": "ইনস্ট্রাকশন সম্পূর্ণ অনুসরণ করা হয়নি",
 	"Didn't fully follow instructions": "ইনস্ট্রাকশন সম্পূর্ণ অনুসরণ করা হয়নি",
+	"Discover a function": "",
 	"Discover a model": "একটি মডেল আবিষ্কার করুন",
 	"Discover a model": "একটি মডেল আবিষ্কার করুন",
 	"Discover a prompt": "একটি প্রম্পট খুঁজে বের করুন",
 	"Discover a prompt": "একটি প্রম্পট খুঁজে বের করুন",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "কাস্টম প্রম্পটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
 	"Discover, download, and explore custom prompts": "কাস্টম প্রম্পটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "মডেল প্রিসেটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
 	"Discover, download, and explore model presets": "মডেল প্রিসেটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "অনুমোদন দেবেন না",
 	"Don't Allow": "অনুমোদন দেবেন না",
 	"Don't have an account?": "একাউন্ট নেই?",
 	"Don't have an account?": "একাউন্ট নেই?",
 	"Don't like the style": "স্টাইল পছন্দ করেন না",
 	"Don't like the style": "স্টাইল পছন্দ করেন না",
+	"Done": "",
 	"Download": "ডাউনলোড",
 	"Download": "ডাউনলোড",
 	"Download canceled": "ডাউনলোড বাতিল করা হয়েছে",
 	"Download canceled": "ডাউনলোড বাতিল করা হয়েছে",
 	"Download Database": "ডেটাবেজ ডাউনলোড করুন",
 	"Download Database": "ডেটাবেজ ডাউনলোড করুন",
@@ -312,6 +318,7 @@
 	"Manage Models": "মডেলসমূহ ব্যবস্থাপনা করুন",
 	"Manage Models": "মডেলসমূহ ব্যবস্থাপনা করুন",
 	"Manage Ollama Models": "Ollama মডেলসূহ ব্যবস্থাপনা করুন",
 	"Manage Ollama Models": "Ollama মডেলসূহ ব্যবস্থাপনা করুন",
 	"Manage Pipelines": "পাইপলাইন পরিচালনা করুন",
 	"Manage Pipelines": "পাইপলাইন পরিচালনা করুন",
+	"Manage Valves": "",
 	"March": "মার্চ",
 	"March": "মার্চ",
 	"Max Tokens (num_predict)": "সর্বোচ্চ টোকেন (num_predict)",
 	"Max Tokens (num_predict)": "সর্বোচ্চ টোকেন (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "একসঙ্গে সর্বোচ্চ তিনটি মডেল ডাউনলোড করা যায়। দয়া করে পরে আবার চেষ্টা করুন।",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "একসঙ্গে সর্বোচ্চ তিনটি মডেল ডাউনলোড করা যায়। দয়া করে পরে আবার চেষ্টা করুন।",
@@ -459,10 +466,12 @@
 	"Seed": "সীড",
 	"Seed": "সীড",
 	"Select a base model": "একটি বেস মডেল নির্বাচন করুন",
 	"Select a base model": "একটি বেস মডেল নির্বাচন করুন",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "একটি মডেল নির্বাচন করুন",
 	"Select a mode": "একটি মডেল নির্বাচন করুন",
 	"Select a model": "একটি মডেল নির্বাচন করুন",
 	"Select a model": "একটি মডেল নির্বাচন করুন",
 	"Select a pipeline": "একটি পাইপলাইন নির্বাচন করুন",
 	"Select a pipeline": "একটি পাইপলাইন নির্বাচন করুন",
 	"Select a pipeline url": "একটি পাইপলাইন URL নির্বাচন করুন",
 	"Select a pipeline url": "একটি পাইপলাইন URL নির্বাচন করুন",
+	"Select a tool": "",
 	"Select an Ollama instance": "একটি Ollama ইন্সট্যান্স নির্বাচন করুন",
 	"Select an Ollama instance": "একটি Ollama ইন্সট্যান্স নির্বাচন করুন",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "মডেল নির্বাচন করুন",
 	"Select model": "মডেল নির্বাচন করুন",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "শর্টকাটগুলো দেখান",
 	"Show shortcuts": "শর্টকাটগুলো দেখান",
+	"Show your support!": "",
 	"Showcased creativity": "সৃজনশীলতা প্রদর্শন",
 	"Showcased creativity": "সৃজনশীলতা প্রদর্শন",
 	"sidebar": "সাইডবার",
 	"sidebar": "সাইডবার",
 	"Sign in": "সাইন ইন",
 	"Sign in": "সাইন ইন",
@@ -583,6 +593,7 @@
 	"Users": "ব্যাবহারকারীগণ",
 	"Users": "ব্যাবহারকারীগণ",
 	"Utilize": "ইউটিলাইজ",
 	"Utilize": "ইউটিলাইজ",
 	"Valid time units:": "সময়ের গ্রহণযোগ্য এককসমূহ:",
 	"Valid time units:": "সময়ের গ্রহণযোগ্য এককসমূহ:",
+	"Valves": "",
 	"variable": "ভেরিয়েবল",
 	"variable": "ভেরিয়েবল",
 	"variable to have them replaced with clipboard content.": "ক্লিপবোর্ডের কন্টেন্ট দিয়ে যেই ভেরিয়েবল রিপ্লেস করা যাবে।",
 	"variable to have them replaced with clipboard content.": "ক্লিপবোর্ডের কন্টেন্ট দিয়ে যেই ভেরিয়েবল রিপ্লেস করা যাবে।",
 	"Version": "ভার্সন",
 	"Version": "ভার্সন",

+ 403 - 392
src/lib/i18n/locales/ca-ES/translation.json

@@ -1,620 +1,631 @@
 {
 {
-	"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' or '-1' per no caduca mai.",
+	"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' o '-1' perquè no caduqui mai.",
 	"(Beta)": "(Beta)",
 	"(Beta)": "(Beta)",
 	"(e.g. `sh webui.sh --api`)": "(p. ex. `sh webui.sh --api`)",
 	"(e.g. `sh webui.sh --api`)": "(p. ex. `sh webui.sh --api`)",
 	"(latest)": "(últim)",
 	"(latest)": "(últim)",
 	"{{ models }}": "{{ models }}",
 	"{{ models }}": "{{ models }}",
-	"{{ owner }}: You cannot delete a base model": "{{ propietari }}: No es pot suprimir un model base",
+	"{{ owner }}: You cannot delete a base model": "{{ owner }}: No es pot eliminar un model base",
 	"{{modelName}} is thinking...": "{{modelName}} està pensant...",
 	"{{modelName}} is thinking...": "{{modelName}} està pensant...",
-	"{{user}}'s Chats": "{{user}}'s Chats",
-	"{{webUIName}} Backend Required": "Es requereix Backend de {{webUIName}}",
-	"A task model is used when performing tasks such as generating titles for chats and web search queries": "Un model de tasca s'utilitza quan es realitzen tasques com ara generar títols per a xats i consultes de cerca web",
+	"{{user}}'s Chats": "Els xats de {{user}}",
+	"{{webUIName}} Backend Required": "El Backend de {{webUIName}} és necessari",
+	"A task model is used when performing tasks such as generating titles for chats and web search queries": "Un model de tasca s'utilitza quan es realitzen tasques com ara generar títols per a xats i consultes de cerca per a la web",
 	"a user": "un usuari",
 	"a user": "un usuari",
 	"About": "Sobre",
 	"About": "Sobre",
 	"Account": "Compte",
 	"Account": "Compte",
-	"Account Activation Pending": "",
+	"Account Activation Pending": "Activació del compte pendent",
 	"Accurate information": "Informació precisa",
 	"Accurate information": "Informació precisa",
-	"Active Users": "",
+	"Active Users": "Usuaris actius",
 	"Add": "Afegir",
 	"Add": "Afegir",
-	"Add a model id": "Afegir un identificador de model",
-	"Add a short description about what this model does": "Afegiu una breu descripció sobre què fa aquest model",
-	"Add a short title for this prompt": "Afegeix un títol curt per aquest prompt",
+	"Add a model id": "Afegeix un identificador de model",
+	"Add a short description about what this model does": "Afegeix una breu descripció sobre què fa aquest model",
+	"Add a short title for this prompt": "Afegeix un títol curt per a aquesta indicació",
 	"Add a tag": "Afegeix una etiqueta",
 	"Add a tag": "Afegeix una etiqueta",
-	"Add custom prompt": "Afegir un prompt personalitzat",
-	"Add Docs": "Afegeix Documents",
-	"Add Files": "Afegeix Arxius",
-	"Add Memory": "Afegir Memòria",
-	"Add message": "Afegeix missatge",
-	"Add Model": "Afegir Model",
-	"Add Tags": "afegeix etiquetes",
-	"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.",
+	"Add custom prompt": "Afegir una indicació personalitzada",
+	"Add Docs": "Afegir documents",
+	"Add Files": "Afegir arxius",
+	"Add Memory": "Afegir memòria",
+	"Add message": "Afegir un missatge",
+	"Add Model": "Afegir un model",
+	"Add Tags": "Afegir etiquetes",
+	"Add User": "Afegir un usuari",
+	"Adjusting these settings will apply changes universally to all users.": "Si ajustes aquesta configuració, els canvis s'aplicaran de manera universal a tots els usuaris.",
 	"admin": "administrador",
 	"admin": "administrador",
-	"Admin": "",
-	"Admin Panel": "Panell d'Administració",
-	"Admin Settings": "Configuració d'Administració",
-	"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "",
-	"Advanced Parameters": "Paràmetres Avançats",
+	"Admin": "Administrador",
+	"Admin Panel": "Panell d'administració",
+	"Admin Settings": "Configuració d'administració",
+	"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Els administradors tenen accés a totes les eines en tot moment; els usuaris necessiten eines assignades per model a l'espai de treball.",
+	"Advanced Parameters": "Paràmetres avançats",
 	"Advanced Params": "Paràmetres avançats",
 	"Advanced Params": "Paràmetres avançats",
 	"all": "tots",
 	"all": "tots",
-	"All Documents": "Tots els Documents",
-	"All Users": "Tots els Usuaris",
-	"Allow": "Permet",
-	"Allow Chat Deletion": "Permet la Supressió del Xat",
-	"Allow non-local voices": "",
-	"Allow User Location": "",
+	"All Documents": "Tots els documents",
+	"All Users": "Tots els usuaris",
+	"Allow": "Permetre",
+	"Allow Chat Deletion": "Permetre la supressió del xat",
+	"Allow non-local voices": "Permetre veus no locals",
+	"Allow User Location": "Permetre la ubicació de l'usuari",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caràcters alfanumèrics i guions",
 	"alphanumeric characters and hyphens": "caràcters alfanumèrics i guions",
 	"Already have an account?": "Ja tens un compte?",
 	"Already have an account?": "Ja tens un compte?",
 	"an assistant": "un assistent",
 	"an assistant": "un assistent",
 	"and": "i",
 	"and": "i",
 	"and create a new shared link.": "i crear un nou enllaç compartit.",
 	"and create a new shared link.": "i crear un nou enllaç compartit.",
 	"API Base URL": "URL Base de l'API",
 	"API Base URL": "URL Base de l'API",
-	"API Key": "Clau de l'API",
-	"API Key created.": "Clau de l'API creada.",
+	"API Key": "clau API",
+	"API Key created.": "clau API creada.",
 	"API keys": "Claus de l'API",
 	"API keys": "Claus de l'API",
 	"April": "Abril",
 	"April": "Abril",
 	"Archive": "Arxiu",
 	"Archive": "Arxiu",
 	"Archive All Chats": "Arxiva tots els xats",
 	"Archive All Chats": "Arxiva tots els xats",
-	"Archived Chats": "Arxiu d'historial de xat",
+	"Archived Chats": "Xats arxivats",
 	"are allowed - Activate this command by typing": "estan permesos - Activa aquesta comanda escrivint",
 	"are allowed - Activate this command by typing": "estan permesos - Activa aquesta comanda escrivint",
 	"Are you sure?": "Estàs segur?",
 	"Are you sure?": "Estàs segur?",
 	"Attach file": "Adjuntar arxiu",
 	"Attach file": "Adjuntar arxiu",
-	"Attention to detail": "Detall atent",
+	"Attention to detail": "Atenció al detall",
 	"Audio": "Àudio",
 	"Audio": "Àudio",
 	"August": "Agost",
 	"August": "Agost",
-	"Auto-playback response": "Resposta de reproducció automàtica",
-	"AUTOMATIC1111 Base URL": "URL Base AUTOMATIC1111",
-	"AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base AUTOMATIC1111.",
+	"Auto-playback response": "Reproduir la resposta automàticament",
+	"AUTOMATIC1111 Base URL": "URL Base d'AUTOMATIC1111",
+	"AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base d'AUTOMATIC1111.",
 	"available!": "disponible!",
 	"available!": "disponible!",
 	"Back": "Enrere",
 	"Back": "Enrere",
-	"Bad Response": "Resposta Erroni",
+	"Bad Response": "Resposta errònia",
 	"Banners": "Banners",
 	"Banners": "Banners",
 	"Base Model (From)": "Model base (des de)",
 	"Base Model (From)": "Model base (des de)",
-	"Batch Size (num_batch)": "",
+	"Batch Size (num_batch)": "Mida del lot (num_batch)",
 	"before": "abans",
 	"before": "abans",
-	"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",
+	"Being lazy": "Essent mandrós",
+	"Brave Search API Key": "Clau API de Brave Search",
+	"Bypass SSL verification for Websites": "Desactivar la verificació SSL per a l'accés a Internet",
+	"Call": "Trucada",
+	"Call feature is not supported when using Web STT engine": "La funció de trucada no s'admet quan s'utilitza el motor Web STT",
+	"Camera": "Càmera",
+	"Cancel": "Cancel·lar",
 	"Capabilities": "Capacitats",
 	"Capabilities": "Capacitats",
-	"Change Password": "Canvia la Contrasenya",
+	"Change Password": "Canviar la contrasenya",
 	"Chat": "Xat",
 	"Chat": "Xat",
-	"Chat Background Image": "",
+	"Chat Background Image": "Imatge de fons del xat",
 	"Chat Bubble UI": "Chat Bubble UI",
 	"Chat Bubble UI": "Chat Bubble UI",
-	"Chat direction": "Direcció del Xat",
-	"Chat History": "Històric del Xat",
-	"Chat History is off for this browser.": "L'historial de xat està desactivat per a aquest navegador.",
+	"Chat direction": "Direcció del xat",
+	"Chat History": "Històric del xat",
+	"Chat History is off for this browser.": "L'historic del xat està desactivat per a aquest navegador.",
 	"Chats": "Xats",
 	"Chats": "Xats",
-	"Check Again": "Comprova-ho de Nou",
-	"Check for updates": "Comprova si hi ha actualitzacions",
+	"Check Again": "Comprovar-ho de nou",
+	"Check for updates": "Comprovar si hi ha actualitzacions",
 	"Checking for updates...": "Comprovant actualitzacions...",
 	"Checking for updates...": "Comprovant actualitzacions...",
-	"Choose a model before saving...": "Tria un model abans de guardar...",
-	"Chunk Overlap": "Solapament de Blocs",
-	"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 download user import template file.": "",
-	"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.",
-	"Clone": "Clon",
-	"Close": "Tanca",
+	"Choose a model before saving...": "Triar un model abans de desar...",
+	"Chunk Overlap": "Solapament de blocs",
+	"Chunk Params": "Paràmetres dels blocs",
+	"Chunk Size": "Mida del bloc",
+	"Citation": "Cita",
+	"Clear memory": "Esborrar la memòria",
+	"Click here for help.": "Clica aquí per obtenir ajuda.",
+	"Click here to": "Clic aquí per",
+	"Click here to download user import template file.": "Fes clic aquí per descarregar l'arxiu de plantilla d'importació d'usuaris",
+	"Click here to select": "Clica aquí per seleccionar",
+	"Click here to select a csv file.": "Clica aquí per seleccionar un fitxer csv.",
+	"Click here to select a py file.": "Clica aquí per seleccionar un fitxer py.",
+	"Click here to select documents.": "Clica aquí per seleccionar documents.",
+	"click here.": "clica aquí.",
+	"Click on the user role button to change a user's role.": "Clica sobre el botó de rol d'usuari per canviar el rol d'un usuari.",
+	"Clone": "Clonar",
+	"Close": "Tancar",
 	"Collection": "Col·lecció",
 	"Collection": "Col·lecció",
 	"ComfyUI": "ComfyUI",
 	"ComfyUI": "ComfyUI",
 	"ComfyUI Base URL": "URL base de ComfyUI",
 	"ComfyUI Base URL": "URL base de ComfyUI",
-	"ComfyUI Base URL is required.": "URL base de ComfyUI és obligatòria.",
+	"ComfyUI Base URL is required.": "L'URL base de ComfyUI és obligatòria.",
 	"Command": "Comanda",
 	"Command": "Comanda",
-	"Concurrent Requests": "Sol·licituds simultànies",
-	"Confirm": "",
-	"Confirm Password": "Confirma la Contrasenya",
-	"Confirm your action": "",
+	"Concurrent Requests": "Peticions simultànies",
+	"Confirm": "Confirmar",
+	"Confirm Password": "Confirmar la contrasenya",
+	"Confirm your action": "Confirma la teva acció",
 	"Connections": "Connexions",
 	"Connections": "Connexions",
-	"Contact Admin for WebUI Access": "",
+	"Contact Admin for WebUI Access": "Posat en contacte amb l'administrador per accedir a WebUI",
 	"Content": "Contingut",
 	"Content": "Contingut",
-	"Context Length": "Longitud del Context",
-	"Continue Response": "Continua la Resposta",
+	"Context Length": "Mida del context",
+	"Continue Response": "Continuar la resposta",
 	"Continue with {{provider}}": "",
 	"Continue with {{provider}}": "",
 	"Copied shared chat URL to clipboard!": "S'ha copiat l'URL compartida al porta-retalls!",
 	"Copied shared chat URL to clipboard!": "S'ha copiat l'URL compartida al porta-retalls!",
 	"Copy": "Copiar",
 	"Copy": "Copiar",
-	"Copy last code block": "Copia l'últim bloc de codi",
-	"Copy last response": "Copia l'última resposta",
+	"Copy last code block": "Copiar l'últim bloc de codi",
+	"Copy last response": "Copiar l'última resposta",
 	"Copy Link": "Copiar l'enllaç",
 	"Copy Link": "Copiar l'enllaç",
-	"Copying to clipboard was successful!": "La còpia al porta-retalls ha estat exitosa!",
+	"Copying to clipboard was successful!": "La còpia al porta-retalls s'ha realitzat amb èxit!",
 	"Create a model": "Crear un model",
 	"Create a model": "Crear un model",
-	"Create Account": "Crea un Compte",
-	"Create new key": "Crea una nova clau",
-	"Create new secret key": "Crea una nova clau secreta",
+	"Create Account": "Crear un compte",
+	"Create new key": "Crear una nova clau",
+	"Create new secret key": "Crear una nova clau secreta",
 	"Created at": "Creat el",
 	"Created at": "Creat el",
 	"Created At": "Creat el",
 	"Created At": "Creat el",
-	"Created by": "",
-	"CSV Import": "",
-	"Current Model": "Model Actual",
-	"Current Password": "Contrasenya Actual",
+	"Created by": "Creat per",
+	"CSV Import": "Importar CSV",
+	"Current Model": "Model actual",
+	"Current Password": "Contrasenya actual",
 	"Custom": "Personalitzat",
 	"Custom": "Personalitzat",
 	"Customize models for a specific purpose": "Personalitzar models per a un propòsit específic",
 	"Customize models for a specific purpose": "Personalitzar models per a un propòsit específic",
 	"Dark": "Fosc",
 	"Dark": "Fosc",
-	"Dashboard": "",
-	"Database": "Base de Dades",
+	"Dashboard": "Tauler",
+	"Database": "Base de dades",
 	"December": "Desembre",
 	"December": "Desembre",
 	"Default": "Per defecte",
 	"Default": "Per defecte",
 	"Default (Automatic1111)": "Per defecte (Automatic1111)",
 	"Default (Automatic1111)": "Per defecte (Automatic1111)",
 	"Default (SentenceTransformers)": "Per defecte (SentenceTransformers)",
 	"Default (SentenceTransformers)": "Per defecte (SentenceTransformers)",
 	"Default Model": "Model per defecte",
 	"Default Model": "Model per defecte",
 	"Default model updated": "Model per defecte actualitzat",
 	"Default model updated": "Model per defecte actualitzat",
-	"Default Prompt Suggestions": "Suggeriments de Prompt Per Defecte",
-	"Default User Role": "Rol d'Usuari Per Defecte",
-	"delete": "esborra",
-	"Delete": "Esborra",
-	"Delete a model": "Esborra un model",
-	"Delete All Chats": "Suprimir tots els xats",
-	"Delete chat": "Esborra xat",
-	"Delete Chat": "Esborra Xat",
-	"Delete chat?": "",
-	"delete this link": "Esborra aquest enllaç",
-	"Delete User": "Esborra Usuari",
-	"Deleted {{deleteModelTag}}": "Esborrat {{deleteModelTag}}",
-	"Deleted {{name}}": "Suprimit {{nom}}",
+	"Default Prompt Suggestions": "Suggeriments d'indicació per defecte",
+	"Default User Role": "Rol d'usuari per defecte",
+	"delete": "eliminar",
+	"Delete": "Eliminar",
+	"Delete a model": "Eliminar un model",
+	"Delete All Chats": "Eliminar tots els xats",
+	"Delete chat": "Eliminar xat",
+	"Delete Chat": "Eliminar xat",
+	"Delete chat?": "Eliminar el xat?",
+	"delete this link": "Eliminar aquest enllaç",
+	"Delete User": "Eliminar usuari",
+	"Deleted {{deleteModelTag}}": "S'ha eliminat {{deleteModelTag}}",
+	"Deleted {{name}}": "S'ha eliminat {{name}}",
 	"Description": "Descripció",
 	"Description": "Descripció",
-	"Didn't fully follow instructions": "No s'ha completat els instruccions",
-	"Discover a model": "Descobreix un model",
-	"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 Emoji in Call": "",
-	"Display the username instead of You in the Chat": "Mostra el nom d'usuari en lloc de 'Tu' al Xat",
+	"Didn't fully follow instructions": "No s'han seguit les instruccions completament",
+	"Discover a function": "",
+	"Discover a model": "Descobrir un model",
+	"Discover a prompt": "Descobrir una indicació",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
+	"Discover, download, and explore custom prompts": "Descobrir, descarregar i explorar indicacions personalitzades",
+	"Discover, download, and explore custom tools": "",
+	"Discover, download, and explore model presets": "Descobrir, descarregar i explorar models preconfigurats",
+	"Dismissible": "Descartable",
+	"Display Emoji in Call": "Mostrar emojis a la trucada",
+	"Display the username instead of You in the Chat": "Mostrar el nom d'usuari en lloc de 'Tu' al xat",
 	"Document": "Document",
 	"Document": "Document",
-	"Document Settings": "Configuració de Documents",
-	"Documentation": "",
+	"Document Settings": "Configuració de documents",
+	"Documentation": "Documentació",
 	"Documents": "Documents",
 	"Documents": "Documents",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.",
 	"does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.",
-	"Don't Allow": "No Permetre",
+	"Don't Allow": "No permetre",
 	"Don't have an account?": "No tens un compte?",
 	"Don't have an account?": "No tens un compte?",
 	"Don't like the style": "No t'agrada l'estil?",
 	"Don't like the style": "No t'agrada l'estil?",
+	"Done": "",
 	"Download": "Descarregar",
 	"Download": "Descarregar",
 	"Download canceled": "Descàrrega cancel·lada",
 	"Download canceled": "Descàrrega cancel·lada",
-	"Download Database": "Descarrega Base de Dades",
+	"Download Database": "Descarregar la base de dades",
 	"Drop any files here to add to the conversation": "Deixa qualsevol arxiu aquí per afegir-lo a la conversa",
 	"Drop any files here to add to the conversation": "Deixa qualsevol arxiu aquí per afegir-lo a la conversa",
 	"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ex. '30s','10m'. Les unitats de temps vàlides són 's', 'm', 'h'.",
 	"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ex. '30s','10m'. Les unitats de temps vàlides són 's', 'm', 'h'.",
 	"Edit": "Editar",
 	"Edit": "Editar",
-	"Edit Doc": "Edita Document",
-	"Edit Memory": "",
-	"Edit User": "Edita Usuari",
+	"Edit Doc": "Editar el document",
+	"Edit Memory": "Editar la memòria",
+	"Edit User": "Editar l'usuari",
 	"Email": "Correu electrònic",
 	"Email": "Correu electrònic",
-	"Embedding Batch Size": "",
-	"Embedding Model": "Model d'embutiment",
-	"Embedding Model Engine": "Motor de model d'embutiment",
-	"Embedding model set to \"{{embedding_model}}\"": "Model d'embutiment configurat a \"{{embedding_model}}\"",
-	"Enable Chat History": "Activa Historial de Xat",
-	"Enable Community Sharing": "Activar l'ús compartit de la comunitat",
-	"Enable New Sign Ups": "Permet Noves Inscripcions",
-	"Enable Web Search": "Activa la cerca web",
-	"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Assegura't que el fitxer CSV inclou 4 columnes en aquest ordre: Nom, Correu Electrònic, Contrasenya, Rol.",
+	"Embedding Batch Size": "Mida del lot d'incrustació",
+	"Embedding Model": "Model d'incrustació",
+	"Embedding Model Engine": "Motor de model d'incrustació",
+	"Embedding model set to \"{{embedding_model}}\"": "Model d'incrustació configurat a \"{{embedding_model}}\"",
+	"Enable Chat History": "Activar l'historial de xats",
+	"Enable Community Sharing": "Activar l'ús compartit amb la comunitat",
+	"Enable New Sign Ups": "Permetre nous registres",
+	"Enable Web Search": "Activar la cerca web",
+	"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Assegura't que els teus fitxers CSV inclouen 4 columnes en aquest ordre: Nom, Correu electrònic, Contrasenya, Rol.",
 	"Enter {{role}} message here": "Introdueix aquí el missatge de {{role}}",
 	"Enter {{role}} message here": "Introdueix aquí el missatge de {{role}}",
-	"Enter a detail about yourself for your LLMs to recall": "Introdueix un detall sobre tu per que els LLMs puguin recordar-te",
-	"Enter Brave Search API Key": "Introduïu la clau de l'API Brave Search",
-	"Enter Chunk Overlap": "Introdueix el Solapament de Blocs",
-	"Enter Chunk Size": "Introdueix la Mida del Bloc",
-	"Enter Github Raw URL": "Introduïu l'URL en brut de Github",
-	"Enter Google PSE API Key": "Introduïu la clau de l'API de Google PSE",
-	"Enter Google PSE Engine Id": "Introduïu l'identificador del motor PSE de Google",
-	"Enter Image Size (e.g. 512x512)": "Introdueix la Mida de la Imatge (p. ex. 512x512)",
+	"Enter a detail about yourself for your LLMs to recall": "Introdueix un detall sobre tu què els teus models de llenguatge puguin recordar",
+	"Enter Brave Search API Key": "Introdueix la clau API de Brave Search",
+	"Enter Chunk Overlap": "Introdueix la mida de solapament de blocs",
+	"Enter Chunk Size": "Introdueix la mida del bloc",
+	"Enter Github Raw URL": "Introdueix l'URL en brut de Github",
+	"Enter Google PSE API Key": "Introdueix la clau API de Google PSE",
+	"Enter Google PSE Engine Id": "Introdueix l'identificador del motor PSE de Google",
+	"Enter Image Size (e.g. 512x512)": "Introdueix la mida de la imatge (p. ex. 512x512)",
 	"Enter language codes": "Introdueix els codis de llenguatge",
 	"Enter language codes": "Introdueix els codis de llenguatge",
 	"Enter model tag (e.g. {{modelTag}})": "Introdueix l'etiqueta del model (p. ex. {{modelTag}})",
 	"Enter model tag (e.g. {{modelTag}})": "Introdueix l'etiqueta del model (p. ex. {{modelTag}})",
-	"Enter Number of Steps (e.g. 50)": "Introdueix el Nombre de Passos (p. ex. 50)",
-	"Enter Score": "Introdueix el Puntuació",
-	"Enter Searxng Query URL": "Introduïu l'URL de consulta de Searxng",
-	"Enter Serper API Key": "Introduïu la clau de l'API Serper",
-	"Enter Serply API Key": "",
-	"Enter Serpstack API Key": "Introduïu la clau de l'API Serpstack",
+	"Enter Number of Steps (e.g. 50)": "Introdueix el nombre de passos (p. ex. 50)",
+	"Enter Score": "Introdueix la puntuació",
+	"Enter Searxng Query URL": "Introdueix l'URL de consulta de Searxng",
+	"Enter Serper API Key": "Introdueix la clau API Serper",
+	"Enter Serply API Key": "Introdueix la clau API Serply",
+	"Enter Serpstack API Key": "Introdueix la clau API Serpstack",
 	"Enter stop sequence": "Introdueix la seqüència de parada",
 	"Enter stop sequence": "Introdueix la seqüència de parada",
-	"Enter Tavily API Key": "",
+	"Enter Tavily API Key": "Introdueix la clau API de Tavily",
 	"Enter Top K": "Introdueix Top K",
 	"Enter Top K": "Introdueix Top K",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "Introdueix l'URL (p. ex. http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "Introdueix l'URL (p. ex. http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://localhost:11434)": "Introdueix l'URL (p. ex. http://localhost:11434)",
 	"Enter URL (e.g. http://localhost:11434)": "Introdueix l'URL (p. ex. http://localhost:11434)",
-	"Enter Your Email": "Introdueix el Teu Correu Electrònic",
-	"Enter Your Full Name": "Introdueix el Teu Nom Complet",
-	"Enter Your Password": "Introdueix la Teva Contrasenya",
-	"Enter Your Role": "Introdueix el Teu Ròl",
+	"Enter Your Email": "Introdueix el teu correu electrònic",
+	"Enter Your Full Name": "Introdueix el teu nom complet",
+	"Enter Your Password": "Introdueix la teva contrasenya",
+	"Enter Your Role": "Introdueix el teu rol",
 	"Error": "Error",
 	"Error": "Error",
 	"Experimental": "Experimental",
 	"Experimental": "Experimental",
 	"Export": "Exportar",
 	"Export": "Exportar",
-	"Export All Chats (All Users)": "Exporta Tots els Xats (Tots els Usuaris)",
-	"Export chat (.json)": "",
-	"Export Chats": "Exporta Xats",
-	"Export Documents Mapping": "Exporta el Mapatge de Documents",
-	"Export Functions": "",
-	"Export Models": "Models d'exportació",
-	"Export Prompts": "Exporta Prompts",
-	"Export Tools": "",
-	"External Models": "",
-	"Failed to create API Key.": "No s'ha pogut crear la clau d'API.",
+	"Export All Chats (All Users)": "Exportar tots els xats (Tots els usuaris)",
+	"Export chat (.json)": "Exportar el xat (.json)",
+	"Export Chats": "Exportar els xats",
+	"Export Documents Mapping": "Exportar el mapatge de documents",
+	"Export Functions": "Exportar funcions",
+	"Export Models": "Exportar els models",
+	"Export Prompts": "Exportar les indicacions",
+	"Export Tools": "Exportar les eines",
+	"External Models": "Models externs",
+	"Failed to create API Key.": "No s'ha pogut crear la clau API.",
 	"Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls",
 	"Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls",
-	"Failed to update settings": "",
+	"Failed to update settings": "No s'ha pogut actualitzar la configuració",
 	"February": "Febrer",
 	"February": "Febrer",
-	"Feel free to add specific details": "Siusplau, afegeix detalls específics",
-	"File": "",
-	"File Mode": "Mode Arxiu",
-	"File not found.": "Arxiu no trobat.",
-	"Filters": "",
-	"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "S'ha detectat la suplantació d'identitat d'empremtes digitals: no es poden utilitzar les inicials com a avatar. Per defecte a la imatge de perfil predeterminada.",
-	"Fluidly stream large external response chunks": "Transmita con fluidez grandes fragmentos de respuesta externa",
-	"Focus chat input": "Enfoca l'entrada del xat",
-	"Followed instructions perfectly": "Siguiu les instruccions perfeicte",
-	"Form": "",
+	"Feel free to add specific details": "Sent-te lliure d'afegir detalls específics",
+	"File": "Arxiu",
+	"File Mode": "Mode d'arxiu",
+	"File not found.": "No s'ha trobat l'arxiu.",
+	"Filters": "Filtres",
+	"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "S'ha detectat la suplantació d'identitat de l'empremta digital: no es poden utilitzar les inicials com a avatar. S'estableix la imatge de perfil predeterminada.",
+	"Fluidly stream large external response chunks": "Transmetre amb fluïdesa grans trossos de resposta externa",
+	"Focus chat input": "Estableix el focus a l'entrada del xat",
+	"Followed instructions perfectly": "S'han seguit les instruccions perfectament",
+	"Form": "Formulari",
 	"Format your variables using square brackets like this:": "Formata les teves variables utilitzant claudàtors així:",
 	"Format your variables using square brackets like this:": "Formata les teves variables utilitzant claudàtors així:",
-	"Frequency Penalty": "Pena de freqüència",
-	"Functions": "",
+	"Frequency Penalty": "Penalització per freqüència",
+	"Functions": "Funcions",
 	"General": "General",
 	"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",
-	"Google PSE API Key": "Clau de l'API PSE de Google",
+	"General Settings": "Configuració general",
+	"Generate Image": "Generar imatge",
+	"Generating search query": "Generant consulta",
+	"Generation Info": "Informació sobre la generació",
+	"Good Response": "Bona resposta",
+	"Google PSE API Key": "Clau API PSE de Google",
 	"Google PSE Engine Id": "Identificador del motor PSE de Google",
 	"Google PSE Engine Id": "Identificador del motor PSE de Google",
 	"h:mm a": "h:mm a",
 	"h:mm a": "h:mm a",
 	"has no conversations.": "no té converses.",
 	"has no conversations.": "no té converses.",
 	"Hello, {{name}}": "Hola, {{name}}",
 	"Hello, {{name}}": "Hola, {{name}}",
 	"Help": "Ajuda",
 	"Help": "Ajuda",
 	"Hide": "Amaga",
 	"Hide": "Amaga",
-	"Hide Model": "",
+	"Hide Model": "Amagar el model",
 	"How can I help you today?": "Com et puc ajudar avui?",
 	"How can I help you today?": "Com et puc ajudar avui?",
-	"Hybrid Search": "Cerca Hibrida",
-	"Image Generation (Experimental)": "Generació d'Imatges (Experimental)",
-	"Image Generation Engine": "Motor de Generació d'Imatges",
-	"Image Settings": "Configuració d'Imatges",
+	"Hybrid Search": "Cerca brida",
+	"Image Generation (Experimental)": "Generació d'imatges (Experimental)",
+	"Image Generation Engine": "Motor de generació d'imatges",
+	"Image Settings": "Configuració d'imatges",
 	"Images": "Imatges",
 	"Images": "Imatges",
-	"Import Chats": "Importa Xats",
-	"Import Documents Mapping": "Importa el Mapa de Documents",
-	"Import Functions": "",
-	"Import Models": "Models d'importació",
-	"Import Prompts": "Importa Prompts",
-	"Import Tools": "",
-	"Include `--api` flag when running stable-diffusion-webui": "Inclou la bandera `--api` quan executis stable-diffusion-webui",
+	"Import Chats": "Importar xats",
+	"Import Documents Mapping": "Importar el mapatge de documents",
+	"Import Functions": "Importar funcions",
+	"Import Models": "Importar models",
+	"Import Prompts": "Importar indicacions",
+	"Import Tools": "Importar eines",
+	"Include `--api` flag when running stable-diffusion-webui": "Inclou `--api` quan executis stable-diffusion-webui",
 	"Info": "Informació",
 	"Info": "Informació",
-	"Input commands": "Entra ordres",
-	"Install from Github URL": "Instal·leu des de l'URL de Github",
-	"Instant Auto-Send After Voice Transcription": "",
+	"Input commands": "Entra comandes",
+	"Install from Github URL": "Instal·lar des de l'URL de Github",
+	"Instant Auto-Send After Voice Transcription": "Enviament automàtic després de la transcripció de veu",
 	"Interface": "Interfície",
 	"Interface": "Interfície",
-	"Invalid Tag": "Etiqueta Inválida",
+	"Invalid Tag": "Etiqueta no vàlida",
 	"January": "Gener",
 	"January": "Gener",
-	"join our Discord for help.": "uneix-te al nostre Discord per ajuda.",
+	"join our Discord for help.": "uneix-te al nostre Discord per obtenir ajuda.",
 	"JSON": "JSON",
 	"JSON": "JSON",
-	"JSON Preview": "Vista prèvia de JSON",
+	"JSON Preview": "Vista prèvia del document JSON",
 	"July": "Juliol",
 	"July": "Juliol",
 	"June": "Juny",
 	"June": "Juny",
-	"JWT Expiration": "Expiració de JWT",
+	"JWT Expiration": "Caducitat del JWT",
 	"JWT Token": "Token JWT",
 	"JWT Token": "Token JWT",
-	"Keep Alive": "Mantén Actiu",
-	"Keyboard shortcuts": "Dreceres de Teclat",
-	"Knowledge": "",
+	"Keep Alive": "Manté actiu",
+	"Keyboard shortcuts": "Dreceres de teclat",
+	"Knowledge": "Coneixement",
 	"Language": "Idioma",
 	"Language": "Idioma",
-	"Last Active": "Últim Actiu",
-	"Last Modified": "",
+	"Last Active": "Activitat recent",
+	"Last Modified": "Modificació",
 	"Light": "Clar",
 	"Light": "Clar",
-	"Listening...": "",
-	"LLMs can make mistakes. Verify important information.": "Els LLMs poden cometre errors. Verifica la informació important.",
-	"Local Models": "",
+	"Listening...": "Escoltant...",
+	"LLMs can make mistakes. Verify important information.": "Els models de llenguatge poden cometre errors. Verifica la informació important.",
+	"Local Models": "Models locals",
 	"LTR": "LTR",
 	"LTR": "LTR",
 	"Made by OpenWebUI Community": "Creat per la Comunitat OpenWebUI",
 	"Made by OpenWebUI Community": "Creat per la Comunitat OpenWebUI",
 	"Make sure to enclose them with": "Assegura't d'envoltar-los amb",
 	"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",
+	"Manage": "Gestionar",
+	"Manage Models": "Gestionar els models",
+	"Manage Ollama Models": "Gestionar els models Ollama",
+	"Manage Pipelines": "Gestionar les Pipelines",
+	"Manage Valves": "",
 	"March": "Març",
 	"March": "Març",
-	"Max Tokens (num_predict)": "Max Fitxes (num_predict)",
+	"Max Tokens (num_predict)": "Nombre màxim de Tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es poden descarregar un màxim de 3 models simultàniament. Si us plau, prova-ho més tard.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es poden descarregar un màxim de 3 models simultàniament. Si us plau, prova-ho més tard.",
 	"May": "Maig",
 	"May": "Maig",
-	"Memories accessible by LLMs will be shown here.": "Els memòries accessible per a LLMs es mostraran aquí.",
+	"Memories accessible by LLMs will be shown here.": "Les memòries accessibles pels models de llenguatge es mostraran aquí.",
 	"Memory": "Memòria",
 	"Memory": "Memòria",
-	"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Els missatges que envieu després de crear el vostre enllaç no es compartiran. Els usuaris amb l'URL podran veure el xat compartit.",
+	"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Els missatges enviats després de crear el teu enllaç no es compartiran. Els usuaris amb l'URL podran veure el xat compartit.",
 	"Minimum Score": "Puntuació mínima",
 	"Minimum Score": "Puntuació mínima",
 	"Mirostat": "Mirostat",
 	"Mirostat": "Mirostat",
 	"Mirostat Eta": "Eta de Mirostat",
 	"Mirostat Eta": "Eta de Mirostat",
 	"Mirostat Tau": "Tau de Mirostat",
 	"Mirostat Tau": "Tau de Mirostat",
 	"MMMM DD, YYYY": "DD de MMMM, YYYY",
 	"MMMM DD, YYYY": "DD de MMMM, YYYY",
 	"MMMM DD, YYYY HH:mm": "DD de MMMM, YYYY HH:mm",
 	"MMMM DD, YYYY HH:mm": "DD de MMMM, YYYY HH:mm",
-	"MMMM DD, YYYY hh:mm:ss A": "",
+	"MMMM DD, YYYY hh:mm:ss A": "DD de MMMM, YYYY HH:mm:ss, A",
 	"Model '{{modelName}}' has been successfully downloaded.": "El model '{{modelName}}' s'ha descarregat amb èxit.",
 	"Model '{{modelName}}' has been successfully downloaded.": "El model '{{modelName}}' s'ha descarregat amb èxit.",
 	"Model '{{modelTag}}' is already in queue for downloading.": "El model '{{modelTag}}' ja està en cua per ser descarregat.",
 	"Model '{{modelTag}}' is already in queue for downloading.": "El model '{{modelTag}}' ja està en cua per ser descarregat.",
-	"Model {{modelId}} not found": "Model {{modelId}} no trobat",
+	"Model {{modelId}} not found": "No s'ha trobat el model {{modelId}}",
 	"Model {{modelName}} is not vision capable": "El model {{modelName}} no és capaç de visió",
 	"Model {{modelName}} is not vision capable": "El model {{modelName}} no és capaç de visió",
-	"Model {{name}} is now {{status}}": "El model {{nom}} ara és {{estat}}",
-	"Model filesystem path detected. Model shortname is required for update, cannot continue.": "S'ha detectat el camí del sistema de fitxers del model. És necessari un nom curt del model per a actualitzar, no es pot continuar.",
+	"Model {{name}} is now {{status}}": "El model {{name}} ara és {{status}}",
+	"Model filesystem path detected. Model shortname is required for update, cannot continue.": "S'ha detectat el camí del sistema de fitxers del model. És necessari un nom curt del model per actualitzar, no es pot continuar.",
 	"Model ID": "Identificador del model",
 	"Model ID": "Identificador del model",
 	"Model not selected": "Model no seleccionat",
 	"Model not selected": "Model no seleccionat",
 	"Model Params": "Paràmetres del model",
 	"Model Params": "Paràmetres del model",
-	"Model Whitelisting": "Llista Blanca de Models",
-	"Model(s) Whitelisted": "Model(s) a la Llista Blanca",
-	"Modelfile Content": "Contingut del Fitxer de Model",
+	"Model Whitelisting": "Llista blanca de models",
+	"Model(s) Whitelisted": "Model(s) a la llista blanca",
+	"Modelfile Content": "Contingut del Modelfile",
 	"Models": "Models",
 	"Models": "Models",
 	"More": "Més",
 	"More": "Més",
 	"Name": "Nom",
 	"Name": "Nom",
-	"Name Tag": "Etiqueta de Nom",
-	"Name your model": "Posa un nom al model",
-	"New Chat": "Xat Nou",
-	"New Password": "Nova Contrasenya",
-	"No documents found": "",
+	"Name Tag": "Etiqueta de nom",
+	"Name your model": "Posa un nom al teu model",
+	"New Chat": "Nou xat",
+	"New Password": "Nova contrasenya",
+	"No documents found": "No s'han trobat documents",
 	"No results found": "No s'han trobat resultats",
 	"No results found": "No s'han trobat resultats",
-	"No search query generated": "No es genera cap consulta de cerca",
+	"No search query generated": "No s'ha generat cap consulta",
 	"No source available": "Sense font disponible",
 	"No source available": "Sense font disponible",
 	"None": "Cap",
 	"None": "Cap",
-	"Not factually correct": "No està clarament correcte",
-	"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Nota: Si establiscs una puntuació mínima, la cerca només retornarà documents amb una puntuació major o igual a la puntuació mínima.",
-	"Notifications": "Notificacions d'Escriptori",
+	"Not factually correct": "No és clarament correcte",
+	"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Nota: Si s'estableix una puntuació mínima, la cerca només retornarà documents amb una puntuació major o igual a la puntuació mínima.",
+	"Notifications": "Notificacions",
 	"November": "Novembre",
 	"November": "Novembre",
 	"num_thread (Ollama)": "num_thread (Ollama)",
 	"num_thread (Ollama)": "num_thread (Ollama)",
 	"OAuth ID": "",
 	"OAuth ID": "",
 	"October": "Octubre",
 	"October": "Octubre",
 	"Off": "Desactivat",
 	"Off": "Desactivat",
-	"Okay, Let's Go!": "D'acord, Anem!",
+	"Okay, Let's Go!": "D'acord, som-hi!",
 	"OLED Dark": "OLED Fosc",
 	"OLED Dark": "OLED Fosc",
 	"Ollama": "Ollama",
 	"Ollama": "Ollama",
 	"Ollama API": "API d'Ollama",
 	"Ollama API": "API d'Ollama",
-	"Ollama API disabled": "L'API d'Ollama desactivada",
-	"Ollama API is disabled": "",
+	"Ollama API disabled": "API d'Ollama desactivada",
+	"Ollama API is disabled": "L'API d'Ollama està desactivada",
 	"Ollama Version": "Versió d'Ollama",
 	"Ollama Version": "Versió d'Ollama",
 	"On": "Activat",
 	"On": "Activat",
 	"Only": "Només",
 	"Only": "Només",
-	"Only alphanumeric characters and hyphens are allowed in the command string.": "Només es permeten caràcters alfanumèrics i guions en la cadena de comandes.",
-	"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Ui! Aguanta! Els teus fitxers encara estan en el forn de processament. Els estem cuinant a la perfecció. Si us plau, tingues paciència i t'avisarem quan estiguin llestos.",
-	"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ui! Sembla que l'URL és invàlida. Si us plau, revisa-ho i prova de nou.",
-	"Oops! There was an error in the previous response. Please try again or contact admin.": "",
+	"Only alphanumeric characters and hyphens are allowed in the command string.": "Només es permeten caràcters alfanumèrics i guions en la comanda.",
+	"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Ep! Un moment! Els teus fitxers encara s'estan processant. Els estem cuinant a la perfecció. Si us plau, tingues paciència i t'avisarem quan estiguin preparats.",
+	"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ui! Sembla que l'URL no és vàlida. Si us plau, revisa-la i torna-ho a provar.",
+	"Oops! There was an error in the previous response. Please try again or contact admin.": "Ui! Hi ha hagut un error en la resposta anterior. Torna a provar-ho o contacta amb un administrador",
 	"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ui! Estàs utilitzant un mètode no suportat (només frontend). Si us plau, serveix la WebUI des del backend.",
 	"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ui! Estàs utilitzant un mètode no suportat (només frontend). Si us plau, serveix la WebUI des del backend.",
 	"Open": "Obre",
 	"Open": "Obre",
 	"Open AI": "Open AI",
 	"Open AI": "Open AI",
 	"Open AI (Dall-E)": "Open AI (Dall-E)",
 	"Open AI (Dall-E)": "Open AI (Dall-E)",
-	"Open new chat": "Obre un nou xat",
+	"Open new chat": "Obre un xat nou",
 	"OpenAI": "OpenAI",
 	"OpenAI": "OpenAI",
 	"OpenAI API": "API d'OpenAI",
 	"OpenAI API": "API d'OpenAI",
 	"OpenAI API Config": "Configuració de l'API d'OpenAI",
 	"OpenAI API Config": "Configuració de l'API d'OpenAI",
-	"OpenAI API Key is required.": "Es requereix la Clau API d'OpenAI.",
+	"OpenAI API Key is required.": "Es requereix la clau API d'OpenAI.",
 	"OpenAI URL/Key required.": "URL/Clau d'OpenAI requerides.",
 	"OpenAI URL/Key required.": "URL/Clau d'OpenAI requerides.",
 	"or": "o",
 	"or": "o",
 	"Other": "Altres",
 	"Other": "Altres",
 	"Password": "Contrasenya",
 	"Password": "Contrasenya",
 	"PDF document (.pdf)": "Document PDF (.pdf)",
 	"PDF document (.pdf)": "Document PDF (.pdf)",
-	"PDF Extract Images (OCR)": "Extreu Imatges de PDF (OCR)",
+	"PDF Extract Images (OCR)": "Extreu imatges del PDF (OCR)",
 	"pending": "pendent",
 	"pending": "pendent",
-	"Permission denied when accessing media devices": "",
-	"Permission denied when accessing microphone": "",
+	"Permission denied when accessing media devices": "Permís denegat en accedir a dispositius multimèdia",
+	"Permission denied when accessing microphone": "Permís denegat en accedir al micròfon",
 	"Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}",
 	"Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}",
 	"Personalization": "Personalització",
 	"Personalization": "Personalització",
-	"Pipelines": "Canonades",
-	"Pipelines Valves": "Vàlvules de canonades",
+	"Pipelines": "Pipelines",
+	"Pipelines Valves": "Vàlvules de les Pipelines",
 	"Plain text (.txt)": "Text pla (.txt)",
 	"Plain text (.txt)": "Text pla (.txt)",
-	"Playground": "Zona de Jocs",
-	"Positive attitude": "Attitudin positiva",
+	"Playground": "Zona de jocs",
+	"Positive attitude": "Actitud positiva",
 	"Previous 30 days": "30 dies anteriors",
 	"Previous 30 days": "30 dies anteriors",
 	"Previous 7 days": "7 dies anteriors",
 	"Previous 7 days": "7 dies anteriors",
 	"Profile Image": "Imatge de perfil",
 	"Profile Image": "Imatge de perfil",
-	"Prompt": "Prompt",
-	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Prompt (p.ex. diu-me un fàcte divertit sobre l'Imperi Roman)",
-	"Prompt Content": "Contingut del Prompt",
-	"Prompt suggestions": "Suggeriments de Prompt",
-	"Prompts": "Prompts",
-	"Pull \"{{searchValue}}\" from Ollama.com": "Treu \"{{searchValue}}\" de Ollama.com",
-	"Pull a model from Ollama.com": "Treu un model d'Ollama.com",
-	"Query Params": "Paràmetres de Consulta",
+	"Prompt": "Indicació",
+	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Indicació (p.ex. Digues-me quelcom divertit sobre l'Imperi Romà)",
+	"Prompt Content": "Contingut de la indicació",
+	"Prompt suggestions": "Suggeriments d'indicacions",
+	"Prompts": "Indicacions",
+	"Pull \"{{searchValue}}\" from Ollama.com": "Obtenir \"{{searchValue}}\" de Ollama.com",
+	"Pull a model from Ollama.com": "Obtenir un model d'Ollama.com",
+	"Query Params": "Paràmetres de consulta",
 	"RAG Template": "Plantilla RAG",
 	"RAG Template": "Plantilla RAG",
-	"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",
+	"Read Aloud": "Llegir en veu alta",
+	"Record voice": "Enregistrar la veu",
+	"Redirecting you to OpenWebUI Community": "Redirigint-te a la comunitat OpenWebUI",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Fes referència a tu mateix com a \"Usuari\" (p. ex., \"L'usuari està aprenent espanyol\")",
+	"Refused when it shouldn't have": "Refusat quan no hauria d'haver estat",
 	"Regenerate": "Regenerar",
 	"Regenerate": "Regenerar",
-	"Release Notes": "Notes de la Versió",
-	"Remove": "Elimina",
-	"Remove Model": "Elimina Model",
-	"Rename": "Canvia el nom",
-	"Repeat Last N": "Repeteix Últim N",
-	"Request Mode": "Mode de Sol·licitud",
-	"Reranking Model": "Model de Reranking desactivat",
-	"Reranking model disabled": "Model de Reranking desactivat",
-	"Reranking model set to \"{{reranking_model}}\"": "Model de Reranking establert a \"{{reranking_model}}\"",
-	"Reset": "",
-	"Reset Upload Directory": "",
-	"Reset Vector Storage": "Reinicia l'Emmagatzematge de Vectors",
-	"Response AutoCopy to Clipboard": "Resposta AutoCopiar al Portapapers",
+	"Release Notes": "Notes de la versió",
+	"Remove": "Eliminar",
+	"Remove Model": "Eliminar el model",
+	"Rename": "Canviar el nom",
+	"Repeat Last N": "Repeteix els darrers N",
+	"Request Mode": "Mode de sol·licitud",
+	"Reranking Model": "Model de reavaluació",
+	"Reranking model disabled": "Model de reavaluació desactivat",
+	"Reranking model set to \"{{reranking_model}}\"": "Model de reavaluació establert a \"{{reranking_model}}\"",
+	"Reset": "Restableix",
+	"Reset Upload Directory": "Restableix el directori de pujades",
+	"Reset Vector Storage": "Restableix l'emmagatzematge de vectors",
+	"Response AutoCopy to Clipboard": "Copiar la resposta automàticament al porta-retalls",
 	"Role": "Rol",
 	"Role": "Rol",
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine": "Rosé Pine",
 	"Rosé Pine Dawn": "Albada Rosé Pine",
 	"Rosé Pine Dawn": "Albada Rosé Pine",
 	"RTL": "RTL",
 	"RTL": "RTL",
-	"Running": "",
-	"Save": "Guarda",
-	"Save & Create": "Guarda i Crea",
-	"Save & Update": "Guarda i Actualitza",
-	"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Guardar registres de xat directament a l'emmagatzematge del teu navegador ja no és suportat. Si us plau, pren un moment per descarregar i eliminar els teus registres de xat fent clic al botó de sota. No et preocupis, pots reimportar fàcilment els teus registres de xat al backend a través de",
-	"Scan": "Escaneja",
-	"Scan complete!": "Escaneig completat!",
-	"Scan for documents from {{path}}": "Escaneja documents des de {{path}}",
-	"Search": "Cerca",
-	"Search a model": "Cerca un model",
+	"Running": "S'està executant",
+	"Save": "Desar",
+	"Save & Create": "Desar i crear",
+	"Save & Update": "Desar i actualitzar",
+	"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Desar els registres de xat directament a l'emmagatzematge del teu navegador ja no està suportat. Si us plau, descarregr i elimina els registres de xat fent clic al botó de sota. No et preocupis, pots tornar a importar fàcilment els teus registres de xat al backend a través de",
+	"Scan": "Escanejar",
+	"Scan complete!": "Escaneigr completat!",
+	"Scan for documents from {{path}}": "Escanejar documents des de {{path}}",
+	"Search": "Cercar",
+	"Search a model": "Cercar un model",
 	"Search Chats": "Cercar xats",
 	"Search Chats": "Cercar xats",
-	"Search Documents": "Cerca Documents",
-	"Search Functions": "",
-	"Search Models": "Models de cerca",
-	"Search Prompts": "Cerca Prompts",
-	"Search Query Generation Prompt": "",
-	"Search Query Generation Prompt Length Threshold": "",
+	"Search Documents": "Cercar documents",
+	"Search Functions": "Cercar funcions",
+	"Search Models": "Cercar models",
+	"Search Prompts": "Cercar indicacions",
+	"Search Query Generation Prompt": "Indicació de cerca de generació de consultes",
+	"Search Query Generation Prompt Length Threshold": "Mida màxima de la indicació de cerca de generació de consultes",
 	"Search Result Count": "Recompte de resultats de cerca",
 	"Search Result Count": "Recompte de resultats de cerca",
-	"Search Tools": "",
-	"Searched {{count}} sites_one": "Cercat {{count}} sites_one",
-	"Searched {{count}} sites_many": "Cercat {{recompte}} sites_many",
-	"Searched {{count}} sites_other": "Cercat {{recompte}} sites_other",
-	"Searching \"{{searchQuery}}\"": "",
-	"Searxng Query URL": "Searxng URL de consulta",
-	"See readme.md for instructions": "Consulta el readme.md per a instruccions",
-	"See what's new": "Veure novetats",
+	"Search Tools": "Cercar eines",
+	"Searched {{count}} sites_one": "S'ha cercat {{count}} una pàgina",
+	"Searched {{count}} sites_many": "S'han cercat {{count}} pàgines",
+	"Searched {{count}} sites_other": "S'han cercat {{count}} pàgines",
+	"Searching \"{{searchQuery}}\"": "Cercant \"{{searchQuery}}\"",
+	"Searxng Query URL": "URL de consulta de Searxng",
+	"See readme.md for instructions": "Consulta l'arxiu readme.md per obtenir instruccions",
+	"See what's new": "Veure què hi ha de nou",
 	"Seed": "Llavor",
 	"Seed": "Llavor",
 	"Select a base model": "Seleccionar un model base",
 	"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 Documents": "",
-	"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",
-	"Send message": "Envia missatge",
+	"Select a engine": "Seleccionar un motor",
+	"Select a function": "",
+	"Select a mode": "Seleccionar un mode",
+	"Select a model": "Seleccionar un model",
+	"Select a pipeline": "Seleccionar una Pipeline",
+	"Select a pipeline url": "Seleccionar l'URL d'una Pipeline",
+	"Select a tool": "",
+	"Select an Ollama instance": "Seleccionar una instància d'Ollama",
+	"Select Documents": "Seleccionar documents",
+	"Select model": "Seleccionar un model",
+	"Select only one model to call": "Seleccionar només un model per trucar",
+	"Selected model(s) do not support image inputs": "El(s) model(s) seleccionats no admeten l'entrada d'imatges",
+	"Send": "Enviar",
+	"Send a Message": "Enviar un missatge",
+	"Send message": "Enviar missatge",
 	"September": "Setembre",
 	"September": "Setembre",
-	"Serper API Key": "Clau API Serper",
-	"Serply API Key": "",
-	"Serpstack API Key": "Serpstack API Key",
+	"Serper API Key": "Clau API de Serper",
+	"Serply API Key": "Clau API de Serply",
+	"Serpstack API Key": "Clau API de Serpstack",
 	"Server connection verified": "Connexió al servidor verificada",
 	"Server connection verified": "Connexió al servidor verificada",
-	"Set as default": "Estableix com a predeterminat",
-	"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 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",
-	"Set Voice": "Estableix Veu",
+	"Set as default": "Establir com a predeterminat",
+	"Set Default Model": "Establir el model predeterminat",
+	"Set embedding model (e.g. {{model}})": "Establir el model d'incrustació (p.ex. {{model}})",
+	"Set Image Size": "Establir la mida de la image",
+	"Set reranking model (e.g. {{model}})": "Establir el model de reavaluació (p.ex. {{model}})",
+	"Set Steps": "Establir el nombre de passos",
+	"Set Task Model": "Establir el model de tasca",
+	"Set Voice": "Establir la veu",
 	"Settings": "Configuracions",
 	"Settings": "Configuracions",
-	"Settings saved successfully!": "Configuracions guardades amb èxit!",
-	"Settings updated successfully": "",
+	"Settings saved successfully!": "Les configuracions s'han desat amb èxit!",
+	"Settings updated successfully": "Les configuracions s'han actualitzat amb èxit",
 	"Share": "Compartir",
 	"Share": "Compartir",
-	"Share Chat": "Compartir el Chat",
-	"Share to OpenWebUI Community": "Comparteix amb la Comunitat OpenWebUI",
-	"short-summary": "resum curt",
-	"Show": "Mostra",
-	"Show Admin Details in Account Pending Overlay": "",
-	"Show Model": "",
-	"Show shortcuts": "Mostra dreceres",
-	"Showcased creativity": "Mostra la creativitat",
+	"Share Chat": "Compartir el xat",
+	"Share to OpenWebUI Community": "Compartir amb la comunitat OpenWebUI",
+	"short-summary": "resum breu",
+	"Show": "Mostrar",
+	"Show Admin Details in Account Pending Overlay": "Mostrar els detalls de l'administrador a la superposició del compte pendent",
+	"Show Model": "Mostrar el model",
+	"Show shortcuts": "Mostrar dreceres",
+	"Show your support!": "",
+	"Showcased creativity": "Creativitat mostrada",
 	"sidebar": "barra lateral",
 	"sidebar": "barra lateral",
-	"Sign in": "Inicia sessió",
-	"Sign Out": "Tanca sessió",
-	"Sign up": "Registra't",
+	"Sign in": "Iniciar sessió",
+	"Sign Out": "Tancar sessió",
+	"Sign up": "Registrar-se",
 	"Signing in": "Iniciant sessió",
 	"Signing in": "Iniciant sessió",
 	"Source": "Font",
 	"Source": "Font",
 	"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
 	"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
-	"Speech-to-Text Engine": "Motor de Veu a Text",
-	"Stop Sequence": "Atura Seqüència",
-	"STT Model": "",
-	"STT Settings": "Configuracions STT",
-	"Submit": "Envia",
+	"Speech-to-Text Engine": "Motor de veu a text",
+	"Stop Sequence": "Atura la seqüència",
+	"STT Model": "Model SST",
+	"STT Settings": "Configuracions de STT",
+	"Submit": "Enviar",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítol (per exemple, sobre l'Imperi Romà)",
 	"Subtitle (e.g. about the Roman Empire)": "Subtítol (per exemple, sobre l'Imperi Romà)",
 	"Success": "Èxit",
 	"Success": "Èxit",
 	"Successfully updated.": "Actualitzat amb èxit.",
 	"Successfully updated.": "Actualitzat amb èxit.",
 	"Suggested": "Suggerit",
 	"Suggested": "Suggerit",
 	"System": "Sistema",
 	"System": "Sistema",
-	"System Prompt": "Prompt del Sistema",
+	"System Prompt": "Indicació del Sistema",
 	"Tags": "Etiquetes",
 	"Tags": "Etiquetes",
-	"Tap to interrupt": "",
-	"Tavily API Key": "",
-	"Tell us more:": "Dóna'ns més informació:",
+	"Tap to interrupt": "Prem per interrompre",
+	"Tavily API Key": "Clau API de Tavily",
+	"Tell us more:": "Dona'ns més informació:",
 	"Temperature": "Temperatura",
 	"Temperature": "Temperatura",
 	"Template": "Plantilla",
 	"Template": "Plantilla",
-	"Text Completion": "Completació de Text",
-	"Text-to-Speech Engine": "Motor de Text a Veu",
+	"Text Completion": "Completament de text",
+	"Text-to-Speech Engine": "Motor de text a veu",
 	"Tfs Z": "Tfs Z",
 	"Tfs Z": "Tfs Z",
 	"Thanks for your feedback!": "Gràcies pel teu comentari!",
 	"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%).",
+	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "El valor de puntuació hauria de ser entre 0.0 (0%) i 1.0 (100%).",
 	"Theme": "Tema",
 	"Theme": "Tema",
-	"Thinking...": "",
-	"This action cannot be undone. Do you wish to continue?": "",
-	"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.": "",
+	"Thinking...": "Pensant...",
+	"This action cannot be undone. Do you wish to continue?": "Aquesta acció no es pot desfer. Vols continuar?",
+	"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Això assegura que les teves converses valuoses queden desades de manera segura a la teva base de dades. Gràcies!",
+	"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Aquesta és una funció experimental, és possible que no funcioni com s'espera i està subjecta a canvis en qualsevol moment.",
 	"This setting does not sync across browsers or devices.": "Aquesta configuració no es sincronitza entre navegadors ni dispositius.",
 	"This setting does not sync across browsers or devices.": "Aquesta configuració no es sincronitza entre navegadors ni dispositius.",
-	"This will delete": "",
-	"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.",
+	"This will delete": "Això eliminarà",
+	"Thorough explanation": "Explicació en detall",
+	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Consell: Actualitza les diverses variables consecutivament prement la tecla de tabulació en l'entrada del xat després de cada reemplaçament.",
 	"Title": "Títol",
 	"Title": "Títol",
-	"Title (e.g. Tell me a fun fact)": "Títol (p. ex. diu-me un fet divertit)",
-	"Title Auto-Generation": "Auto-Generació de Títol",
+	"Title (e.g. Tell me a fun fact)": "Títol (p. ex. Digues-me quelcom divertit)",
+	"Title Auto-Generation": "Generació automàtica de títol",
 	"Title cannot be an empty string.": "El títol no pot ser una cadena buida.",
 	"Title cannot be an empty string.": "El títol no pot ser una cadena buida.",
-	"Title Generation Prompt": "Prompt de Generació de Títol",
+	"Title Generation Prompt": "Indicació de generació de títol",
 	"to": "a",
 	"to": "a",
 	"To access the available model names for downloading,": "Per accedir als noms dels models disponibles per descarregar,",
 	"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 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 add documents here, upload them to the \"Documents\" workspace first.": "",
+	"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Per accedir a la WebUI, poseu-vos en contacte amb l'administrador. Els administradors poden gestionar els estats dels usuaris des del tauler d'administració.",
+	"To add documents here, upload them to the \"Documents\" workspace first.": "Per afegir documents aquí, puja-ls primer a l'espai de treball \"Documents\".",
 	"to chat input.": "a l'entrada del xat.",
 	"to chat input.": "a l'entrada del xat.",
-	"To select filters here, add them to the \"Functions\" workspace first.": "",
-	"To select toolkits here, add them to the \"Tools\" workspace first.": "",
+	"To select filters here, add them to the \"Functions\" workspace first.": "Per seleccionar filtres aquí, afegeix-los primer a l'espai de treball \"Funcions\".",
+	"To select toolkits here, add them to the \"Tools\" workspace first.": "Per seleccionar kits d'eines aquí, afegeix-los primer a l'espai de treball \"Eines\".",
 	"Today": "Avui",
 	"Today": "Avui",
-	"Toggle settings": "Commuta configuracions",
-	"Toggle sidebar": "Commuta barra lateral",
-	"Tokens To Keep On Context Refresh (num_keep)": "",
-	"Tools": "",
+	"Toggle settings": "Alterna configuracions",
+	"Toggle sidebar": "Alterna la barra lateral",
+	"Tokens To Keep On Context Refresh (num_keep)": "Tokens a mantenir en l'actualització del context (num_keep)",
+	"Tools": "Eines",
 	"Top K": "Top K",
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Top P": "Top P",
-	"Trouble accessing Ollama?": "Problemes accedint a Ollama?",
-	"TTS Model": "",
+	"Trouble accessing Ollama?": "Problemes en accedir a Ollama?",
+	"TTS Model": "Model TTS",
 	"TTS Settings": "Configuracions TTS",
 	"TTS Settings": "Configuracions TTS",
-	"TTS Voice": "",
+	"TTS Voice": "Veu TTS",
 	"Type": "Tipus",
 	"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}}.",
-	"UI": "",
+	"Type Hugging Face Resolve (Download) URL": "Escriu l'URL de Resolució (Descàrrega) de Hugging Face",
+	"Uh-oh! There was an issue connecting to {{provider}}.": "Oh! Hi ha hagut un problema connectant a {{provider}}.",
+	"UI": "UI",
 	"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "",
 	"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "",
-	"Update": "",
-	"Update and Copy Link": "Actualitza i Copia enllaç",
-	"Update password": "Actualitza contrasenya",
-	"Updated at": "",
-	"Upload": "",
-	"Upload a GGUF model": "Puja un model GGUF",
+	"Update": "Actualitzar",
+	"Update and Copy Link": "Actualitzar i copiar l'enllaç",
+	"Update password": "Actualitzar la contrasenya",
+	"Updated at": "Actualitzat",
+	"Upload": "Pujar",
+	"Upload a GGUF model": "Pujar un model GGUF",
 	"Upload Files": "Pujar fitxers",
 	"Upload Files": "Pujar fitxers",
-	"Upload Pipeline": "",
-	"Upload Progress": "Progrés de Càrrega",
+	"Upload Pipeline": "Pujar una Pipeline",
+	"Upload Progress": "Progrés de càrrega",
 	"URL Mode": "Mode URL",
 	"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.",
-	"Use Gravatar": "Utilitza Gravatar",
-	"Use Initials": "Utilitza Inicials",
+	"Use '#' in the prompt input to load and select your documents.": "Utilitza '#' a l'entrada de la indicació per carregar i seleccionar els teus documents.",
+	"Use Gravatar": "Utilitzar Gravatar",
+	"Use Initials": "Utilitzar inicials",
 	"use_mlock (Ollama)": "use_mlock (Ollama)",
 	"use_mlock (Ollama)": "use_mlock (Ollama)",
 	"use_mmap (Ollama)": "use_mmap (Ollama)",
 	"use_mmap (Ollama)": "use_mmap (Ollama)",
 	"user": "usuari",
 	"user": "usuari",
-	"User Permissions": "Permisos d'Usuari",
+	"User Permissions": "Permisos d'usuari",
 	"Users": "Usuaris",
 	"Users": "Usuaris",
-	"Utilize": "Utilitza",
+	"Utilize": "Utilitzar",
 	"Valid time units:": "Unitats de temps vàlides:",
 	"Valid time units:": "Unitats de temps vàlides:",
+	"Valves": "",
 	"variable": "variable",
 	"variable": "variable",
 	"variable to have them replaced with clipboard content.": "variable per tenir-les reemplaçades amb el contingut del porta-retalls.",
 	"variable to have them replaced with clipboard content.": "variable per tenir-les reemplaçades amb el contingut del porta-retalls.",
 	"Version": "Versió",
 	"Version": "Versió",
-	"Voice": "",
-	"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.",
+	"Voice": "Veu",
+	"Warning": "Avís",
+	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Avís: Si s'actualitza o es canvia el model d'incrustació, s'hauran de tornar a importar tots els documents.",
 	"Web": "Web",
 	"Web": "Web",
-	"Web API": "",
+	"Web API": "Web API",
 	"Web Loader Settings": "Configuració del carregador web",
 	"Web Loader Settings": "Configuració del carregador web",
 	"Web Params": "Paràmetres web",
 	"Web Params": "Paràmetres web",
-	"Web Search": "Cercador web",
-	"Web Search Engine": "Cercador web",
+	"Web Search": "Cerca la web",
+	"Web Search Engine": "Motor de cerca de la web",
 	"Webhook URL": "URL del webhook",
 	"Webhook URL": "URL del webhook",
-	"WebUI Settings": "Configuració de WebUI",
+	"WebUI Settings": "Configuracions de WebUI",
 	"WebUI will make requests to": "WebUI farà peticions a",
 	"WebUI will make requests to": "WebUI farà peticions a",
-	"What’s New in": "Què hi ha de Nou en",
+	"What’s New in": "Què hi ha de nou a",
 	"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.",
 	"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)": "",
-	"Widescreen Mode": "",
-	"Workspace": "Treball",
-	"Write a prompt suggestion (e.g. Who are you?)": "Escriu una suggerència de prompt (p. ex. Qui ets tu?)",
+	"Whisper (Local)": "Whisper (local)",
+	"Widescreen Mode": "Mode de pantalla ampla",
+	"Workspace": "Espai de treball",
+	"Write a prompt suggestion (e.g. Who are you?)": "Escriu una suggerència d'indicació (p. ex. Qui ets?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "Escriu un resum en 50 paraules que resumeixi [tema o paraula clau].",
 	"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",
+	"Yesterday": "Ahir",
 	"You": "Tu",
 	"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 can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pots personalitzar les teves interaccions amb els models de llenguatge afegint memòries mitjançant el botó 'Gestiona' que hi ha a continuació, fent-les més útils i adaptades a tu.",
 	"You cannot clone a base model": "No es pot clonar un model base",
 	"You cannot clone a base model": "No es pot clonar un model base",
 	"You have no archived conversations.": "No tens converses arxivades.",
 	"You have no archived conversations.": "No tens converses arxivades.",
 	"You have shared this chat": "Has compartit aquest xat",
 	"You have shared this chat": "Has compartit aquest xat",
 	"You're a helpful assistant.": "Ets un assistent útil.",
 	"You're a helpful assistant.": "Ets un assistent útil.",
 	"You're now logged in.": "Ara estàs connectat.",
 	"You're now logged in.": "Ara estàs connectat.",
-	"Your account status is currently pending activation.": "",
+	"Your account status is currently pending activation.": "El compte està actualment pendent d'activació",
 	"Youtube": "Youtube",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Configuració del carregador de Youtube"
 	"Youtube Loader Settings": "Configuració del carregador de Youtube"
 }
 }

+ 11 - 0
src/lib/i18n/locales/ceb-PH/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Tugoti nga mapapas ang mga chat",
 	"Allow Chat Deletion": "Tugoti nga mapapas ang mga chat",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alphanumeric nga mga karakter ug hyphen",
 	"alphanumeric characters and hyphens": "alphanumeric nga mga karakter ug hyphen",
 	"Already have an account?": "Naa na kay account ?",
 	"Already have an account?": "Naa na kay account ?",
 	"an assistant": "usa ka katabang",
 	"an assistant": "usa ka katabang",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "Deskripsyon",
 	"Description": "Deskripsyon",
 	"Didn't fully follow instructions": "",
 	"Didn't fully follow instructions": "",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "Pagkaplag usa ka prompt",
 	"Discover a prompt": "Pagkaplag usa ka prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Pagdiskubre, pag-download ug pagsuhid sa mga naandan nga pag-aghat",
 	"Discover, download, and explore custom prompts": "Pagdiskubre, pag-download ug pagsuhid sa mga naandan nga pag-aghat",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Pagdiskobre, pag-download, ug pagsuhid sa mga preset sa template",
 	"Discover, download, and explore model presets": "Pagdiskobre, pag-download, ug pagsuhid sa mga preset sa template",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Dili tugotan",
 	"Don't Allow": "Dili tugotan",
 	"Don't have an account?": "Wala kay account ?",
 	"Don't have an account?": "Wala kay account ?",
 	"Don't like the style": "",
 	"Don't like the style": "",
+	"Done": "",
 	"Download": "",
 	"Download": "",
 	"Download canceled": "",
 	"Download canceled": "",
 	"Download Database": "I-download ang database",
 	"Download Database": "I-download ang database",
@@ -312,6 +318,7 @@
 	"Manage Models": "Pagdumala sa mga templates",
 	"Manage Models": "Pagdumala sa mga templates",
 	"Manage Ollama Models": "Pagdumala sa mga modelo sa Ollama",
 	"Manage Ollama Models": "Pagdumala sa mga modelo sa Ollama",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "",
 	"March": "",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Ang labing taas nga 3 nga mga disenyo mahimong ma-download nga dungan. ",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Ang labing taas nga 3 nga mga disenyo mahimong ma-download nga dungan. ",
@@ -459,10 +466,12 @@
 	"Seed": "Binhi",
 	"Seed": "Binhi",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Pagpili og mode",
 	"Select a mode": "Pagpili og mode",
 	"Select a model": "Pagpili og modelo",
 	"Select a model": "Pagpili og modelo",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "Pagpili usa ka pananglitan sa Ollama",
 	"Select an Ollama instance": "Pagpili usa ka pananglitan sa Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Pagpili og modelo",
 	"Select model": "Pagpili og modelo",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Ipakita ang mga shortcut",
 	"Show shortcuts": "Ipakita ang mga shortcut",
+	"Show your support!": "",
 	"Showcased creativity": "",
 	"Showcased creativity": "",
 	"sidebar": "lateral bar",
 	"sidebar": "lateral bar",
 	"Sign in": "Para maka log in",
 	"Sign in": "Para maka log in",
@@ -583,6 +593,7 @@
 	"Users": "Mga tiggamit",
 	"Users": "Mga tiggamit",
 	"Utilize": "Sa paggamit",
 	"Utilize": "Sa paggamit",
 	"Valid time units:": "Balido nga mga yunit sa oras:",
 	"Valid time units:": "Balido nga mga yunit sa oras:",
+	"Valves": "",
 	"variable": "variable",
 	"variable": "variable",
 	"variable to have them replaced with clipboard content.": "variable aron pulihan kini sa mga sulud sa clipboard.",
 	"variable to have them replaced with clipboard content.": "variable aron pulihan kini sa mga sulud sa clipboard.",
 	"Version": "Bersyon",
 	"Version": "Bersyon",

+ 11 - 0
src/lib/i18n/locales/de-DE/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Chat Löschung erlauben",
 	"Allow Chat Deletion": "Chat Löschung erlauben",
 	"Allow non-local voices": "Nicht-lokale Stimmen erlauben",
 	"Allow non-local voices": "Nicht-lokale Stimmen erlauben",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alphanumerische Zeichen und Bindestriche",
 	"alphanumeric characters and hyphens": "alphanumerische Zeichen und Bindestriche",
 	"Already have an account?": "Hast du vielleicht schon ein Account?",
 	"Already have an account?": "Hast du vielleicht schon ein Account?",
 	"an assistant": "ein Assistent",
 	"an assistant": "ein Assistent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Gelöscht {{name}}",
 	"Deleted {{name}}": "Gelöscht {{name}}",
 	"Description": "Beschreibung",
 	"Description": "Beschreibung",
 	"Didn't fully follow instructions": "Nicht genau den Answeisungen gefolgt",
 	"Didn't fully follow instructions": "Nicht genau den Answeisungen gefolgt",
+	"Discover a function": "",
 	"Discover a model": "Entdecken Sie ein Modell",
 	"Discover a model": "Entdecken Sie ein Modell",
 	"Discover a prompt": "Einen Prompt entdecken",
 	"Discover a prompt": "Einen Prompt entdecken",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Benutzerdefinierte Prompts entdecken, herunterladen und erkunden",
 	"Discover, download, and explore custom prompts": "Benutzerdefinierte Prompts entdecken, herunterladen und erkunden",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Modellvorgaben entdecken, herunterladen und erkunden",
 	"Discover, download, and explore model presets": "Modellvorgaben entdecken, herunterladen und erkunden",
 	"Dismissible": "ausblendbar",
 	"Dismissible": "ausblendbar",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Nicht erlauben",
 	"Don't Allow": "Nicht erlauben",
 	"Don't have an account?": "Hast du vielleicht noch kein Konto?",
 	"Don't have an account?": "Hast du vielleicht noch kein Konto?",
 	"Don't like the style": "Dir gefällt der Style nicht",
 	"Don't like the style": "Dir gefällt der Style nicht",
+	"Done": "",
 	"Download": "Herunterladen",
 	"Download": "Herunterladen",
 	"Download canceled": "Download abgebrochen",
 	"Download canceled": "Download abgebrochen",
 	"Download Database": "Datenbank herunterladen",
 	"Download Database": "Datenbank herunterladen",
@@ -312,6 +318,7 @@
 	"Manage Models": "Modelle verwalten",
 	"Manage Models": "Modelle verwalten",
 	"Manage Ollama Models": "Ollama-Modelle verwalten",
 	"Manage Ollama Models": "Ollama-Modelle verwalten",
 	"Manage Pipelines": "Verwalten von Pipelines",
 	"Manage Pipelines": "Verwalten von Pipelines",
+	"Manage Valves": "",
 	"March": "März",
 	"March": "März",
 	"Max Tokens (num_predict)": "Max. Token (num_predict)",
 	"Max Tokens (num_predict)": "Max. Token (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es können maximal 3 Modelle gleichzeitig heruntergeladen werden. Bitte versuche es später erneut.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es können maximal 3 Modelle gleichzeitig heruntergeladen werden. Bitte versuche es später erneut.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Wählen Sie ein Basismodell",
 	"Select a base model": "Wählen Sie ein Basismodell",
 	"Select a engine": "Wähle eine Engine",
 	"Select a engine": "Wähle eine Engine",
+	"Select a function": "",
 	"Select a mode": "Einen Modus auswählen",
 	"Select a mode": "Einen Modus auswählen",
 	"Select a model": "Ein Modell auswählen",
 	"Select a model": "Ein Modell auswählen",
 	"Select a pipeline": "Wählen Sie eine Pipeline aus",
 	"Select a pipeline": "Wählen Sie eine Pipeline aus",
 	"Select a pipeline url": "Auswählen einer Pipeline-URL",
 	"Select a pipeline url": "Auswählen einer Pipeline-URL",
+	"Select a tool": "",
 	"Select an Ollama instance": "Eine Ollama Instanz auswählen",
 	"Select an Ollama instance": "Eine Ollama Instanz auswählen",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Modell auswählen",
 	"Select model": "Modell auswählen",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
 	"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Verknüpfungen anzeigen",
 	"Show shortcuts": "Verknüpfungen anzeigen",
+	"Show your support!": "",
 	"Showcased creativity": "Kreativität zur Schau gestellt",
 	"Showcased creativity": "Kreativität zur Schau gestellt",
 	"sidebar": "Seitenleiste",
 	"sidebar": "Seitenleiste",
 	"Sign in": "Anmelden",
 	"Sign in": "Anmelden",
@@ -583,6 +593,7 @@
 	"Users": "Benutzer",
 	"Users": "Benutzer",
 	"Utilize": "Nutze die",
 	"Utilize": "Nutze die",
 	"Valid time units:": "Gültige Zeiteinheiten:",
 	"Valid time units:": "Gültige Zeiteinheiten:",
+	"Valves": "",
 	"variable": "Variable",
 	"variable": "Variable",
 	"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
 	"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
 	"Version": "Version",
 	"Version": "Version",

+ 11 - 0
src/lib/i18n/locales/dg-DG/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Allow Delete Chats",
 	"Allow Chat Deletion": "Allow Delete Chats",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "so alpha, many hyphen",
 	"alphanumeric characters and hyphens": "so alpha, many hyphen",
 	"Already have an account?": "Such account exists?",
 	"Already have an account?": "Such account exists?",
 	"an assistant": "such assistant",
 	"an assistant": "such assistant",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "Description",
 	"Description": "Description",
 	"Didn't fully follow instructions": "",
 	"Didn't fully follow instructions": "",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "Discover a prompt",
 	"Discover a prompt": "Discover a prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts",
 	"Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Discover, download, and explore model presets",
 	"Discover, download, and explore model presets": "Discover, download, and explore model presets",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Don't Allow",
 	"Don't Allow": "Don't Allow",
 	"Don't have an account?": "No account? Much sad.",
 	"Don't have an account?": "No account? Much sad.",
 	"Don't like the style": "",
 	"Don't like the style": "",
+	"Done": "",
 	"Download": "",
 	"Download": "",
 	"Download canceled": "",
 	"Download canceled": "",
 	"Download Database": "Download Database",
 	"Download Database": "Download Database",
@@ -312,6 +318,7 @@
 	"Manage Models": "Manage Wowdels",
 	"Manage Models": "Manage Wowdels",
 	"Manage Ollama Models": "Manage Ollama Wowdels",
 	"Manage Ollama Models": "Manage Ollama Wowdels",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "",
 	"March": "",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximum of 3 models can be downloaded simultaneously. Please try again later.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximum of 3 models can be downloaded simultaneously. Please try again later.",
@@ -461,10 +468,12 @@
 	"Seed": "Seed very plant",
 	"Seed": "Seed very plant",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Select a mode very choose",
 	"Select a mode": "Select a mode very choose",
 	"Select a model": "Select a model much choice",
 	"Select a model": "Select a model much choice",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "Select an Ollama instance very choose",
 	"Select an Ollama instance": "Select an Ollama instance very choose",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Select model much choice",
 	"Select model": "Select model much choice",
@@ -497,6 +506,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Show shortcuts much shortcut",
 	"Show shortcuts": "Show shortcuts much shortcut",
+	"Show your support!": "",
 	"Showcased creativity": "",
 	"Showcased creativity": "",
 	"sidebar": "sidebar much side",
 	"sidebar": "sidebar much side",
 	"Sign in": "Sign in very sign",
 	"Sign in": "Sign in very sign",
@@ -585,6 +595,7 @@
 	"Users": "Users much users",
 	"Users": "Users much users",
 	"Utilize": "Utilize very use",
 	"Utilize": "Utilize very use",
 	"Valid time units:": "Valid time units: much time",
 	"Valid time units:": "Valid time units: much time",
+	"Valves": "",
 	"variable": "variable very variable",
 	"variable": "variable very variable",
 	"variable to have them replaced with clipboard content.": "variable to have them replaced with clipboard content. Very replace.",
 	"variable to have them replaced with clipboard content.": "variable to have them replaced with clipboard content. Very replace.",
 	"Version": "Version much version",
 	"Version": "Version much version",

+ 11 - 0
src/lib/i18n/locales/en-GB/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "",
 	"Allow Chat Deletion": "",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "",
 	"alphanumeric characters and hyphens": "",
 	"Already have an account?": "",
 	"Already have an account?": "",
 	"an assistant": "",
 	"an assistant": "",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "",
 	"Description": "",
 	"Didn't fully follow instructions": "",
 	"Didn't fully follow instructions": "",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "",
 	"Discover a prompt": "",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "",
 	"Discover, download, and explore custom prompts": "",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "",
 	"Discover, download, and explore model presets": "",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "",
 	"Don't Allow": "",
 	"Don't have an account?": "",
 	"Don't have an account?": "",
 	"Don't like the style": "",
 	"Don't like the style": "",
+	"Done": "",
 	"Download": "",
 	"Download": "",
 	"Download canceled": "",
 	"Download canceled": "",
 	"Download Database": "",
 	"Download Database": "",
@@ -312,6 +318,7 @@
 	"Manage Models": "",
 	"Manage Models": "",
 	"Manage Ollama Models": "",
 	"Manage Ollama Models": "",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "",
 	"March": "",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
@@ -459,10 +466,12 @@
 	"Seed": "",
 	"Seed": "",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "",
 	"Select a mode": "",
 	"Select a model": "",
 	"Select a model": "",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "",
 	"Select an Ollama instance": "",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "",
 	"Select model": "",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "",
 	"Show shortcuts": "",
+	"Show your support!": "",
 	"Showcased creativity": "",
 	"Showcased creativity": "",
 	"sidebar": "",
 	"sidebar": "",
 	"Sign in": "",
 	"Sign in": "",
@@ -583,6 +593,7 @@
 	"Users": "",
 	"Users": "",
 	"Utilize": "",
 	"Utilize": "",
 	"Valid time units:": "",
 	"Valid time units:": "",
+	"Valves": "",
 	"variable": "",
 	"variable": "",
 	"variable to have them replaced with clipboard content.": "",
 	"variable to have them replaced with clipboard content.": "",
 	"Version": "",
 	"Version": "",

+ 11 - 0
src/lib/i18n/locales/en-US/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "",
 	"Allow Chat Deletion": "",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "",
 	"alphanumeric characters and hyphens": "",
 	"Already have an account?": "",
 	"Already have an account?": "",
 	"an assistant": "",
 	"an assistant": "",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "",
 	"Description": "",
 	"Didn't fully follow instructions": "",
 	"Didn't fully follow instructions": "",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "",
 	"Discover a prompt": "",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "",
 	"Discover, download, and explore custom prompts": "",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "",
 	"Discover, download, and explore model presets": "",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "",
 	"Don't Allow": "",
 	"Don't have an account?": "",
 	"Don't have an account?": "",
 	"Don't like the style": "",
 	"Don't like the style": "",
+	"Done": "",
 	"Download": "",
 	"Download": "",
 	"Download canceled": "",
 	"Download canceled": "",
 	"Download Database": "",
 	"Download Database": "",
@@ -312,6 +318,7 @@
 	"Manage Models": "",
 	"Manage Models": "",
 	"Manage Ollama Models": "",
 	"Manage Ollama Models": "",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "",
 	"March": "",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
@@ -459,10 +466,12 @@
 	"Seed": "",
 	"Seed": "",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "",
 	"Select a mode": "",
 	"Select a model": "",
 	"Select a model": "",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "",
 	"Select an Ollama instance": "",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "",
 	"Select model": "",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "",
 	"Show shortcuts": "",
+	"Show your support!": "",
 	"Showcased creativity": "",
 	"Showcased creativity": "",
 	"sidebar": "",
 	"sidebar": "",
 	"Sign in": "",
 	"Sign in": "",
@@ -583,6 +593,7 @@
 	"Users": "",
 	"Users": "",
 	"Utilize": "",
 	"Utilize": "",
 	"Valid time units:": "",
 	"Valid time units:": "",
+	"Valves": "",
 	"variable": "",
 	"variable": "",
 	"variable to have them replaced with clipboard content.": "",
 	"variable to have them replaced with clipboard content.": "",
 	"Version": "",
 	"Version": "",

+ 11 - 0
src/lib/i18n/locales/es-ES/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Permitir Borrar Chats",
 	"Allow Chat Deletion": "Permitir Borrar Chats",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos y guiones",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos y guiones",
 	"Already have an account?": "¿Ya tienes una cuenta?",
 	"Already have an account?": "¿Ya tienes una cuenta?",
 	"an assistant": "un asistente",
 	"an assistant": "un asistente",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Eliminado {{nombre}}",
 	"Deleted {{name}}": "Eliminado {{nombre}}",
 	"Description": "Descripción",
 	"Description": "Descripción",
 	"Didn't fully follow instructions": "No siguió las instrucciones",
 	"Didn't fully follow instructions": "No siguió las instrucciones",
+	"Discover a function": "",
 	"Discover a model": "Descubrir un modelo",
 	"Discover a model": "Descubrir un modelo",
 	"Discover a prompt": "Descubre un Prompt",
 	"Discover a prompt": "Descubre un Prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Descubre, descarga, y explora Prompts personalizados",
 	"Discover, download, and explore custom prompts": "Descubre, descarga, y explora Prompts personalizados",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Descubre, descarga y explora ajustes preestablecidos de modelos",
 	"Discover, download, and explore model presets": "Descubre, descarga y explora ajustes preestablecidos de modelos",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "No Permitir",
 	"Don't Allow": "No Permitir",
 	"Don't have an account?": "¿No tienes una cuenta?",
 	"Don't have an account?": "¿No tienes una cuenta?",
 	"Don't like the style": "No te gusta el estilo?",
 	"Don't like the style": "No te gusta el estilo?",
+	"Done": "",
 	"Download": "Descargar",
 	"Download": "Descargar",
 	"Download canceled": "Descarga cancelada",
 	"Download canceled": "Descarga cancelada",
 	"Download Database": "Descarga la Base de Datos",
 	"Download Database": "Descarga la Base de Datos",
@@ -312,6 +318,7 @@
 	"Manage Models": "Administrar Modelos",
 	"Manage Models": "Administrar Modelos",
 	"Manage Ollama Models": "Administrar Modelos Ollama",
 	"Manage Ollama Models": "Administrar Modelos Ollama",
 	"Manage Pipelines": "Administrar canalizaciones",
 	"Manage Pipelines": "Administrar canalizaciones",
+	"Manage Valves": "",
 	"March": "Marzo",
 	"March": "Marzo",
 	"Max Tokens (num_predict)": "Máximo de fichas (num_predict)",
 	"Max Tokens (num_predict)": "Máximo de fichas (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Se pueden descargar un máximo de 3 modelos simultáneamente. Por favor, inténtelo de nuevo más tarde.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Se pueden descargar un máximo de 3 modelos simultáneamente. Por favor, inténtelo de nuevo más tarde.",
@@ -460,10 +467,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Seleccionar un modelo base",
 	"Select a base model": "Seleccionar un modelo base",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Selecciona un modo",
 	"Select a mode": "Selecciona un modo",
 	"Select a model": "Selecciona un modelo",
 	"Select a model": "Selecciona un modelo",
 	"Select a pipeline": "Selección de una canalización",
 	"Select a pipeline": "Selección de una canalización",
 	"Select a pipeline url": "Selección de una dirección URL de canalización",
 	"Select a pipeline url": "Selección de una dirección URL de canalización",
+	"Select a tool": "",
 	"Select an Ollama instance": "Seleccione una instancia de Ollama",
 	"Select an Ollama instance": "Seleccione una instancia de Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Selecciona un modelo",
 	"Select model": "Selecciona un modelo",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Mostrar atajos",
 	"Show shortcuts": "Mostrar atajos",
+	"Show your support!": "",
 	"Showcased creativity": "Mostrar creatividad",
 	"Showcased creativity": "Mostrar creatividad",
 	"sidebar": "barra lateral",
 	"sidebar": "barra lateral",
 	"Sign in": "Iniciar sesión",
 	"Sign in": "Iniciar sesión",
@@ -584,6 +594,7 @@
 	"Users": "Usuarios",
 	"Users": "Usuarios",
 	"Utilize": "Utilizar",
 	"Utilize": "Utilizar",
 	"Valid time units:": "Unidades válidas de tiempo:",
 	"Valid time units:": "Unidades válidas de tiempo:",
+	"Valves": "",
 	"variable": "variable",
 	"variable": "variable",
 	"variable to have them replaced with clipboard content.": "variable para reemplazarlos con el contenido del portapapeles.",
 	"variable to have them replaced with clipboard content.": "variable para reemplazarlos con el contenido del portapapeles.",
 	"Version": "Versión",
 	"Version": "Versión",

+ 11 - 0
src/lib/i18n/locales/fa-IR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "اجازه حذف گپ",
 	"Allow Chat Deletion": "اجازه حذف گپ",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "حروف الفبایی و خط فاصله",
 	"alphanumeric characters and hyphens": "حروف الفبایی و خط فاصله",
 	"Already have an account?": "از قبل حساب کاربری دارید؟",
 	"Already have an account?": "از قبل حساب کاربری دارید؟",
 	"an assistant": "یک دستیار",
 	"an assistant": "یک دستیار",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "حذف شده {{name}}",
 	"Deleted {{name}}": "حذف شده {{name}}",
 	"Description": "توضیحات",
 	"Description": "توضیحات",
 	"Didn't fully follow instructions": "نمی تواند دستورالعمل را کامل پیگیری کند",
 	"Didn't fully follow instructions": "نمی تواند دستورالعمل را کامل پیگیری کند",
+	"Discover a function": "",
 	"Discover a model": "کشف یک مدل",
 	"Discover a model": "کشف یک مدل",
 	"Discover a prompt": "یک اعلان را کشف کنید",
 	"Discover a prompt": "یک اعلان را کشف کنید",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "پرامپت\u200cهای سفارشی را کشف، دانلود و کاوش کنید",
 	"Discover, download, and explore custom prompts": "پرامپت\u200cهای سفارشی را کشف، دانلود و کاوش کنید",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "پیش تنظیمات مدل را کشف، دانلود و کاوش کنید",
 	"Discover, download, and explore model presets": "پیش تنظیمات مدل را کشف، دانلود و کاوش کنید",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "اجازه نده",
 	"Don't Allow": "اجازه نده",
 	"Don't have an account?": "حساب کاربری ندارید؟",
 	"Don't have an account?": "حساب کاربری ندارید؟",
 	"Don't like the style": "نظری ندارید؟",
 	"Don't like the style": "نظری ندارید؟",
+	"Done": "",
 	"Download": "دانلود کن",
 	"Download": "دانلود کن",
 	"Download canceled": "دانلود لغو شد",
 	"Download canceled": "دانلود لغو شد",
 	"Download Database": "دانلود پایگاه داده",
 	"Download Database": "دانلود پایگاه داده",
@@ -312,6 +318,7 @@
 	"Manage Models": "مدیریت مدل\u200cها",
 	"Manage Models": "مدیریت مدل\u200cها",
 	"Manage Ollama Models": "مدیریت مدل\u200cهای اولاما",
 	"Manage Ollama Models": "مدیریت مدل\u200cهای اولاما",
 	"Manage Pipelines": "مدیریت خطوط لوله",
 	"Manage Pipelines": "مدیریت خطوط لوله",
+	"Manage Valves": "",
 	"March": "مارچ",
 	"March": "مارچ",
 	"Max Tokens (num_predict)": "توکنهای بیشینه (num_predict)",
 	"Max Tokens (num_predict)": "توکنهای بیشینه (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "حداکثر 3 مدل را می توان به طور همزمان دانلود کرد. لطفاً بعداً دوباره امتحان کنید.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "حداکثر 3 مدل را می توان به طور همزمان دانلود کرد. لطفاً بعداً دوباره امتحان کنید.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "انتخاب یک مدل پایه",
 	"Select a base model": "انتخاب یک مدل پایه",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "یک حالت انتخاب کنید",
 	"Select a mode": "یک حالت انتخاب کنید",
 	"Select a model": "انتخاب یک مدل",
 	"Select a model": "انتخاب یک مدل",
 	"Select a pipeline": "انتخاب یک خط لوله",
 	"Select a pipeline": "انتخاب یک خط لوله",
 	"Select a pipeline url": "یک ادرس خط لوله را انتخاب کنید",
 	"Select a pipeline url": "یک ادرس خط لوله را انتخاب کنید",
+	"Select a tool": "",
 	"Select an Ollama instance": "انتخاب یک نمونه از اولاما",
 	"Select an Ollama instance": "انتخاب یک نمونه از اولاما",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "انتخاب یک مدل",
 	"Select model": "انتخاب یک مدل",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "نمایش میانبرها",
 	"Show shortcuts": "نمایش میانبرها",
+	"Show your support!": "",
 	"Showcased creativity": "ایده\u200cآفرینی",
 	"Showcased creativity": "ایده\u200cآفرینی",
 	"sidebar": "نوار کناری",
 	"sidebar": "نوار کناری",
 	"Sign in": "ورود",
 	"Sign in": "ورود",
@@ -583,6 +593,7 @@
 	"Users": "کاربران",
 	"Users": "کاربران",
 	"Utilize": "استفاده کنید",
 	"Utilize": "استفاده کنید",
 	"Valid time units:": "واحدهای زمانی معتبر:",
 	"Valid time units:": "واحدهای زمانی معتبر:",
+	"Valves": "",
 	"variable": "متغیر",
 	"variable": "متغیر",
 	"variable to have them replaced with clipboard content.": "متغیر برای جایگزینی آنها با محتوای کلیپ بورد.",
 	"variable to have them replaced with clipboard content.": "متغیر برای جایگزینی آنها با محتوای کلیپ بورد.",
 	"Version": "نسخه",
 	"Version": "نسخه",

+ 11 - 0
src/lib/i18n/locales/fi-FI/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Salli keskustelujen poisto",
 	"Allow Chat Deletion": "Salli keskustelujen poisto",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "kirjaimia, numeroita ja väliviivoja",
 	"alphanumeric characters and hyphens": "kirjaimia, numeroita ja väliviivoja",
 	"Already have an account?": "Onko sinulla jo tili?",
 	"Already have an account?": "Onko sinulla jo tili?",
 	"an assistant": "avustaja",
 	"an assistant": "avustaja",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Poistettu {{nimi}}",
 	"Deleted {{name}}": "Poistettu {{nimi}}",
 	"Description": "Kuvaus",
 	"Description": "Kuvaus",
 	"Didn't fully follow instructions": "Ei noudattanut ohjeita täysin",
 	"Didn't fully follow instructions": "Ei noudattanut ohjeita täysin",
+	"Discover a function": "",
 	"Discover a model": "Tutustu malliin",
 	"Discover a model": "Tutustu malliin",
 	"Discover a prompt": "Löydä kehote",
 	"Discover a prompt": "Löydä kehote",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Löydä ja lataa mukautettuja kehotteita",
 	"Discover, download, and explore custom prompts": "Löydä ja lataa mukautettuja kehotteita",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Löydä ja lataa mallien esiasetuksia",
 	"Discover, download, and explore model presets": "Löydä ja lataa mallien esiasetuksia",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Älä salli",
 	"Don't Allow": "Älä salli",
 	"Don't have an account?": "Eikö sinulla ole tiliä?",
 	"Don't have an account?": "Eikö sinulla ole tiliä?",
 	"Don't like the style": "En pidä tyylistä",
 	"Don't like the style": "En pidä tyylistä",
+	"Done": "",
 	"Download": "Lataa",
 	"Download": "Lataa",
 	"Download canceled": "Lataus peruutettu",
 	"Download canceled": "Lataus peruutettu",
 	"Download Database": "Lataa tietokanta",
 	"Download Database": "Lataa tietokanta",
@@ -312,6 +318,7 @@
 	"Manage Models": "Hallitse malleja",
 	"Manage Models": "Hallitse malleja",
 	"Manage Ollama Models": "Hallitse Ollama-malleja",
 	"Manage Ollama Models": "Hallitse Ollama-malleja",
 	"Manage Pipelines": "Hallitse putkia",
 	"Manage Pipelines": "Hallitse putkia",
+	"Manage Valves": "",
 	"March": "maaliskuu",
 	"March": "maaliskuu",
 	"Max Tokens (num_predict)": "Tokenien enimmäismäärä (num_predict)",
 	"Max Tokens (num_predict)": "Tokenien enimmäismäärä (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Enintään 3 mallia voidaan ladata samanaikaisesti. Yritä myöhemmin uudelleen.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Enintään 3 mallia voidaan ladata samanaikaisesti. Yritä myöhemmin uudelleen.",
@@ -459,10 +466,12 @@
 	"Seed": "Siemen",
 	"Seed": "Siemen",
 	"Select a base model": "Valitse perusmalli",
 	"Select a base model": "Valitse perusmalli",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Valitse tila",
 	"Select a mode": "Valitse tila",
 	"Select a model": "Valitse malli",
 	"Select a model": "Valitse malli",
 	"Select a pipeline": "Valitse putki",
 	"Select a pipeline": "Valitse putki",
 	"Select a pipeline url": "Valitse putken URL-osoite",
 	"Select a pipeline url": "Valitse putken URL-osoite",
+	"Select a tool": "",
 	"Select an Ollama instance": "Valitse Ollama-instanssi",
 	"Select an Ollama instance": "Valitse Ollama-instanssi",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Valitse malli",
 	"Select model": "Valitse malli",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Näytä pikanäppäimet",
 	"Show shortcuts": "Näytä pikanäppäimet",
+	"Show your support!": "",
 	"Showcased creativity": "Näytti luovuutta",
 	"Showcased creativity": "Näytti luovuutta",
 	"sidebar": "sivupalkki",
 	"sidebar": "sivupalkki",
 	"Sign in": "Kirjaudu sisään",
 	"Sign in": "Kirjaudu sisään",
@@ -583,6 +593,7 @@
 	"Users": "Käyttäjät",
 	"Users": "Käyttäjät",
 	"Utilize": "Käytä",
 	"Utilize": "Käytä",
 	"Valid time units:": "Kelvolliset aikayksiköt:",
 	"Valid time units:": "Kelvolliset aikayksiköt:",
+	"Valves": "",
 	"variable": "muuttuja",
 	"variable": "muuttuja",
 	"variable to have them replaced with clipboard content.": "muuttuja korvataan leikepöydän sisällöllä.",
 	"variable to have them replaced with clipboard content.": "muuttuja korvataan leikepöydän sisällöllä.",
 	"Version": "Versio",
 	"Version": "Versio",

+ 11 - 0
src/lib/i18n/locales/fr-CA/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Autoriser la suppression des discussions",
 	"Allow Chat Deletion": "Autoriser la suppression des discussions",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
 	"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
 	"Already have an account?": "Vous avez déjà un compte ?",
 	"Already have an account?": "Vous avez déjà un compte ?",
 	"an assistant": "un assistant",
 	"an assistant": "un assistant",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Supprimé {{nom}}",
 	"Deleted {{name}}": "Supprimé {{nom}}",
 	"Description": "Description",
 	"Description": "Description",
 	"Didn't fully follow instructions": "Ne suit pas les instructions",
 	"Didn't fully follow instructions": "Ne suit pas les instructions",
+	"Discover a function": "",
 	"Discover a model": "Découvrez un modèle",
 	"Discover a model": "Découvrez un modèle",
 	"Discover a prompt": "Découvrir un prompt",
 	"Discover a prompt": "Découvrir un prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Ne pas autoriser",
 	"Don't Allow": "Ne pas autoriser",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"Don't like the style": "Vous n'aimez pas le style ?",
 	"Don't like the style": "Vous n'aimez pas le style ?",
+	"Done": "",
 	"Download": "Télécharger",
 	"Download": "Télécharger",
 	"Download canceled": "Téléchargement annulé",
 	"Download canceled": "Téléchargement annulé",
 	"Download Database": "Télécharger la base de données",
 	"Download Database": "Télécharger la base de données",
@@ -312,6 +318,7 @@
 	"Manage Models": "Gérer les modèles",
 	"Manage Models": "Gérer les modèles",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Pipelines": "Gérer les pipelines",
 	"Manage Pipelines": "Gérer les pipelines",
+	"Manage Valves": "",
 	"March": "Mars",
 	"March": "Mars",
 	"Max Tokens (num_predict)": "Max Tokens (num_predict)",
 	"Max Tokens (num_predict)": "Max Tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
@@ -460,10 +467,12 @@
 	"Seed": "Graine",
 	"Seed": "Graine",
 	"Select a base model": "Sélectionner un modèle de base",
 	"Select a base model": "Sélectionner un modèle de base",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Sélectionnez un mode",
 	"Select a mode": "Sélectionnez un mode",
 	"Select a model": "Sélectionnez un modèle",
 	"Select a model": "Sélectionnez un modèle",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Sélectionnez un modèle",
 	"Select model": "Sélectionnez un modèle",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Afficher les raccourcis",
 	"Show shortcuts": "Afficher les raccourcis",
+	"Show your support!": "",
 	"Showcased creativity": "Créativité affichée",
 	"Showcased creativity": "Créativité affichée",
 	"sidebar": "barre latérale",
 	"sidebar": "barre latérale",
 	"Sign in": "Se connecter",
 	"Sign in": "Se connecter",
@@ -584,6 +594,7 @@
 	"Users": "Utilisateurs",
 	"Users": "Utilisateurs",
 	"Utilize": "Utiliser",
 	"Utilize": "Utiliser",
 	"Valid time units:": "Unités de temps valides :",
 	"Valid time units:": "Unités de temps valides :",
+	"Valves": "",
 	"variable": "variable",
 	"variable": "variable",
 	"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
 	"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
 	"Version": "Version",
 	"Version": "Version",

+ 11 - 0
src/lib/i18n/locales/fr-FR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Autoriser la suppression du chat",
 	"Allow Chat Deletion": "Autoriser la suppression du chat",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
 	"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
 	"Already have an account?": "Vous avez déjà un compte ?",
 	"Already have an account?": "Vous avez déjà un compte ?",
 	"an assistant": "un assistant",
 	"an assistant": "un assistant",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}} supprimé",
 	"Deleted {{name}}": "{{name}} supprimé",
 	"Description": "Description",
 	"Description": "Description",
 	"Didn't fully follow instructions": "N'a pas suivi entièrement les instructions",
 	"Didn't fully follow instructions": "N'a pas suivi entièrement les instructions",
+	"Discover a function": "",
 	"Discover a model": "Découvrir un modèle",
 	"Discover a model": "Découvrir un modèle",
 	"Discover a prompt": "Découvrir un prompt",
 	"Discover a prompt": "Découvrir un prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
 	"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
 	"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Ne pas autoriser",
 	"Don't Allow": "Ne pas autoriser",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"Don't have an account?": "Vous n'avez pas de compte ?",
 	"Don't like the style": "N'aime pas le style",
 	"Don't like the style": "N'aime pas le style",
+	"Done": "",
 	"Download": "Télécharger",
 	"Download": "Télécharger",
 	"Download canceled": "Téléchargement annulé",
 	"Download canceled": "Téléchargement annulé",
 	"Download Database": "Télécharger la base de données",
 	"Download Database": "Télécharger la base de données",
@@ -312,6 +318,7 @@
 	"Manage Models": "Gérer les modèles",
 	"Manage Models": "Gérer les modèles",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Ollama Models": "Gérer les modèles Ollama",
 	"Manage Pipelines": "Gérer les pipelines",
 	"Manage Pipelines": "Gérer les pipelines",
+	"Manage Valves": "",
 	"March": "Mars",
 	"March": "Mars",
 	"Max Tokens (num_predict)": "Tokens maximaux (num_predict)",
 	"Max Tokens (num_predict)": "Tokens maximaux (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
@@ -460,10 +467,12 @@
 	"Seed": "Graine",
 	"Seed": "Graine",
 	"Select a base model": "Sélectionner un modèle de base",
 	"Select a base model": "Sélectionner un modèle de base",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Sélectionner un mode",
 	"Select a mode": "Sélectionner un mode",
 	"Select a model": "Sélectionner un modèle",
 	"Select a model": "Sélectionner un modèle",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline": "Sélectionner un pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
 	"Select a pipeline url": "Sélectionnez une URL de pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select an Ollama instance": "Sélectionner une instance Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Sélectionner un modèle",
 	"Select model": "Sélectionner un modèle",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Afficher les raccourcis",
 	"Show shortcuts": "Afficher les raccourcis",
+	"Show your support!": "",
 	"Showcased creativity": "Créativité affichée",
 	"Showcased creativity": "Créativité affichée",
 	"sidebar": "barre latérale",
 	"sidebar": "barre latérale",
 	"Sign in": "Se connecter",
 	"Sign in": "Se connecter",
@@ -584,6 +594,7 @@
 	"Users": "Utilisateurs",
 	"Users": "Utilisateurs",
 	"Utilize": "Utiliser",
 	"Utilize": "Utiliser",
 	"Valid time units:": "Unités de temps valides :",
 	"Valid time units:": "Unités de temps valides :",
+	"Valves": "",
 	"variable": "variable",
 	"variable": "variable",
 	"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
 	"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
 	"Version": "Version",
 	"Version": "Version",

+ 11 - 0
src/lib/i18n/locales/he-IL/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "אפשר מחיקת צ'אט",
 	"Allow Chat Deletion": "אפשר מחיקת צ'אט",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "תווים אלפאנומריים ומקפים",
 	"alphanumeric characters and hyphens": "תווים אלפאנומריים ומקפים",
 	"Already have an account?": "כבר יש לך חשבון?",
 	"Already have an account?": "כבר יש לך חשבון?",
 	"an assistant": "עוזר",
 	"an assistant": "עוזר",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "נמחק {{name}}",
 	"Deleted {{name}}": "נמחק {{name}}",
 	"Description": "תיאור",
 	"Description": "תיאור",
 	"Didn't fully follow instructions": "לא עקב אחרי ההוראות באופן מלא",
 	"Didn't fully follow instructions": "לא עקב אחרי ההוראות באופן מלא",
+	"Discover a function": "",
 	"Discover a model": "גלה מודל",
 	"Discover a model": "גלה מודל",
 	"Discover a prompt": "גלה פקודה",
 	"Discover a prompt": "גלה פקודה",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "גלה, הורד, וחקור פקודות מותאמות אישית",
 	"Discover, download, and explore custom prompts": "גלה, הורד, וחקור פקודות מותאמות אישית",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "גלה, הורד, וחקור הגדרות מודל מוגדרות מראש",
 	"Discover, download, and explore model presets": "גלה, הורד, וחקור הגדרות מודל מוגדרות מראש",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "אל תאפשר",
 	"Don't Allow": "אל תאפשר",
 	"Don't have an account?": "אין לך חשבון?",
 	"Don't have an account?": "אין לך חשבון?",
 	"Don't like the style": "לא אוהב את הסגנון",
 	"Don't like the style": "לא אוהב את הסגנון",
+	"Done": "",
 	"Download": "הורד",
 	"Download": "הורד",
 	"Download canceled": "ההורדה בוטלה",
 	"Download canceled": "ההורדה בוטלה",
 	"Download Database": "הורד מסד נתונים",
 	"Download Database": "הורד מסד נתונים",
@@ -312,6 +318,7 @@
 	"Manage Models": "נהל מודלים",
 	"Manage Models": "נהל מודלים",
 	"Manage Ollama Models": "נהל מודלים של Ollama",
 	"Manage Ollama Models": "נהל מודלים של Ollama",
 	"Manage Pipelines": "ניהול צינורות",
 	"Manage Pipelines": "ניהול צינורות",
+	"Manage Valves": "",
 	"March": "מרץ",
 	"March": "מרץ",
 	"Max Tokens (num_predict)": "מקסימום אסימונים (num_predict)",
 	"Max Tokens (num_predict)": "מקסימום אסימונים (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ניתן להוריד מקסימום 3 מודלים בו זמנית. אנא נסה שוב מאוחר יותר.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ניתן להוריד מקסימום 3 מודלים בו זמנית. אנא נסה שוב מאוחר יותר.",
@@ -460,10 +467,12 @@
 	"Seed": "זרע",
 	"Seed": "זרע",
 	"Select a base model": "בחירת מודל בסיס",
 	"Select a base model": "בחירת מודל בסיס",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "בחר מצב",
 	"Select a mode": "בחר מצב",
 	"Select a model": "בחר מודל",
 	"Select a model": "בחר מודל",
 	"Select a pipeline": "בחר קו צינור",
 	"Select a pipeline": "בחר קו צינור",
 	"Select a pipeline url": "בחר כתובת URL של קו צינור",
 	"Select a pipeline url": "בחר כתובת URL של קו צינור",
+	"Select a tool": "",
 	"Select an Ollama instance": "בחר מופע של Ollama",
 	"Select an Ollama instance": "בחר מופע של Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "בחר מודל",
 	"Select model": "בחר מודל",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "הצג קיצורי דרך",
 	"Show shortcuts": "הצג קיצורי דרך",
+	"Show your support!": "",
 	"Showcased creativity": "הצגת יצירתיות",
 	"Showcased creativity": "הצגת יצירתיות",
 	"sidebar": "סרגל צד",
 	"sidebar": "סרגל צד",
 	"Sign in": "הירשם",
 	"Sign in": "הירשם",
@@ -584,6 +594,7 @@
 	"Users": "משתמשים",
 	"Users": "משתמשים",
 	"Utilize": "שימוש",
 	"Utilize": "שימוש",
 	"Valid time units:": "יחידות זמן תקינות:",
 	"Valid time units:": "יחידות זמן תקינות:",
+	"Valves": "",
 	"variable": "משתנה",
 	"variable": "משתנה",
 	"variable to have them replaced with clipboard content.": "משתנה להחליפו ב- clipboard תוכן.",
 	"variable to have them replaced with clipboard content.": "משתנה להחליפו ב- clipboard תוכן.",
 	"Version": "גרסה",
 	"Version": "גרסה",

+ 11 - 0
src/lib/i18n/locales/hi-IN/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "चैट हटाने की अनुमति दें",
 	"Allow Chat Deletion": "चैट हटाने की अनुमति दें",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "अल्फ़ान्यूमेरिक वर्ण और हाइफ़न",
 	"alphanumeric characters and hyphens": "अल्फ़ान्यूमेरिक वर्ण और हाइफ़न",
 	"Already have an account?": "क्या आपके पास पहले से एक खाता मौजूद है?",
 	"Already have an account?": "क्या आपके पास पहले से एक खाता मौजूद है?",
 	"an assistant": "एक सहायक",
 	"an assistant": "एक सहायक",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}} हटा दिया गया",
 	"Deleted {{name}}": "{{name}} हटा दिया गया",
 	"Description": "विवरण",
 	"Description": "विवरण",
 	"Didn't fully follow instructions": "निर्देशों का पूरी तरह से पालन नहीं किया",
 	"Didn't fully follow instructions": "निर्देशों का पूरी तरह से पालन नहीं किया",
+	"Discover a function": "",
 	"Discover a model": "एक मॉडल की खोज करें",
 	"Discover a model": "एक मॉडल की खोज करें",
 	"Discover a prompt": "प्रॉम्प्ट खोजें",
 	"Discover a prompt": "प्रॉम्प्ट खोजें",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "कस्टम प्रॉम्प्ट को खोजें, डाउनलोड करें और एक्सप्लोर करें",
 	"Discover, download, and explore custom prompts": "कस्टम प्रॉम्प्ट को खोजें, डाउनलोड करें और एक्सप्लोर करें",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "मॉडल प्रीसेट खोजें, डाउनलोड करें और एक्सप्लोर करें",
 	"Discover, download, and explore model presets": "मॉडल प्रीसेट खोजें, डाउनलोड करें और एक्सप्लोर करें",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "अनुमति न दें",
 	"Don't Allow": "अनुमति न दें",
 	"Don't have an account?": "कोई खाता नहीं है?",
 	"Don't have an account?": "कोई खाता नहीं है?",
 	"Don't like the style": "शैली पसंद नहीं है",
 	"Don't like the style": "शैली पसंद नहीं है",
+	"Done": "",
 	"Download": "डाउनलोड",
 	"Download": "डाउनलोड",
 	"Download canceled": "डाउनलोड रद्द किया गया",
 	"Download canceled": "डाउनलोड रद्द किया गया",
 	"Download Database": "डेटाबेस डाउनलोड करें",
 	"Download Database": "डेटाबेस डाउनलोड करें",
@@ -312,6 +318,7 @@
 	"Manage Models": "मॉडल प्रबंधित करें",
 	"Manage Models": "मॉडल प्रबंधित करें",
 	"Manage Ollama Models": "Ollama मॉडल प्रबंधित करें",
 	"Manage Ollama Models": "Ollama मॉडल प्रबंधित करें",
 	"Manage Pipelines": "पाइपलाइनों का प्रबंधन करें",
 	"Manage Pipelines": "पाइपलाइनों का प्रबंधन करें",
+	"Manage Valves": "",
 	"March": "मार्च",
 	"March": "मार्च",
 	"Max Tokens (num_predict)": "अधिकतम टोकन (num_predict)",
 	"Max Tokens (num_predict)": "अधिकतम टोकन (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "अधिकतम 3 मॉडल एक साथ डाउनलोड किये जा सकते हैं। कृपया बाद में पुन: प्रयास करें।",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "अधिकतम 3 मॉडल एक साथ डाउनलोड किये जा सकते हैं। कृपया बाद में पुन: प्रयास करें।",
@@ -459,10 +466,12 @@
 	"Seed": "सीड्\u200c",
 	"Seed": "सीड्\u200c",
 	"Select a base model": "एक आधार मॉडल का चयन करें",
 	"Select a base model": "एक आधार मॉडल का चयन करें",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "एक मोड चुनें",
 	"Select a mode": "एक मोड चुनें",
 	"Select a model": "एक मॉडल चुनें",
 	"Select a model": "एक मॉडल चुनें",
 	"Select a pipeline": "एक पाइपलाइन का चयन करें",
 	"Select a pipeline": "एक पाइपलाइन का चयन करें",
 	"Select a pipeline url": "एक पाइपलाइन url चुनें",
 	"Select a pipeline url": "एक पाइपलाइन url चुनें",
+	"Select a tool": "",
 	"Select an Ollama instance": "एक Ollama Instance चुनें",
 	"Select an Ollama instance": "एक Ollama Instance चुनें",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "मॉडल चुनें",
 	"Select model": "मॉडल चुनें",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "शॉर्टकट दिखाएँ",
 	"Show shortcuts": "शॉर्टकट दिखाएँ",
+	"Show your support!": "",
 	"Showcased creativity": "रचनात्मकता का प्रदर्शन किया",
 	"Showcased creativity": "रचनात्मकता का प्रदर्शन किया",
 	"sidebar": "साइड बार",
 	"sidebar": "साइड बार",
 	"Sign in": "साइन इन",
 	"Sign in": "साइन इन",
@@ -583,6 +593,7 @@
 	"Users": "उपयोगकर्ताओं",
 	"Users": "उपयोगकर्ताओं",
 	"Utilize": "उपयोग करें",
 	"Utilize": "उपयोग करें",
 	"Valid time units:": "मान्य समय इकाइयाँ:",
 	"Valid time units:": "मान्य समय इकाइयाँ:",
+	"Valves": "",
 	"variable": "वेरिएबल",
 	"variable": "वेरिएबल",
 	"variable to have them replaced with clipboard content.": "उन्हें क्लिपबोर्ड सामग्री से बदलने के लिए वेरिएबल।",
 	"variable to have them replaced with clipboard content.": "उन्हें क्लिपबोर्ड सामग्री से बदलने के लिए वेरिएबल।",
 	"Version": "संस्करण",
 	"Version": "संस्करण",

+ 11 - 0
src/lib/i18n/locales/hr-HR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Dopusti brisanje razgovora",
 	"Allow Chat Deletion": "Dopusti brisanje razgovora",
 	"Allow non-local voices": "Dopusti nelokalne glasove",
 	"Allow non-local voices": "Dopusti nelokalne glasove",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alfanumerički znakovi i crtice",
 	"alphanumeric characters and hyphens": "alfanumerički znakovi i crtice",
 	"Already have an account?": "Već imate račun?",
 	"Already have an account?": "Već imate račun?",
 	"an assistant": "asistent",
 	"an assistant": "asistent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Izbrisano {{name}}",
 	"Deleted {{name}}": "Izbrisano {{name}}",
 	"Description": "Opis",
 	"Description": "Opis",
 	"Didn't fully follow instructions": "Nije u potpunosti slijedio upute",
 	"Didn't fully follow instructions": "Nije u potpunosti slijedio upute",
+	"Discover a function": "",
 	"Discover a model": "Otkrijte model",
 	"Discover a model": "Otkrijte model",
 	"Discover a prompt": "Otkrijte prompt",
 	"Discover a prompt": "Otkrijte prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Otkrijte, preuzmite i istražite prilagođene prompte",
 	"Discover, download, and explore custom prompts": "Otkrijte, preuzmite i istražite prilagođene prompte",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Otkrijte, preuzmite i istražite unaprijed postavljene modele",
 	"Discover, download, and explore model presets": "Otkrijte, preuzmite i istražite unaprijed postavljene modele",
 	"Dismissible": "Odbaciti",
 	"Dismissible": "Odbaciti",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Ne dopuštaj",
 	"Don't Allow": "Ne dopuštaj",
 	"Don't have an account?": "Nemate račun?",
 	"Don't have an account?": "Nemate račun?",
 	"Don't like the style": "Ne sviđa mi se stil",
 	"Don't like the style": "Ne sviđa mi se stil",
+	"Done": "",
 	"Download": "Preuzimanje",
 	"Download": "Preuzimanje",
 	"Download canceled": "Preuzimanje otkazano",
 	"Download canceled": "Preuzimanje otkazano",
 	"Download Database": "Preuzmi bazu podataka",
 	"Download Database": "Preuzmi bazu podataka",
@@ -312,6 +318,7 @@
 	"Manage Models": "Upravljanje modelima",
 	"Manage Models": "Upravljanje modelima",
 	"Manage Ollama Models": "Upravljanje Ollama modelima",
 	"Manage Ollama Models": "Upravljanje Ollama modelima",
 	"Manage Pipelines": "Upravljanje cjevovodima",
 	"Manage Pipelines": "Upravljanje cjevovodima",
+	"Manage Valves": "",
 	"March": "Ožujak",
 	"March": "Ožujak",
 	"Max Tokens (num_predict)": "Maksimalan broj tokena (num_predict)",
 	"Max Tokens (num_predict)": "Maksimalan broj tokena (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalno 3 modela se mogu preuzeti istovremeno. Pokušajte ponovo kasnije.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalno 3 modela se mogu preuzeti istovremeno. Pokušajte ponovo kasnije.",
@@ -460,10 +467,12 @@
 	"Seed": "Sjeme",
 	"Seed": "Sjeme",
 	"Select a base model": "Odabir osnovnog modela",
 	"Select a base model": "Odabir osnovnog modela",
 	"Select a engine": "Odaberite pogon",
 	"Select a engine": "Odaberite pogon",
+	"Select a function": "",
 	"Select a mode": "Odaberite način",
 	"Select a mode": "Odaberite način",
 	"Select a model": "Odaberite model",
 	"Select a model": "Odaberite model",
 	"Select a pipeline": "Odabir kanala",
 	"Select a pipeline": "Odabir kanala",
 	"Select a pipeline url": "Odabir URL-a kanala",
 	"Select a pipeline url": "Odabir URL-a kanala",
+	"Select a tool": "",
 	"Select an Ollama instance": "Odaberite Ollama instancu",
 	"Select an Ollama instance": "Odaberite Ollama instancu",
 	"Select Documents": "Odaberite dokumente",
 	"Select Documents": "Odaberite dokumente",
 	"Select model": "Odaberite model",
 	"Select model": "Odaberite model",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Pokaži prečace",
 	"Show shortcuts": "Pokaži prečace",
+	"Show your support!": "",
 	"Showcased creativity": "Prikazana kreativnost",
 	"Showcased creativity": "Prikazana kreativnost",
 	"sidebar": "bočna traka",
 	"sidebar": "bočna traka",
 	"Sign in": "Prijava",
 	"Sign in": "Prijava",
@@ -584,6 +594,7 @@
 	"Users": "Korisnici",
 	"Users": "Korisnici",
 	"Utilize": "Iskoristi",
 	"Utilize": "Iskoristi",
 	"Valid time units:": "Važeće vremenske jedinice:",
 	"Valid time units:": "Važeće vremenske jedinice:",
+	"Valves": "",
 	"variable": "varijabla",
 	"variable": "varijabla",
 	"variable to have them replaced with clipboard content.": "varijabla za zamjenu sadržajem međuspremnika.",
 	"variable to have them replaced with clipboard content.": "varijabla za zamjenu sadržajem međuspremnika.",
 	"Version": "Verzija",
 	"Version": "Verzija",

+ 11 - 0
src/lib/i18n/locales/it-IT/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Consenti l'eliminazione della chat",
 	"Allow Chat Deletion": "Consenti l'eliminazione della chat",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caratteri alfanumerici e trattini",
 	"alphanumeric characters and hyphens": "caratteri alfanumerici e trattini",
 	"Already have an account?": "Hai già un account?",
 	"Already have an account?": "Hai già un account?",
 	"an assistant": "un assistente",
 	"an assistant": "un assistente",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Eliminato {{name}}",
 	"Deleted {{name}}": "Eliminato {{name}}",
 	"Description": "Descrizione",
 	"Description": "Descrizione",
 	"Didn't fully follow instructions": "Non ha seguito completamente le istruzioni",
 	"Didn't fully follow instructions": "Non ha seguito completamente le istruzioni",
+	"Discover a function": "",
 	"Discover a model": "Scopri un modello",
 	"Discover a model": "Scopri un modello",
 	"Discover a prompt": "Scopri un prompt",
 	"Discover a prompt": "Scopri un prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
 	"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
 	"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Non consentire",
 	"Don't Allow": "Non consentire",
 	"Don't have an account?": "Non hai un account?",
 	"Don't have an account?": "Non hai un account?",
 	"Don't like the style": "Non ti piace lo stile",
 	"Don't like the style": "Non ti piace lo stile",
+	"Done": "",
 	"Download": "Scarica",
 	"Download": "Scarica",
 	"Download canceled": "Scaricamento annullato",
 	"Download canceled": "Scaricamento annullato",
 	"Download Database": "Scarica database",
 	"Download Database": "Scarica database",
@@ -312,6 +318,7 @@
 	"Manage Models": "Gestisci modelli",
 	"Manage Models": "Gestisci modelli",
 	"Manage Ollama Models": "Gestisci modelli Ollama",
 	"Manage Ollama Models": "Gestisci modelli Ollama",
 	"Manage Pipelines": "Gestire le pipeline",
 	"Manage Pipelines": "Gestire le pipeline",
+	"Manage Valves": "",
 	"March": "Marzo",
 	"March": "Marzo",
 	"Max Tokens (num_predict)": "Numero massimo di gettoni (num_predict)",
 	"Max Tokens (num_predict)": "Numero massimo di gettoni (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "È possibile scaricare un massimo di 3 modelli contemporaneamente. Riprova più tardi.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "È possibile scaricare un massimo di 3 modelli contemporaneamente. Riprova più tardi.",
@@ -460,10 +467,12 @@
 	"Seed": "Seme",
 	"Seed": "Seme",
 	"Select a base model": "Selezionare un modello di base",
 	"Select a base model": "Selezionare un modello di base",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Seleziona una modalità",
 	"Select a mode": "Seleziona una modalità",
 	"Select a model": "Seleziona un modello",
 	"Select a model": "Seleziona un modello",
 	"Select a pipeline": "Selezionare una tubazione",
 	"Select a pipeline": "Selezionare una tubazione",
 	"Select a pipeline url": "Selezionare l'URL di una pipeline",
 	"Select a pipeline url": "Selezionare l'URL di una pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Seleziona un'istanza Ollama",
 	"Select an Ollama instance": "Seleziona un'istanza Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Seleziona modello",
 	"Select model": "Seleziona modello",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Mostra",
 	"Show shortcuts": "Mostra",
+	"Show your support!": "",
 	"Showcased creativity": "Creatività messa in mostra",
 	"Showcased creativity": "Creatività messa in mostra",
 	"sidebar": "barra laterale",
 	"sidebar": "barra laterale",
 	"Sign in": "Accedi",
 	"Sign in": "Accedi",
@@ -584,6 +594,7 @@
 	"Users": "Utenti",
 	"Users": "Utenti",
 	"Utilize": "Utilizza",
 	"Utilize": "Utilizza",
 	"Valid time units:": "Unità di tempo valide:",
 	"Valid time units:": "Unità di tempo valide:",
+	"Valves": "",
 	"variable": "variabile",
 	"variable": "variabile",
 	"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
 	"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
 	"Version": "Versione",
 	"Version": "Versione",

+ 11 - 0
src/lib/i18n/locales/ja-JP/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "チャットの削除を許可",
 	"Allow Chat Deletion": "チャットの削除を許可",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "英数字とハイフン",
 	"alphanumeric characters and hyphens": "英数字とハイフン",
 	"Already have an account?": "すでにアカウントをお持ちですか?",
 	"Already have an account?": "すでにアカウントをお持ちですか?",
 	"an assistant": "アシスタント",
 	"an assistant": "アシスタント",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}}を削除しました",
 	"Deleted {{name}}": "{{name}}を削除しました",
 	"Description": "説明",
 	"Description": "説明",
 	"Didn't fully follow instructions": "説明に沿って操作していませんでした",
 	"Didn't fully follow instructions": "説明に沿って操作していませんでした",
+	"Discover a function": "",
 	"Discover a model": "モデルを検出する",
 	"Discover a model": "モデルを検出する",
 	"Discover a prompt": "プロンプトを見つける",
 	"Discover a prompt": "プロンプトを見つける",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
 	"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
 	"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "許可しない",
 	"Don't Allow": "許可しない",
 	"Don't have an account?": "アカウントをお持ちではありませんか?",
 	"Don't have an account?": "アカウントをお持ちではありませんか?",
 	"Don't like the style": "デザインが好きでない",
 	"Don't like the style": "デザインが好きでない",
+	"Done": "",
 	"Download": "ダウンロードをキャンセルしました",
 	"Download": "ダウンロードをキャンセルしました",
 	"Download canceled": "ダウンロードをキャンセルしました",
 	"Download canceled": "ダウンロードをキャンセルしました",
 	"Download Database": "データベースをダウンロード",
 	"Download Database": "データベースをダウンロード",
@@ -312,6 +318,7 @@
 	"Manage Models": "モデルを管理",
 	"Manage Models": "モデルを管理",
 	"Manage Ollama Models": "Ollama モデルを管理",
 	"Manage Ollama Models": "Ollama モデルを管理",
 	"Manage Pipelines": "パイプラインの管理",
 	"Manage Pipelines": "パイプラインの管理",
+	"Manage Valves": "",
 	"March": "3月",
 	"March": "3月",
 	"Max Tokens (num_predict)": "最大トークン数 (num_predict)",
 	"Max Tokens (num_predict)": "最大トークン数 (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。",
@@ -458,10 +465,12 @@
 	"Seed": "シード",
 	"Seed": "シード",
 	"Select a base model": "基本モデルの選択",
 	"Select a base model": "基本モデルの選択",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "モードを選択",
 	"Select a mode": "モードを選択",
 	"Select a model": "モデルを選択",
 	"Select a model": "モデルを選択",
 	"Select a pipeline": "パイプラインの選択",
 	"Select a pipeline": "パイプラインの選択",
 	"Select a pipeline url": "パイプラインの URL を選択する",
 	"Select a pipeline url": "パイプラインの URL を選択する",
+	"Select a tool": "",
 	"Select an Ollama instance": "Ollama インスタンスを選択",
 	"Select an Ollama instance": "Ollama インスタンスを選択",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "モデルを選択",
 	"Select model": "モデルを選択",
@@ -494,6 +503,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "表示",
 	"Show shortcuts": "表示",
+	"Show your support!": "",
 	"Showcased creativity": "創造性を披露",
 	"Showcased creativity": "創造性を披露",
 	"sidebar": "サイドバー",
 	"sidebar": "サイドバー",
 	"Sign in": "サインイン",
 	"Sign in": "サインイン",
@@ -582,6 +592,7 @@
 	"Users": "ユーザー",
 	"Users": "ユーザー",
 	"Utilize": "活用",
 	"Utilize": "活用",
 	"Valid time units:": "有効な時間単位:",
 	"Valid time units:": "有効な時間単位:",
+	"Valves": "",
 	"variable": "変数",
 	"variable": "変数",
 	"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
 	"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
 	"Version": "バージョン",
 	"Version": "バージョン",

+ 11 - 0
src/lib/i18n/locales/ka-GE/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "მიმოწერის წაშლის დაშვება",
 	"Allow Chat Deletion": "მიმოწერის წაშლის დაშვება",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "ალფანუმერული სიმბოლოები და დეფისები",
 	"alphanumeric characters and hyphens": "ალფანუმერული სიმბოლოები და დეფისები",
 	"Already have an account?": "უკვე გაქვს ანგარიში?",
 	"Already have an account?": "უკვე გაქვს ანგარიში?",
 	"an assistant": "ასისტენტი",
 	"an assistant": "ასისტენტი",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Deleted {{name}}",
 	"Deleted {{name}}": "Deleted {{name}}",
 	"Description": "აღწერა",
 	"Description": "აღწერა",
 	"Didn't fully follow instructions": "ვერ ყველა ინფორმაციისთვის ვერ ხელახლა ჩაწერე",
 	"Didn't fully follow instructions": "ვერ ყველა ინფორმაციისთვის ვერ ხელახლა ჩაწერე",
+	"Discover a function": "",
 	"Discover a model": "გაიგეთ მოდელი",
 	"Discover a model": "გაიგეთ მოდელი",
 	"Discover a prompt": "აღმოაჩინეთ მოთხოვნა",
 	"Discover a prompt": "აღმოაჩინეთ მოთხოვნა",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მორგებული მოთხოვნები",
 	"Discover, download, and explore custom prompts": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მორგებული მოთხოვნები",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მოდელის წინასწარ პარამეტრები",
 	"Discover, download, and explore model presets": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მოდელის წინასწარ პარამეტრები",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "არ დაუშვა",
 	"Don't Allow": "არ დაუშვა",
 	"Don't have an account?": "არ გაქვს ანგარიში?",
 	"Don't have an account?": "არ გაქვს ანგარიში?",
 	"Don't like the style": "არ ეთიკურია ფართოდ",
 	"Don't like the style": "არ ეთიკურია ფართოდ",
+	"Done": "",
 	"Download": "ჩამოტვირთვა გაუქმებულია",
 	"Download": "ჩამოტვირთვა გაუქმებულია",
 	"Download canceled": "ჩამოტვირთვა გაუქმებულია",
 	"Download canceled": "ჩამოტვირთვა გაუქმებულია",
 	"Download Database": "გადმოწერე მონაცემთა ბაზა",
 	"Download Database": "გადმოწერე მონაცემთა ბაზა",
@@ -312,6 +318,7 @@
 	"Manage Models": "მოდელების მართვა",
 	"Manage Models": "მოდელების მართვა",
 	"Manage Ollama Models": "Ollama მოდელების მართვა",
 	"Manage Ollama Models": "Ollama მოდელების მართვა",
 	"Manage Pipelines": "მილსადენების მართვა",
 	"Manage Pipelines": "მილსადენების მართვა",
+	"Manage Valves": "",
 	"March": "მარტივი",
 	"March": "მარტივი",
 	"Max Tokens (num_predict)": "მაქს ტოკენსი (num_predict)",
 	"Max Tokens (num_predict)": "მაქს ტოკენსი (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "მაქსიმუმ 3 მოდელის ჩამოტვირთვა შესაძლებელია ერთდროულად. Გთხოვთ სცადოთ მოგვიანებით.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "მაქსიმუმ 3 მოდელის ჩამოტვირთვა შესაძლებელია ერთდროულად. Გთხოვთ სცადოთ მოგვიანებით.",
@@ -459,10 +466,12 @@
 	"Seed": "სიდი",
 	"Seed": "სიდი",
 	"Select a base model": "აირჩიეთ ბაზის მოდელი",
 	"Select a base model": "აირჩიეთ ბაზის მოდელი",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "რეჟიმის არჩევა",
 	"Select a mode": "რეჟიმის არჩევა",
 	"Select a model": "მოდელის არჩევა",
 	"Select a model": "მოდელის არჩევა",
 	"Select a pipeline": "აირჩიეთ მილსადენი",
 	"Select a pipeline": "აირჩიეთ მილსადენი",
 	"Select a pipeline url": "აირჩიეთ მილსადენის url",
 	"Select a pipeline url": "აირჩიეთ მილსადენის url",
+	"Select a tool": "",
 	"Select an Ollama instance": "Ollama ინსტანსის არჩევა",
 	"Select an Ollama instance": "Ollama ინსტანსის არჩევა",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "მოდელის არჩევა",
 	"Select model": "მოდელის არჩევა",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "მალსახმობების ჩვენება",
 	"Show shortcuts": "მალსახმობების ჩვენება",
+	"Show your support!": "",
 	"Showcased creativity": "ჩვენებული ქონება",
 	"Showcased creativity": "ჩვენებული ქონება",
 	"sidebar": "საიდბარი",
 	"sidebar": "საიდბარი",
 	"Sign in": "ავტორიზაცია",
 	"Sign in": "ავტორიზაცია",
@@ -583,6 +593,7 @@
 	"Users": "მომხმარებლები",
 	"Users": "მომხმარებლები",
 	"Utilize": "გამოყენება",
 	"Utilize": "გამოყენება",
 	"Valid time units:": "მოქმედი დროის ერთეულები",
 	"Valid time units:": "მოქმედი დროის ერთეულები",
+	"Valves": "",
 	"variable": "ცვლადი",
 	"variable": "ცვლადი",
 	"variable to have them replaced with clipboard content.": "ცვლადი, რომ შეცვალოს ისინი ბუფერში შიგთავსით.",
 	"variable to have them replaced with clipboard content.": "ცვლადი, რომ შეცვალოს ისინი ბუფერში შიგთავსით.",
 	"Version": "ვერსია",
 	"Version": "ვერსია",

+ 11 - 0
src/lib/i18n/locales/ko-KR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "채팅 삭제 허용",
 	"Allow Chat Deletion": "채팅 삭제 허용",
 	"Allow non-local voices": "외부 음성 허용",
 	"Allow non-local voices": "외부 음성 허용",
 	"Allow User Location": "사용자 위치 활용 허용",
 	"Allow User Location": "사용자 위치 활용 허용",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "영문자, 숫자, 하이픈",
 	"alphanumeric characters and hyphens": "영문자, 숫자, 하이픈",
 	"Already have an account?": "이미 계정이 있으신가요?",
 	"Already have an account?": "이미 계정이 있으신가요?",
 	"an assistant": "어시스턴트",
 	"an assistant": "어시스턴트",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}}을(를) 삭제했습니다.",
 	"Deleted {{name}}": "{{name}}을(를) 삭제했습니다.",
 	"Description": "설명",
 	"Description": "설명",
 	"Didn't fully follow instructions": "완전히 지침을 따르지 않음",
 	"Didn't fully follow instructions": "완전히 지침을 따르지 않음",
+	"Discover a function": "",
 	"Discover a model": "모델 검색",
 	"Discover a model": "모델 검색",
 	"Discover a prompt": "프롬프트 검색",
 	"Discover a prompt": "프롬프트 검색",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "사용자 정의 프롬프트 검색, 다운로드 및 탐색",
 	"Discover, download, and explore custom prompts": "사용자 정의 프롬프트 검색, 다운로드 및 탐색",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "모델 사전 설정 검색, 다운로드 및 탐색",
 	"Discover, download, and explore model presets": "모델 사전 설정 검색, 다운로드 및 탐색",
 	"Dismissible": "제외가능",
 	"Dismissible": "제외가능",
 	"Display Emoji in Call": "콜(call)에서 이모지 표시",
 	"Display Emoji in Call": "콜(call)에서 이모지 표시",
@@ -180,6 +185,7 @@
 	"Don't Allow": "허용 안 함",
 	"Don't Allow": "허용 안 함",
 	"Don't have an account?": "계정이 없으신가요?",
 	"Don't have an account?": "계정이 없으신가요?",
 	"Don't like the style": "스타일을 좋아하지 않으세요?",
 	"Don't like the style": "스타일을 좋아하지 않으세요?",
+	"Done": "",
 	"Download": "다운로드",
 	"Download": "다운로드",
 	"Download canceled": "다운로드 취소",
 	"Download canceled": "다운로드 취소",
 	"Download Database": "데이터베이스 다운로드",
 	"Download Database": "데이터베이스 다운로드",
@@ -312,6 +318,7 @@
 	"Manage Models": "모델 관리",
 	"Manage Models": "모델 관리",
 	"Manage Ollama Models": "Ollama 모델 관리",
 	"Manage Ollama Models": "Ollama 모델 관리",
 	"Manage Pipelines": "파이프라인 관리",
 	"Manage Pipelines": "파이프라인 관리",
+	"Manage Valves": "",
 	"March": "3월",
 	"March": "3월",
 	"Max Tokens (num_predict)": "최대 토큰(num_predict)",
 	"Max Tokens (num_predict)": "최대 토큰(num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "최대 3개의 모델을 동시에 다운로드할 수 있습니다. 나중에 다시 시도하세요.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "최대 3개의 모델을 동시에 다운로드할 수 있습니다. 나중에 다시 시도하세요.",
@@ -459,10 +466,12 @@
 	"Seed": "시드",
 	"Seed": "시드",
 	"Select a base model": "기본 모델 선택",
 	"Select a base model": "기본 모델 선택",
 	"Select a engine": "엔진 선택",
 	"Select a engine": "엔진 선택",
+	"Select a function": "",
 	"Select a mode": "모드 선택",
 	"Select a mode": "모드 선택",
 	"Select a model": "모델 선택",
 	"Select a model": "모델 선택",
 	"Select a pipeline": "파이프라인 선택",
 	"Select a pipeline": "파이프라인 선택",
 	"Select a pipeline url": "파이프라인 URL 선택",
 	"Select a pipeline url": "파이프라인 URL 선택",
+	"Select a tool": "",
 	"Select an Ollama instance": "Ollama 인스턴스 선택",
 	"Select an Ollama instance": "Ollama 인스턴스 선택",
 	"Select Documents": "문서 선택",
 	"Select Documents": "문서 선택",
 	"Select model": "모델 선택",
 	"Select model": "모델 선택",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "사용자용 계정 보류 설명창에, 관리자 상세 정보 노출",
 	"Show Admin Details in Account Pending Overlay": "사용자용 계정 보류 설명창에, 관리자 상세 정보 노출",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "단축키 보기",
 	"Show shortcuts": "단축키 보기",
+	"Show your support!": "",
 	"Showcased creativity": "창의성 발휘",
 	"Showcased creativity": "창의성 발휘",
 	"sidebar": "사이드바",
 	"sidebar": "사이드바",
 	"Sign in": "로그인",
 	"Sign in": "로그인",
@@ -583,6 +593,7 @@
 	"Users": "사용자",
 	"Users": "사용자",
 	"Utilize": "활용",
 	"Utilize": "활용",
 	"Valid time units:": "유효 시간 단위:",
 	"Valid time units:": "유효 시간 단위:",
+	"Valves": "",
 	"variable": "변수",
 	"variable": "변수",
 	"variable to have them replaced with clipboard content.": "변수를 사용하여 클립보드 내용으로 바꾸세요.",
 	"variable to have them replaced with clipboard content.": "변수를 사용하여 클립보드 내용으로 바꾸세요.",
 	"Version": "버전",
 	"Version": "버전",

+ 11 - 0
src/lib/i18n/locales/lt-LT/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Leisti pokalbių ištrynimą",
 	"Allow Chat Deletion": "Leisti pokalbių ištrynimą",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "skaičiai, raidės ir brūkšneliai",
 	"alphanumeric characters and hyphens": "skaičiai, raidės ir brūkšneliai",
 	"Already have an account?": "Ar jau turite paskyrą?",
 	"Already have an account?": "Ar jau turite paskyrą?",
 	"an assistant": "assistentas",
 	"an assistant": "assistentas",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "Aprašymas",
 	"Description": "Aprašymas",
 	"Didn't fully follow instructions": "Pilnai nesekė instrukcijų",
 	"Didn't fully follow instructions": "Pilnai nesekė instrukcijų",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "Atrasti užklausas",
 	"Discover a prompt": "Atrasti užklausas",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Atrasti ir parsisiųsti užklausas",
 	"Discover, download, and explore custom prompts": "Atrasti ir parsisiųsti užklausas",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Atrasti ir parsisiųsti modelių konfigūracija",
 	"Discover, download, and explore model presets": "Atrasti ir parsisiųsti modelių konfigūracija",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Neleisti",
 	"Don't Allow": "Neleisti",
 	"Don't have an account?": "Neturite paskyros?",
 	"Don't have an account?": "Neturite paskyros?",
 	"Don't like the style": "Nepatinka stilius",
 	"Don't like the style": "Nepatinka stilius",
+	"Done": "",
 	"Download": "Parsisiųsti",
 	"Download": "Parsisiųsti",
 	"Download canceled": "Parsisiuntimas atšauktas",
 	"Download canceled": "Parsisiuntimas atšauktas",
 	"Download Database": "Parsisiųsti duomenų bazę",
 	"Download Database": "Parsisiųsti duomenų bazę",
@@ -312,6 +318,7 @@
 	"Manage Models": "Tvarkyti modelius",
 	"Manage Models": "Tvarkyti modelius",
 	"Manage Ollama Models": "Tvarkyti Ollama modelius",
 	"Manage Ollama Models": "Tvarkyti Ollama modelius",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "Kovas",
 	"March": "Kovas",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Daugiausiai trys modeliai gali būti parsisiunčiami vienu metu.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Daugiausiai trys modeliai gali būti parsisiunčiami vienu metu.",
@@ -461,10 +468,12 @@
 	"Seed": "Sėkla",
 	"Seed": "Sėkla",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Pasirinkti režimą",
 	"Select a mode": "Pasirinkti režimą",
 	"Select a model": "Pasirinkti modelį",
 	"Select a model": "Pasirinkti modelį",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "Pasirinkti Ollama instanciją",
 	"Select an Ollama instance": "Pasirinkti Ollama instanciją",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Pasirinkti modelį",
 	"Select model": "Pasirinkti modelį",
@@ -497,6 +506,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Rodyti trumpinius",
 	"Show shortcuts": "Rodyti trumpinius",
+	"Show your support!": "",
 	"Showcased creativity": "Kūrybingų užklausų paroda",
 	"Showcased creativity": "Kūrybingų užklausų paroda",
 	"sidebar": "šoninis meniu",
 	"sidebar": "šoninis meniu",
 	"Sign in": "Prisijungti",
 	"Sign in": "Prisijungti",
@@ -585,6 +595,7 @@
 	"Users": "Naudotojai",
 	"Users": "Naudotojai",
 	"Utilize": "Naudoti",
 	"Utilize": "Naudoti",
 	"Valid time units:": "Teisingūs laiko vienetai :",
 	"Valid time units:": "Teisingūs laiko vienetai :",
+	"Valves": "",
 	"variable": "kintamasis",
 	"variable": "kintamasis",
 	"variable to have them replaced with clipboard content.": "kintamoji pakeičiama kopijuoklės turiniu.",
 	"variable to have them replaced with clipboard content.": "kintamoji pakeičiama kopijuoklės turiniu.",
 	"Version": "Versija",
 	"Version": "Versija",

+ 11 - 0
src/lib/i18n/locales/nb-NO/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Tillat sletting av chatter",
 	"Allow Chat Deletion": "Tillat sletting av chatter",
 	"Allow non-local voices": "Tillat ikke-lokale stemmer",
 	"Allow non-local voices": "Tillat ikke-lokale stemmer",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alfanumeriske tegn og bindestreker",
 	"alphanumeric characters and hyphens": "alfanumeriske tegn og bindestreker",
 	"Already have an account?": "Har du allerede en konto?",
 	"Already have an account?": "Har du allerede en konto?",
 	"an assistant": "en assistent",
 	"an assistant": "en assistent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Slettet {{name}}",
 	"Deleted {{name}}": "Slettet {{name}}",
 	"Description": "Beskrivelse",
 	"Description": "Beskrivelse",
 	"Didn't fully follow instructions": "Fulgte ikke instruksjonene fullt ut",
 	"Didn't fully follow instructions": "Fulgte ikke instruksjonene fullt ut",
+	"Discover a function": "",
 	"Discover a model": "Oppdag en modell",
 	"Discover a model": "Oppdag en modell",
 	"Discover a prompt": "Oppdag en prompt",
 	"Discover a prompt": "Oppdag en prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Oppdag, last ned og utforsk egendefinerte prompts",
 	"Discover, download, and explore custom prompts": "Oppdag, last ned og utforsk egendefinerte prompts",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Oppdag, last ned og utforsk modellforhåndsinnstillinger",
 	"Discover, download, and explore model presets": "Oppdag, last ned og utforsk modellforhåndsinnstillinger",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Ikke tillat",
 	"Don't Allow": "Ikke tillat",
 	"Don't have an account?": "Har du ikke en konto?",
 	"Don't have an account?": "Har du ikke en konto?",
 	"Don't like the style": "Liker ikke stilen",
 	"Don't like the style": "Liker ikke stilen",
+	"Done": "",
 	"Download": "Last ned",
 	"Download": "Last ned",
 	"Download canceled": "Nedlasting avbrutt",
 	"Download canceled": "Nedlasting avbrutt",
 	"Download Database": "Last ned database",
 	"Download Database": "Last ned database",
@@ -312,6 +318,7 @@
 	"Manage Models": "Administrer modeller",
 	"Manage Models": "Administrer modeller",
 	"Manage Ollama Models": "Administrer Ollama-modeller",
 	"Manage Ollama Models": "Administrer Ollama-modeller",
 	"Manage Pipelines": "Administrer pipelines",
 	"Manage Pipelines": "Administrer pipelines",
+	"Manage Valves": "",
 	"March": "Mars",
 	"March": "Mars",
 	"Max Tokens (num_predict)": "Maks antall tokens (num_predict)",
 	"Max Tokens (num_predict)": "Maks antall tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalt 3 modeller kan lastes ned samtidig. Vennligst prøv igjen senere.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalt 3 modeller kan lastes ned samtidig. Vennligst prøv igjen senere.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Velg en grunnmodell",
 	"Select a base model": "Velg en grunnmodell",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Velg en modus",
 	"Select a mode": "Velg en modus",
 	"Select a model": "Velg en modell",
 	"Select a model": "Velg en modell",
 	"Select a pipeline": "Velg en pipeline",
 	"Select a pipeline": "Velg en pipeline",
 	"Select a pipeline url": "Velg en pipeline-URL",
 	"Select a pipeline url": "Velg en pipeline-URL",
+	"Select a tool": "",
 	"Select an Ollama instance": "Velg en Ollama-instans",
 	"Select an Ollama instance": "Velg en Ollama-instans",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Velg modell",
 	"Select model": "Velg modell",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "Vis administratordetaljer i ventende kontooverlay",
 	"Show Admin Details in Account Pending Overlay": "Vis administratordetaljer i ventende kontooverlay",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Vis snarveier",
 	"Show shortcuts": "Vis snarveier",
+	"Show your support!": "",
 	"Showcased creativity": "Vist frem kreativitet",
 	"Showcased creativity": "Vist frem kreativitet",
 	"sidebar": "sidefelt",
 	"sidebar": "sidefelt",
 	"Sign in": "Logg inn",
 	"Sign in": "Logg inn",
@@ -583,6 +593,7 @@
 	"Users": "Brukere",
 	"Users": "Brukere",
 	"Utilize": "Utnytt",
 	"Utilize": "Utnytt",
 	"Valid time units:": "Gyldige tidsenheter:",
 	"Valid time units:": "Gyldige tidsenheter:",
+	"Valves": "",
 	"variable": "variabel",
 	"variable": "variabel",
 	"variable to have them replaced with clipboard content.": "variabel for å få dem erstattet med utklippstavleinnhold.",
 	"variable to have them replaced with clipboard content.": "variabel for å få dem erstattet med utklippstavleinnhold.",
 	"Version": "Versjon",
 	"Version": "Versjon",

+ 11 - 0
src/lib/i18n/locales/nl-NL/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Sta Chat Verwijdering toe",
 	"Allow Chat Deletion": "Sta Chat Verwijdering toe",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alfanumerieke karakters en streepjes",
 	"alphanumeric characters and hyphens": "alfanumerieke karakters en streepjes",
 	"Already have an account?": "Heb je al een account?",
 	"Already have an account?": "Heb je al een account?",
 	"an assistant": "een assistent",
 	"an assistant": "een assistent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}} verwijderd",
 	"Deleted {{name}}": "{{name}} verwijderd",
 	"Description": "Beschrijving",
 	"Description": "Beschrijving",
 	"Didn't fully follow instructions": "Ik heb niet alle instructies volgt",
 	"Didn't fully follow instructions": "Ik heb niet alle instructies volgt",
+	"Discover a function": "",
 	"Discover a model": "Ontdek een model",
 	"Discover a model": "Ontdek een model",
 	"Discover a prompt": "Ontdek een prompt",
 	"Discover a prompt": "Ontdek een prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Ontdek, download en verken aangepaste prompts",
 	"Discover, download, and explore custom prompts": "Ontdek, download en verken aangepaste prompts",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Ontdek, download en verken model presets",
 	"Discover, download, and explore model presets": "Ontdek, download en verken model presets",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Niet Toestaan",
 	"Don't Allow": "Niet Toestaan",
 	"Don't have an account?": "Heb je geen account?",
 	"Don't have an account?": "Heb je geen account?",
 	"Don't like the style": "Je vindt het stijl niet?",
 	"Don't like the style": "Je vindt het stijl niet?",
+	"Done": "",
 	"Download": "Download",
 	"Download": "Download",
 	"Download canceled": "Download geannuleerd",
 	"Download canceled": "Download geannuleerd",
 	"Download Database": "Download Database",
 	"Download Database": "Download Database",
@@ -312,6 +318,7 @@
 	"Manage Models": "Beheer Modellen",
 	"Manage Models": "Beheer Modellen",
 	"Manage Ollama Models": "Beheer Ollama Modellen",
 	"Manage Ollama Models": "Beheer Ollama Modellen",
 	"Manage Pipelines": "Pijplijnen beheren",
 	"Manage Pipelines": "Pijplijnen beheren",
+	"Manage Valves": "",
 	"March": "Maart",
 	"March": "Maart",
 	"Max Tokens (num_predict)": "Max Tokens (num_predict)",
 	"Max Tokens (num_predict)": "Max Tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximaal 3 modellen kunnen tegelijkertijd worden gedownload. Probeer het later opnieuw.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximaal 3 modellen kunnen tegelijkertijd worden gedownload. Probeer het later opnieuw.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Selecteer een basismodel",
 	"Select a base model": "Selecteer een basismodel",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Selecteer een modus",
 	"Select a mode": "Selecteer een modus",
 	"Select a model": "Selecteer een model",
 	"Select a model": "Selecteer een model",
 	"Select a pipeline": "Selecteer een pijplijn",
 	"Select a pipeline": "Selecteer een pijplijn",
 	"Select a pipeline url": "Selecteer een pijplijn-URL",
 	"Select a pipeline url": "Selecteer een pijplijn-URL",
+	"Select a tool": "",
 	"Select an Ollama instance": "Selecteer een Ollama instantie",
 	"Select an Ollama instance": "Selecteer een Ollama instantie",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Selecteer een model",
 	"Select model": "Selecteer een model",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Toon snelkoppelingen",
 	"Show shortcuts": "Toon snelkoppelingen",
+	"Show your support!": "",
 	"Showcased creativity": "Tooncase creativiteit",
 	"Showcased creativity": "Tooncase creativiteit",
 	"sidebar": "sidebar",
 	"sidebar": "sidebar",
 	"Sign in": "Inloggen",
 	"Sign in": "Inloggen",
@@ -583,6 +593,7 @@
 	"Users": "Gebruikers",
 	"Users": "Gebruikers",
 	"Utilize": "Utilize",
 	"Utilize": "Utilize",
 	"Valid time units:": "Geldige tijdseenheden:",
 	"Valid time units:": "Geldige tijdseenheden:",
+	"Valves": "",
 	"variable": "variabele",
 	"variable": "variabele",
 	"variable to have them replaced with clipboard content.": "variabele om ze te laten vervangen door klembord inhoud.",
 	"variable to have them replaced with clipboard content.": "variabele om ze te laten vervangen door klembord inhoud.",
 	"Version": "Versie",
 	"Version": "Versie",

+ 11 - 0
src/lib/i18n/locales/pa-IN/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "ਗੱਲਬਾਤ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ",
 	"Allow Chat Deletion": "ਗੱਲਬਾਤ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "ਅਲਫ਼ਾਨਯੂਮੈਰਿਕ ਅੱਖਰ ਅਤੇ ਹਾਈਫਨ",
 	"alphanumeric characters and hyphens": "ਅਲਫ਼ਾਨਯੂਮੈਰਿਕ ਅੱਖਰ ਅਤੇ ਹਾਈਫਨ",
 	"Already have an account?": "ਪਹਿਲਾਂ ਹੀ ਖਾਤਾ ਹੈ?",
 	"Already have an account?": "ਪਹਿਲਾਂ ਹੀ ਖਾਤਾ ਹੈ?",
 	"an assistant": "ਇੱਕ ਸਹਾਇਕ",
 	"an assistant": "ਇੱਕ ਸਹਾਇਕ",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ {{name}}",
 	"Deleted {{name}}": "ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ {{name}}",
 	"Description": "ਵਰਣਨਾ",
 	"Description": "ਵਰਣਨਾ",
 	"Didn't fully follow instructions": "ਹਦਾਇਤਾਂ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਫਾਲੋ ਨਹੀਂ ਕੀਤਾ",
 	"Didn't fully follow instructions": "ਹਦਾਇਤਾਂ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਫਾਲੋ ਨਹੀਂ ਕੀਤਾ",
+	"Discover a function": "",
 	"Discover a model": "ਇੱਕ ਮਾਡਲ ਲੱਭੋ",
 	"Discover a model": "ਇੱਕ ਮਾਡਲ ਲੱਭੋ",
 	"Discover a prompt": "ਇੱਕ ਪ੍ਰੰਪਟ ਖੋਜੋ",
 	"Discover a prompt": "ਇੱਕ ਪ੍ਰੰਪਟ ਖੋਜੋ",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "ਕਸਟਮ ਪ੍ਰੰਪਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
 	"Discover, download, and explore custom prompts": "ਕਸਟਮ ਪ੍ਰੰਪਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "ਮਾਡਲ ਪ੍ਰੀਸੈਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
 	"Discover, download, and explore model presets": "ਮਾਡਲ ਪ੍ਰੀਸੈਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "ਆਗਿਆ ਨਾ ਦਿਓ",
 	"Don't Allow": "ਆਗਿਆ ਨਾ ਦਿਓ",
 	"Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?",
 	"Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?",
 	"Don't like the style": "ਸਟਾਈਲ ਪਸੰਦ ਨਹੀਂ ਹੈ",
 	"Don't like the style": "ਸਟਾਈਲ ਪਸੰਦ ਨਹੀਂ ਹੈ",
+	"Done": "",
 	"Download": "ਡਾਊਨਲੋਡ",
 	"Download": "ਡਾਊਨਲੋਡ",
 	"Download canceled": "ਡਾਊਨਲੋਡ ਰੱਦ ਕੀਤਾ ਗਿਆ",
 	"Download canceled": "ਡਾਊਨਲੋਡ ਰੱਦ ਕੀਤਾ ਗਿਆ",
 	"Download Database": "ਡਾਟਾਬੇਸ ਡਾਊਨਲੋਡ ਕਰੋ",
 	"Download Database": "ਡਾਟਾਬੇਸ ਡਾਊਨਲੋਡ ਕਰੋ",
@@ -312,6 +318,7 @@
 	"Manage Models": "ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Models": "ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Ollama Models": "ਓਲਾਮਾ ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Ollama Models": "ਓਲਾਮਾ ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Pipelines": "ਪਾਈਪਲਾਈਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
 	"Manage Pipelines": "ਪਾਈਪਲਾਈਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
+	"Manage Valves": "",
 	"March": "ਮਾਰਚ",
 	"March": "ਮਾਰਚ",
 	"Max Tokens (num_predict)": "ਮੈਕਸ ਟੋਕਨ (num_predict)",
 	"Max Tokens (num_predict)": "ਮੈਕਸ ਟੋਕਨ (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ਇੱਕ ਸਮੇਂ ਵਿੱਚ ਵੱਧ ਤੋਂ ਵੱਧ 3 ਮਾਡਲ ਡਾਊਨਲੋਡ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ। ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ਇੱਕ ਸਮੇਂ ਵਿੱਚ ਵੱਧ ਤੋਂ ਵੱਧ 3 ਮਾਡਲ ਡਾਊਨਲੋਡ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ। ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
@@ -459,10 +466,12 @@
 	"Seed": "ਬੀਜ",
 	"Seed": "ਬੀਜ",
 	"Select a base model": "ਆਧਾਰ ਮਾਡਲ ਚੁਣੋ",
 	"Select a base model": "ਆਧਾਰ ਮਾਡਲ ਚੁਣੋ",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "ਇੱਕ ਮੋਡ ਚੁਣੋ",
 	"Select a mode": "ਇੱਕ ਮੋਡ ਚੁਣੋ",
 	"Select a model": "ਇੱਕ ਮਾਡਲ ਚੁਣੋ",
 	"Select a model": "ਇੱਕ ਮਾਡਲ ਚੁਣੋ",
 	"Select a pipeline": "ਪਾਈਪਲਾਈਨ ਚੁਣੋ",
 	"Select a pipeline": "ਪਾਈਪਲਾਈਨ ਚੁਣੋ",
 	"Select a pipeline url": "ਪਾਈਪਲਾਈਨ URL ਚੁਣੋ",
 	"Select a pipeline url": "ਪਾਈਪਲਾਈਨ URL ਚੁਣੋ",
+	"Select a tool": "",
 	"Select an Ollama instance": "ਇੱਕ ਓਲਾਮਾ ਇੰਸਟੈਂਸ ਚੁਣੋ",
 	"Select an Ollama instance": "ਇੱਕ ਓਲਾਮਾ ਇੰਸਟੈਂਸ ਚੁਣੋ",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "ਮਾਡਲ ਚੁਣੋ",
 	"Select model": "ਮਾਡਲ ਚੁਣੋ",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "ਸ਼ਾਰਟਕਟ ਦਿਖਾਓ",
 	"Show shortcuts": "ਸ਼ਾਰਟਕਟ ਦਿਖਾਓ",
+	"Show your support!": "",
 	"Showcased creativity": "ਸਿਰਜਣਾਤਮਕਤਾ ਦਿਖਾਈ",
 	"Showcased creativity": "ਸਿਰਜਣਾਤਮਕਤਾ ਦਿਖਾਈ",
 	"sidebar": "ਸਾਈਡਬਾਰ",
 	"sidebar": "ਸਾਈਡਬਾਰ",
 	"Sign in": "ਸਾਈਨ ਇਨ ਕਰੋ",
 	"Sign in": "ਸਾਈਨ ਇਨ ਕਰੋ",
@@ -583,6 +593,7 @@
 	"Users": "ਉਪਭੋਗਤਾ",
 	"Users": "ਉਪਭੋਗਤਾ",
 	"Utilize": "ਵਰਤੋਂ",
 	"Utilize": "ਵਰਤੋਂ",
 	"Valid time units:": "ਵੈਧ ਸਮਾਂ ਇਕਾਈਆਂ:",
 	"Valid time units:": "ਵੈਧ ਸਮਾਂ ਇਕਾਈਆਂ:",
+	"Valves": "",
 	"variable": "ਵੈਰੀਏਬਲ",
 	"variable": "ਵੈਰੀਏਬਲ",
 	"variable to have them replaced with clipboard content.": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਨਾਲ ਬਦਲਣ ਲਈ ਵੈਰੀਏਬਲ।",
 	"variable to have them replaced with clipboard content.": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਨਾਲ ਬਦਲਣ ਲਈ ਵੈਰੀਏਬਲ।",
 	"Version": "ਵਰਜਨ",
 	"Version": "ਵਰਜਨ",

+ 11 - 0
src/lib/i18n/locales/pl-PL/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Pozwól na usuwanie czatu",
 	"Allow Chat Deletion": "Pozwól na usuwanie czatu",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "znaki alfanumeryczne i myślniki",
 	"alphanumeric characters and hyphens": "znaki alfanumeryczne i myślniki",
 	"Already have an account?": "Masz już konto?",
 	"Already have an account?": "Masz już konto?",
 	"an assistant": "asystent",
 	"an assistant": "asystent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Usunięto {{name}}",
 	"Deleted {{name}}": "Usunięto {{name}}",
 	"Description": "Opis",
 	"Description": "Opis",
 	"Didn't fully follow instructions": "Nie postępował zgodnie z instrukcjami",
 	"Didn't fully follow instructions": "Nie postępował zgodnie z instrukcjami",
+	"Discover a function": "",
 	"Discover a model": "Odkryj model",
 	"Discover a model": "Odkryj model",
 	"Discover a prompt": "Odkryj prompt",
 	"Discover a prompt": "Odkryj prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Odkryj, pobierz i eksploruj niestandardowe prompty",
 	"Discover, download, and explore custom prompts": "Odkryj, pobierz i eksploruj niestandardowe prompty",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Odkryj, pobierz i eksploruj ustawienia modeli",
 	"Discover, download, and explore model presets": "Odkryj, pobierz i eksploruj ustawienia modeli",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Nie zezwalaj",
 	"Don't Allow": "Nie zezwalaj",
 	"Don't have an account?": "Nie masz konta?",
 	"Don't have an account?": "Nie masz konta?",
 	"Don't like the style": "Nie podobał mi się styl",
 	"Don't like the style": "Nie podobał mi się styl",
+	"Done": "",
 	"Download": "Pobieranie",
 	"Download": "Pobieranie",
 	"Download canceled": "Pobieranie przerwane",
 	"Download canceled": "Pobieranie przerwane",
 	"Download Database": "Pobierz bazę danych",
 	"Download Database": "Pobierz bazę danych",
@@ -312,6 +318,7 @@
 	"Manage Models": "Zarządzaj modelami",
 	"Manage Models": "Zarządzaj modelami",
 	"Manage Ollama Models": "Zarządzaj modelami Ollama",
 	"Manage Ollama Models": "Zarządzaj modelami Ollama",
 	"Manage Pipelines": "Zarządzanie potokami",
 	"Manage Pipelines": "Zarządzanie potokami",
+	"Manage Valves": "",
 	"March": "Marzec",
 	"March": "Marzec",
 	"Max Tokens (num_predict)": "Maksymalna liczba żetonów (num_predict)",
 	"Max Tokens (num_predict)": "Maksymalna liczba żetonów (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksymalnie 3 modele można pobierać jednocześnie. Spróbuj ponownie później.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksymalnie 3 modele można pobierać jednocześnie. Spróbuj ponownie później.",
@@ -461,10 +468,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Wybieranie modelu bazowego",
 	"Select a base model": "Wybieranie modelu bazowego",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Wybierz tryb",
 	"Select a mode": "Wybierz tryb",
 	"Select a model": "Wybierz model",
 	"Select a model": "Wybierz model",
 	"Select a pipeline": "Wybieranie potoku",
 	"Select a pipeline": "Wybieranie potoku",
 	"Select a pipeline url": "Wybieranie adresu URL potoku",
 	"Select a pipeline url": "Wybieranie adresu URL potoku",
+	"Select a tool": "",
 	"Select an Ollama instance": "Wybierz instancję Ollama",
 	"Select an Ollama instance": "Wybierz instancję Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Wybierz model",
 	"Select model": "Wybierz model",
@@ -497,6 +506,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Pokaż skróty",
 	"Show shortcuts": "Pokaż skróty",
+	"Show your support!": "",
 	"Showcased creativity": "Pokaz kreatywności",
 	"Showcased creativity": "Pokaz kreatywności",
 	"sidebar": "Panel boczny",
 	"sidebar": "Panel boczny",
 	"Sign in": "Zaloguj się",
 	"Sign in": "Zaloguj się",
@@ -585,6 +595,7 @@
 	"Users": "Użytkownicy",
 	"Users": "Użytkownicy",
 	"Utilize": "Wykorzystaj",
 	"Utilize": "Wykorzystaj",
 	"Valid time units:": "Poprawne jednostki czasu:",
 	"Valid time units:": "Poprawne jednostki czasu:",
+	"Valves": "",
 	"variable": "zmienna",
 	"variable": "zmienna",
 	"variable to have them replaced with clipboard content.": "zmienna która zostanie zastąpiona zawartością schowka.",
 	"variable to have them replaced with clipboard content.": "zmienna która zostanie zastąpiona zawartością schowka.",
 	"Version": "Wersja",
 	"Version": "Wersja",

+ 11 - 0
src/lib/i18n/locales/pt-BR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
 	"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
 	"Already have an account?": "Já tem uma conta?",
 	"Already have an account?": "Já tem uma conta?",
 	"an assistant": "um assistente",
 	"an assistant": "um assistente",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Excluído {{nome}}",
 	"Deleted {{name}}": "Excluído {{nome}}",
 	"Description": "Descrição",
 	"Description": "Descrição",
 	"Didn't fully follow instructions": "Não seguiu instruções com precisão",
 	"Didn't fully follow instructions": "Não seguiu instruções com precisão",
+	"Discover a function": "",
 	"Discover a model": "Descubra um modelo",
 	"Discover a model": "Descubra um modelo",
 	"Discover a prompt": "Descobrir um prompt",
 	"Discover a prompt": "Descobrir um prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
 	"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
 	"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Não Permitir",
 	"Don't Allow": "Não Permitir",
 	"Don't have an account?": "Não tem uma conta?",
 	"Don't have an account?": "Não tem uma conta?",
 	"Don't like the style": "Não gosta do estilo",
 	"Don't like the style": "Não gosta do estilo",
+	"Done": "",
 	"Download": "Baixar",
 	"Download": "Baixar",
 	"Download canceled": "Download cancelado",
 	"Download canceled": "Download cancelado",
 	"Download Database": "Baixar Banco de Dados",
 	"Download Database": "Baixar Banco de Dados",
@@ -312,6 +318,7 @@
 	"Manage Models": "Gerenciar Modelos",
 	"Manage Models": "Gerenciar Modelos",
 	"Manage Ollama Models": "Gerenciar Modelos Ollama",
 	"Manage Ollama Models": "Gerenciar Modelos Ollama",
 	"Manage Pipelines": "Gerenciar pipelines",
 	"Manage Pipelines": "Gerenciar pipelines",
+	"Manage Valves": "",
 	"March": "Março",
 	"March": "Março",
 	"Max Tokens (num_predict)": "Fichas máximas (num_predict)",
 	"Max Tokens (num_predict)": "Fichas máximas (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Máximo de 3 modelos podem ser baixados simultaneamente. Tente novamente mais tarde.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Máximo de 3 modelos podem ser baixados simultaneamente. Tente novamente mais tarde.",
@@ -460,10 +467,12 @@
 	"Seed": "Semente",
 	"Seed": "Semente",
 	"Select a base model": "Selecione um modelo base",
 	"Select a base model": "Selecione um modelo base",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Selecione um modo",
 	"Select a mode": "Selecione um modo",
 	"Select a model": "Selecione um modelo",
 	"Select a model": "Selecione um modelo",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline url": "Selecione uma URL de pipeline",
 	"Select a pipeline url": "Selecione uma URL de pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Selecione um modelo",
 	"Select model": "Selecione um modelo",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Mostrar",
 	"Show shortcuts": "Mostrar",
+	"Show your support!": "",
 	"Showcased creativity": "Criatividade Exibida",
 	"Showcased creativity": "Criatividade Exibida",
 	"sidebar": "barra lateral",
 	"sidebar": "barra lateral",
 	"Sign in": "Entrar",
 	"Sign in": "Entrar",
@@ -584,6 +594,7 @@
 	"Users": "Usuários",
 	"Users": "Usuários",
 	"Utilize": "Utilizar",
 	"Utilize": "Utilizar",
 	"Valid time units:": "Unidades de tempo válidas:",
 	"Valid time units:": "Unidades de tempo válidas:",
+	"Valves": "",
 	"variable": "variável",
 	"variable": "variável",
 	"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
 	"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
 	"Version": "Versão",
 	"Version": "Versão",

+ 11 - 0
src/lib/i18n/locales/pt-PT/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Permitir Exclusão de Conversa",
 	"Allow Chat Deletion": "Permitir Exclusão de Conversa",
 	"Allow non-local voices": "Permitir vozes não locais",
 	"Allow non-local voices": "Permitir vozes não locais",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
 	"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
 	"Already have an account?": "Já tem uma conta?",
 	"Already have an account?": "Já tem uma conta?",
 	"an assistant": "um assistente",
 	"an assistant": "um assistente",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Apagado {{name}}",
 	"Deleted {{name}}": "Apagado {{name}}",
 	"Description": "Descrição",
 	"Description": "Descrição",
 	"Didn't fully follow instructions": "Não seguiu instruções com precisão",
 	"Didn't fully follow instructions": "Não seguiu instruções com precisão",
+	"Discover a function": "",
 	"Discover a model": "Descubra um modelo",
 	"Discover a model": "Descubra um modelo",
 	"Discover a prompt": "Descobrir um prompt",
 	"Discover a prompt": "Descobrir um prompt",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Descubra, descarregue e explore prompts personalizados",
 	"Discover, download, and explore custom prompts": "Descubra, descarregue e explore prompts personalizados",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Descubra, descarregue e explore predefinições de modelo",
 	"Discover, download, and explore model presets": "Descubra, descarregue e explore predefinições de modelo",
 	"Dismissible": "Dispensável",
 	"Dismissible": "Dispensável",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Não Permitir",
 	"Don't Allow": "Não Permitir",
 	"Don't have an account?": "Não tem uma conta?",
 	"Don't have an account?": "Não tem uma conta?",
 	"Don't like the style": "Não gosta do estilo",
 	"Don't like the style": "Não gosta do estilo",
+	"Done": "",
 	"Download": "Descarregar",
 	"Download": "Descarregar",
 	"Download canceled": "Download cancelado",
 	"Download canceled": "Download cancelado",
 	"Download Database": "Descarregar Base de Dados",
 	"Download Database": "Descarregar Base de Dados",
@@ -312,6 +318,7 @@
 	"Manage Models": "Gerir Modelos",
 	"Manage Models": "Gerir Modelos",
 	"Manage Ollama Models": "Gerir Modelos Ollama",
 	"Manage Ollama Models": "Gerir Modelos Ollama",
 	"Manage Pipelines": "Gerir pipelines",
 	"Manage Pipelines": "Gerir pipelines",
+	"Manage Valves": "",
 	"March": "Março",
 	"March": "Março",
 	"Max Tokens (num_predict)": "Máx Tokens (num_predict)",
 	"Max Tokens (num_predict)": "Máx Tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "O máximo de 3 modelos podem ser descarregados simultaneamente. Tente novamente mais tarde.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "O máximo de 3 modelos podem ser descarregados simultaneamente. Tente novamente mais tarde.",
@@ -460,10 +467,12 @@
 	"Seed": "Semente",
 	"Seed": "Semente",
 	"Select a base model": "Selecione um modelo base",
 	"Select a base model": "Selecione um modelo base",
 	"Select a engine": "Selecione um motor",
 	"Select a engine": "Selecione um motor",
+	"Select a function": "",
 	"Select a mode": "Selecione um modo",
 	"Select a mode": "Selecione um modo",
 	"Select a model": "Selecione um modelo",
 	"Select a model": "Selecione um modelo",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline": "Selecione um pipeline",
 	"Select a pipeline url": "Selecione um URL de pipeline",
 	"Select a pipeline url": "Selecione um URL de pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select an Ollama instance": "Selecione uma instância Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Selecione o modelo",
 	"Select model": "Selecione o modelo",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "Mostrar Detalhes do Administrador na sobreposição de Conta Pendente",
 	"Show Admin Details in Account Pending Overlay": "Mostrar Detalhes do Administrador na sobreposição de Conta Pendente",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Mostrar atalhos",
 	"Show shortcuts": "Mostrar atalhos",
+	"Show your support!": "",
 	"Showcased creativity": "Criatividade Exibida",
 	"Showcased creativity": "Criatividade Exibida",
 	"sidebar": "barra lateral",
 	"sidebar": "barra lateral",
 	"Sign in": "Entrar",
 	"Sign in": "Entrar",
@@ -584,6 +594,7 @@
 	"Users": "Utilizadores",
 	"Users": "Utilizadores",
 	"Utilize": "Utilizar",
 	"Utilize": "Utilizar",
 	"Valid time units:": "Unidades de tempo válidas:",
 	"Valid time units:": "Unidades de tempo válidas:",
+	"Valves": "",
 	"variable": "variável",
 	"variable": "variável",
 	"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
 	"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
 	"Version": "Versão",
 	"Version": "Versão",

+ 11 - 0
src/lib/i18n/locales/ru-RU/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Дозволять удаление чат",
 	"Allow Chat Deletion": "Дозволять удаление чат",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "буквенно цифровые символы и дефисы",
 	"alphanumeric characters and hyphens": "буквенно цифровые символы и дефисы",
 	"Already have an account?": "у вас уже есть аккаунт?",
 	"Already have an account?": "у вас уже есть аккаунт?",
 	"an assistant": "ассистент",
 	"an assistant": "ассистент",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Удалено {{name}}",
 	"Deleted {{name}}": "Удалено {{name}}",
 	"Description": "Описание",
 	"Description": "Описание",
 	"Didn't fully follow instructions": "Не полностью следул инструкциям",
 	"Didn't fully follow instructions": "Не полностью следул инструкциям",
+	"Discover a function": "",
 	"Discover a model": "Откройте для себя модель",
 	"Discover a model": "Откройте для себя модель",
 	"Discover a prompt": "Найти промт",
 	"Discover a prompt": "Найти промт",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Находите, загружайте и исследуйте настраиваемые промты",
 	"Discover, download, and explore custom prompts": "Находите, загружайте и исследуйте настраиваемые промты",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Находите, загружайте и исследуйте предустановки модели",
 	"Discover, download, and explore model presets": "Находите, загружайте и исследуйте предустановки модели",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Не разрешать",
 	"Don't Allow": "Не разрешать",
 	"Don't have an account?": "у вас не есть аккаунт?",
 	"Don't have an account?": "у вас не есть аккаунт?",
 	"Don't like the style": "Не нравится стиль",
 	"Don't like the style": "Не нравится стиль",
+	"Done": "",
 	"Download": "Загрузить",
 	"Download": "Загрузить",
 	"Download canceled": "Загрузка отменена",
 	"Download canceled": "Загрузка отменена",
 	"Download Database": "Загрузить базу данных",
 	"Download Database": "Загрузить базу данных",
@@ -312,6 +318,7 @@
 	"Manage Models": "Управление моделями",
 	"Manage Models": "Управление моделями",
 	"Manage Ollama Models": "Управление моделями Ollama",
 	"Manage Ollama Models": "Управление моделями Ollama",
 	"Manage Pipelines": "Управление конвейерами",
 	"Manage Pipelines": "Управление конвейерами",
+	"Manage Valves": "",
 	"March": "Март",
 	"March": "Март",
 	"Max Tokens (num_predict)": "Максимальное количество жетонов (num_predict)",
 	"Max Tokens (num_predict)": "Максимальное количество жетонов (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимальное количество моделей для загрузки одновременно - 3. Пожалуйста, попробуйте позже.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимальное количество моделей для загрузки одновременно - 3. Пожалуйста, попробуйте позже.",
@@ -461,10 +468,12 @@
 	"Seed": "Сид",
 	"Seed": "Сид",
 	"Select a base model": "Выбор базовой модели",
 	"Select a base model": "Выбор базовой модели",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Выберите режим",
 	"Select a mode": "Выберите режим",
 	"Select a model": "Выберите модель",
 	"Select a model": "Выберите модель",
 	"Select a pipeline": "Выбор конвейера",
 	"Select a pipeline": "Выбор конвейера",
 	"Select a pipeline url": "Выберите URL-адрес конвейера",
 	"Select a pipeline url": "Выберите URL-адрес конвейера",
+	"Select a tool": "",
 	"Select an Ollama instance": "Выберите экземпляр Ollama",
 	"Select an Ollama instance": "Выберите экземпляр Ollama",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Выберите модель",
 	"Select model": "Выберите модель",
@@ -497,6 +506,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Показать клавиатурные сокращения",
 	"Show shortcuts": "Показать клавиатурные сокращения",
+	"Show your support!": "",
 	"Showcased creativity": "Показать творчество",
 	"Showcased creativity": "Показать творчество",
 	"sidebar": "боковая панель",
 	"sidebar": "боковая панель",
 	"Sign in": "Войти",
 	"Sign in": "Войти",
@@ -585,6 +595,7 @@
 	"Users": "Пользователи",
 	"Users": "Пользователи",
 	"Utilize": "Использовать",
 	"Utilize": "Использовать",
 	"Valid time units:": "Допустимые единицы времени:",
 	"Valid time units:": "Допустимые единицы времени:",
+	"Valves": "",
 	"variable": "переменная",
 	"variable": "переменная",
 	"variable to have them replaced with clipboard content.": "переменная, чтобы их заменить содержимым буфера обмена.",
 	"variable to have them replaced with clipboard content.": "переменная, чтобы их заменить содержимым буфера обмена.",
 	"Version": "Версия",
 	"Version": "Версия",

+ 11 - 0
src/lib/i18n/locales/sr-RS/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Дозволи брисање ћаскања",
 	"Allow Chat Deletion": "Дозволи брисање ћаскања",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "алфанумерички знакови и цртице",
 	"alphanumeric characters and hyphens": "алфанумерички знакови и цртице",
 	"Already have an account?": "Већ имате налог?",
 	"Already have an account?": "Већ имате налог?",
 	"an assistant": "помоћник",
 	"an assistant": "помоћник",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Избрисано {{наме}}",
 	"Deleted {{name}}": "Избрисано {{наме}}",
 	"Description": "Опис",
 	"Description": "Опис",
 	"Didn't fully follow instructions": "Упутства нису праћена у потпуности",
 	"Didn't fully follow instructions": "Упутства нису праћена у потпуности",
+	"Discover a function": "",
 	"Discover a model": "Откријте модел",
 	"Discover a model": "Откријте модел",
 	"Discover a prompt": "Откриј упит",
 	"Discover a prompt": "Откриј упит",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Откријте, преузмите и истражите прилагођене упите",
 	"Discover, download, and explore custom prompts": "Откријте, преузмите и истражите прилагођене упите",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Откријте, преузмите и истражите образце модела",
 	"Discover, download, and explore model presets": "Откријте, преузмите и истражите образце модела",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Не дозволи",
 	"Don't Allow": "Не дозволи",
 	"Don't have an account?": "Немате налог?",
 	"Don't have an account?": "Немате налог?",
 	"Don't like the style": "Не свиђа ми се стил",
 	"Don't like the style": "Не свиђа ми се стил",
+	"Done": "",
 	"Download": "Преузми",
 	"Download": "Преузми",
 	"Download canceled": "Преузимање отказано",
 	"Download canceled": "Преузимање отказано",
 	"Download Database": "Преузми базу података",
 	"Download Database": "Преузми базу података",
@@ -312,6 +318,7 @@
 	"Manage Models": "Управљај моделима",
 	"Manage Models": "Управљај моделима",
 	"Manage Ollama Models": "Управљај Ollama моделима",
 	"Manage Ollama Models": "Управљај Ollama моделима",
 	"Manage Pipelines": "Управљање цевоводима",
 	"Manage Pipelines": "Управљање цевоводима",
+	"Manage Valves": "",
 	"March": "Март",
 	"March": "Март",
 	"Max Tokens (num_predict)": "Маx Токенс (нум_предицт)",
 	"Max Tokens (num_predict)": "Маx Токенс (нум_предицт)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Највише 3 модела могу бити преузета истовремено. Покушајте поново касније.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Највише 3 модела могу бити преузета истовремено. Покушајте поново касније.",
@@ -460,10 +467,12 @@
 	"Seed": "Семе",
 	"Seed": "Семе",
 	"Select a base model": "Избор основног модела",
 	"Select a base model": "Избор основног модела",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Изабери режим",
 	"Select a mode": "Изабери режим",
 	"Select a model": "Изабери модел",
 	"Select a model": "Изабери модел",
 	"Select a pipeline": "Избор цевовода",
 	"Select a pipeline": "Избор цевовода",
 	"Select a pipeline url": "Избор урл адресе цевовода",
 	"Select a pipeline url": "Избор урл адресе цевовода",
+	"Select a tool": "",
 	"Select an Ollama instance": "Изабери Ollama инстанцу",
 	"Select an Ollama instance": "Изабери Ollama инстанцу",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Изабери модел",
 	"Select model": "Изабери модел",
@@ -496,6 +505,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Прикажи пречице",
 	"Show shortcuts": "Прикажи пречице",
+	"Show your support!": "",
 	"Showcased creativity": "Приказана креативност",
 	"Showcased creativity": "Приказана креативност",
 	"sidebar": "бочна трака",
 	"sidebar": "бочна трака",
 	"Sign in": "Пријави се",
 	"Sign in": "Пријави се",
@@ -584,6 +594,7 @@
 	"Users": "Корисници",
 	"Users": "Корисници",
 	"Utilize": "Искористи",
 	"Utilize": "Искористи",
 	"Valid time units:": "Важеће временске јединице:",
 	"Valid time units:": "Важеће временске јединице:",
+	"Valves": "",
 	"variable": "променљива",
 	"variable": "променљива",
 	"variable to have them replaced with clipboard content.": "променљива за замену са садржајем оставе.",
 	"variable to have them replaced with clipboard content.": "променљива за замену са садржајем оставе.",
 	"Version": "Издање",
 	"Version": "Издање",

+ 11 - 0
src/lib/i18n/locales/sv-SE/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Tillåt chattborttagning",
 	"Allow Chat Deletion": "Tillåt chattborttagning",
 	"Allow non-local voices": "Tillåt icke-lokala röster",
 	"Allow non-local voices": "Tillåt icke-lokala röster",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alfanumeriska tecken och bindestreck",
 	"alphanumeric characters and hyphens": "alfanumeriska tecken och bindestreck",
 	"Already have an account?": "Har du redan ett konto?",
 	"Already have an account?": "Har du redan ett konto?",
 	"an assistant": "en assistent",
 	"an assistant": "en assistent",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Borttagen {{name}}",
 	"Deleted {{name}}": "Borttagen {{name}}",
 	"Description": "Beskrivning",
 	"Description": "Beskrivning",
 	"Didn't fully follow instructions": "Följde inte instruktionerna",
 	"Didn't fully follow instructions": "Följde inte instruktionerna",
+	"Discover a function": "",
 	"Discover a model": "Upptäck en modell",
 	"Discover a model": "Upptäck en modell",
 	"Discover a prompt": "Upptäck en instruktion",
 	"Discover a prompt": "Upptäck en instruktion",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Upptäck, ladda ner och utforska anpassade instruktioner",
 	"Discover, download, and explore custom prompts": "Upptäck, ladda ner och utforska anpassade instruktioner",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Upptäck, ladda ner och utforska modellförinställningar",
 	"Discover, download, and explore model presets": "Upptäck, ladda ner och utforska modellförinställningar",
 	"Dismissible": "Kan stängas",
 	"Dismissible": "Kan stängas",
 	"Display Emoji in Call": "Visa Emoji under samtal",
 	"Display Emoji in Call": "Visa Emoji under samtal",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Tillåt inte",
 	"Don't Allow": "Tillåt inte",
 	"Don't have an account?": "Har du inget konto?",
 	"Don't have an account?": "Har du inget konto?",
 	"Don't like the style": "Tycker inte om utseendet",
 	"Don't like the style": "Tycker inte om utseendet",
+	"Done": "",
 	"Download": "Ladda ner",
 	"Download": "Ladda ner",
 	"Download canceled": "Nedladdning avbruten",
 	"Download canceled": "Nedladdning avbruten",
 	"Download Database": "Ladda ner databas",
 	"Download Database": "Ladda ner databas",
@@ -312,6 +318,7 @@
 	"Manage Models": "Hantera modeller",
 	"Manage Models": "Hantera modeller",
 	"Manage Ollama Models": "Hantera Ollama-modeller",
 	"Manage Ollama Models": "Hantera Ollama-modeller",
 	"Manage Pipelines": "Hantera rörledningar",
 	"Manage Pipelines": "Hantera rörledningar",
+	"Manage Valves": "",
 	"March": "mars",
 	"March": "mars",
 	"Max Tokens (num_predict)": "Maximalt antal tokens (num_predict)",
 	"Max Tokens (num_predict)": "Maximalt antal tokens (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Högst 3 modeller kan laddas ner samtidigt. Vänligen försök igen senare.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Högst 3 modeller kan laddas ner samtidigt. Vänligen försök igen senare.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Välj en basmodell",
 	"Select a base model": "Välj en basmodell",
 	"Select a engine": "Välj en motor",
 	"Select a engine": "Välj en motor",
+	"Select a function": "",
 	"Select a mode": "Välj ett läge",
 	"Select a mode": "Välj ett läge",
 	"Select a model": "Välj en modell",
 	"Select a model": "Välj en modell",
 	"Select a pipeline": "Välj en rörledning",
 	"Select a pipeline": "Välj en rörledning",
 	"Select a pipeline url": "Välj en URL för rörledningen",
 	"Select a pipeline url": "Välj en URL för rörledningen",
+	"Select a tool": "",
 	"Select an Ollama instance": "Välj en Ollama-instans",
 	"Select an Ollama instance": "Välj en Ollama-instans",
 	"Select Documents": "Välj dokument",
 	"Select Documents": "Välj dokument",
 	"Select model": "Välj en modell",
 	"Select model": "Välj en modell",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "Visa administratörsinformation till väntande konton",
 	"Show Admin Details in Account Pending Overlay": "Visa administratörsinformation till väntande konton",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Visa genvägar",
 	"Show shortcuts": "Visa genvägar",
+	"Show your support!": "",
 	"Showcased creativity": "Visade kreativitet",
 	"Showcased creativity": "Visade kreativitet",
 	"sidebar": "sidofält",
 	"sidebar": "sidofält",
 	"Sign in": "Logga in",
 	"Sign in": "Logga in",
@@ -583,6 +593,7 @@
 	"Users": "Användare",
 	"Users": "Användare",
 	"Utilize": "Använd",
 	"Utilize": "Använd",
 	"Valid time units:": "Giltiga tidsenheter:",
 	"Valid time units:": "Giltiga tidsenheter:",
+	"Valves": "",
 	"variable": "variabel",
 	"variable": "variabel",
 	"variable to have them replaced with clipboard content.": "variabel för att få dem ersatta med urklippsinnehåll.",
 	"variable to have them replaced with clipboard content.": "variabel för att få dem ersatta med urklippsinnehåll.",
 	"Version": "Version",
 	"Version": "Version",

+ 11 - 0
src/lib/i18n/locales/tk-TW/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "",
 	"Allow Chat Deletion": "",
 	"Allow non-local voices": "",
 	"Allow non-local voices": "",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "",
 	"alphanumeric characters and hyphens": "",
 	"Already have an account?": "",
 	"Already have an account?": "",
 	"an assistant": "",
 	"an assistant": "",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "",
 	"Deleted {{name}}": "",
 	"Description": "",
 	"Description": "",
 	"Didn't fully follow instructions": "",
 	"Didn't fully follow instructions": "",
+	"Discover a function": "",
 	"Discover a model": "",
 	"Discover a model": "",
 	"Discover a prompt": "",
 	"Discover a prompt": "",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "",
 	"Discover, download, and explore custom prompts": "",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "",
 	"Discover, download, and explore model presets": "",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "",
 	"Don't Allow": "",
 	"Don't have an account?": "",
 	"Don't have an account?": "",
 	"Don't like the style": "",
 	"Don't like the style": "",
+	"Done": "",
 	"Download": "",
 	"Download": "",
 	"Download canceled": "",
 	"Download canceled": "",
 	"Download Database": "",
 	"Download Database": "",
@@ -312,6 +318,7 @@
 	"Manage Models": "",
 	"Manage Models": "",
 	"Manage Ollama Models": "",
 	"Manage Ollama Models": "",
 	"Manage Pipelines": "",
 	"Manage Pipelines": "",
+	"Manage Valves": "",
 	"March": "",
 	"March": "",
 	"Max Tokens (num_predict)": "",
 	"Max Tokens (num_predict)": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
@@ -459,10 +466,12 @@
 	"Seed": "",
 	"Seed": "",
 	"Select a base model": "",
 	"Select a base model": "",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "",
 	"Select a mode": "",
 	"Select a model": "",
 	"Select a model": "",
 	"Select a pipeline": "",
 	"Select a pipeline": "",
 	"Select a pipeline url": "",
 	"Select a pipeline url": "",
+	"Select a tool": "",
 	"Select an Ollama instance": "",
 	"Select an Ollama instance": "",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "",
 	"Select model": "",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "",
 	"Show shortcuts": "",
+	"Show your support!": "",
 	"Showcased creativity": "",
 	"Showcased creativity": "",
 	"sidebar": "",
 	"sidebar": "",
 	"Sign in": "",
 	"Sign in": "",
@@ -583,6 +593,7 @@
 	"Users": "",
 	"Users": "",
 	"Utilize": "",
 	"Utilize": "",
 	"Valid time units:": "",
 	"Valid time units:": "",
+	"Valves": "",
 	"variable": "",
 	"variable": "",
 	"variable to have them replaced with clipboard content.": "",
 	"variable to have them replaced with clipboard content.": "",
 	"Version": "",
 	"Version": "",

+ 11 - 0
src/lib/i18n/locales/tr-TR/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Sohbet Silmeye İzin Ver",
 	"Allow Chat Deletion": "Sohbet Silmeye İzin Ver",
 	"Allow non-local voices": "Yerel olmayan seslere izin verin",
 	"Allow non-local voices": "Yerel olmayan seslere izin verin",
 	"Allow User Location": "",
 	"Allow User Location": "",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler",
 	"alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler",
 	"Already have an account?": "Zaten bir hesabınız mı var?",
 	"Already have an account?": "Zaten bir hesabınız mı var?",
 	"an assistant": "bir asistan",
 	"an assistant": "bir asistan",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "{{name}} silindi",
 	"Deleted {{name}}": "{{name}} silindi",
 	"Description": "Açıklama",
 	"Description": "Açıklama",
 	"Didn't fully follow instructions": "Talimatları tam olarak takip etmedi",
 	"Didn't fully follow instructions": "Talimatları tam olarak takip etmedi",
+	"Discover a function": "",
 	"Discover a model": "Bir model keşfedin",
 	"Discover a model": "Bir model keşfedin",
 	"Discover a prompt": "Bir prompt keşfedin",
 	"Discover a prompt": "Bir prompt keşfedin",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin",
 	"Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin",
 	"Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin",
 	"Dismissible": "",
 	"Dismissible": "",
 	"Display Emoji in Call": "",
 	"Display Emoji in Call": "",
@@ -180,6 +185,7 @@
 	"Don't Allow": "İzin Verme",
 	"Don't Allow": "İzin Verme",
 	"Don't have an account?": "Hesabınız yok mu?",
 	"Don't have an account?": "Hesabınız yok mu?",
 	"Don't like the style": "Tarzını beğenmedim",
 	"Don't like the style": "Tarzını beğenmedim",
+	"Done": "",
 	"Download": "İndir",
 	"Download": "İndir",
 	"Download canceled": "İndirme iptal edildi",
 	"Download canceled": "İndirme iptal edildi",
 	"Download Database": "Veritabanını İndir",
 	"Download Database": "Veritabanını İndir",
@@ -312,6 +318,7 @@
 	"Manage Models": "Modelleri Yönet",
 	"Manage Models": "Modelleri Yönet",
 	"Manage Ollama Models": "Ollama Modellerini Yönet",
 	"Manage Ollama Models": "Ollama Modellerini Yönet",
 	"Manage Pipelines": "Pipeline'ları Yönet",
 	"Manage Pipelines": "Pipeline'ları Yönet",
+	"Manage Valves": "",
 	"March": "Mart",
 	"March": "Mart",
 	"Max Tokens (num_predict)": "Maksimum Token (num_predict)",
 	"Max Tokens (num_predict)": "Maksimum Token (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Aynı anda en fazla 3 model indirilebilir. Lütfen daha sonra tekrar deneyin.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Aynı anda en fazla 3 model indirilebilir. Lütfen daha sonra tekrar deneyin.",
@@ -459,10 +466,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Bir temel model seç",
 	"Select a base model": "Bir temel model seç",
 	"Select a engine": "",
 	"Select a engine": "",
+	"Select a function": "",
 	"Select a mode": "Bir mod seç",
 	"Select a mode": "Bir mod seç",
 	"Select a model": "Bir model seç",
 	"Select a model": "Bir model seç",
 	"Select a pipeline": "Bir pipeline seç",
 	"Select a pipeline": "Bir pipeline seç",
 	"Select a pipeline url": "Bir pipeline URL'si seç",
 	"Select a pipeline url": "Bir pipeline URL'si seç",
+	"Select a tool": "",
 	"Select an Ollama instance": "Bir Ollama örneği seçin",
 	"Select an Ollama instance": "Bir Ollama örneği seçin",
 	"Select Documents": "",
 	"Select Documents": "",
 	"Select model": "Model seç",
 	"Select model": "Model seç",
@@ -495,6 +504,7 @@
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Admin Details in Account Pending Overlay": "",
 	"Show Model": "",
 	"Show Model": "",
 	"Show shortcuts": "Kısayolları göster",
 	"Show shortcuts": "Kısayolları göster",
+	"Show your support!": "",
 	"Showcased creativity": "Sergilenen yaratıcılık",
 	"Showcased creativity": "Sergilenen yaratıcılık",
 	"sidebar": "kenar çubuğu",
 	"sidebar": "kenar çubuğu",
 	"Sign in": "Oturum aç",
 	"Sign in": "Oturum aç",
@@ -583,6 +593,7 @@
 	"Users": "Kullanıcılar",
 	"Users": "Kullanıcılar",
 	"Utilize": "Kullan",
 	"Utilize": "Kullan",
 	"Valid time units:": "Geçerli zaman birimleri:",
 	"Valid time units:": "Geçerli zaman birimleri:",
+	"Valves": "",
 	"variable": "değişken",
 	"variable": "değişken",
 	"variable to have them replaced with clipboard content.": "panodaki içerikle değiştirilmesi için değişken.",
 	"variable to have them replaced with clipboard content.": "panodaki içerikle değiştirilmesi için değişken.",
 	"Version": "Sürüm",
 	"Version": "Sürüm",

+ 11 - 0
src/lib/i18n/locales/uk-UA/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Дозволити видалення чату",
 	"Allow Chat Deletion": "Дозволити видалення чату",
 	"Allow non-local voices": "Дозволити не локальні голоси",
 	"Allow non-local voices": "Дозволити не локальні голоси",
 	"Allow User Location": "Доступ до місцезнаходження",
 	"Allow User Location": "Доступ до місцезнаходження",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "алфавітно-цифрові символи та дефіси",
 	"alphanumeric characters and hyphens": "алфавітно-цифрові символи та дефіси",
 	"Already have an account?": "Вже є обліковий запис?",
 	"Already have an account?": "Вже є обліковий запис?",
 	"an assistant": "асистента",
 	"an assistant": "асистента",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Видалено {{name}}",
 	"Deleted {{name}}": "Видалено {{name}}",
 	"Description": "Опис",
 	"Description": "Опис",
 	"Didn't fully follow instructions": "Не повністю дотримувалися інструкцій",
 	"Didn't fully follow instructions": "Не повністю дотримувалися інструкцій",
+	"Discover a function": "",
 	"Discover a model": "Знайдіть модель",
 	"Discover a model": "Знайдіть модель",
 	"Discover a prompt": "Знайти промт",
 	"Discover a prompt": "Знайти промт",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Знайдіть, завантажте та досліджуйте налаштовані промти",
 	"Discover, download, and explore custom prompts": "Знайдіть, завантажте та досліджуйте налаштовані промти",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Знайдіть, завантажте та досліджуйте налаштовані налаштування моделі",
 	"Discover, download, and explore model presets": "Знайдіть, завантажте та досліджуйте налаштовані налаштування моделі",
 	"Dismissible": "Неприйнятно",
 	"Dismissible": "Неприйнятно",
 	"Display Emoji in Call": "Відображати емодзі у викликах",
 	"Display Emoji in Call": "Відображати емодзі у викликах",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Не дозволяти",
 	"Don't Allow": "Не дозволяти",
 	"Don't have an account?": "Немає облікового запису?",
 	"Don't have an account?": "Немає облікового запису?",
 	"Don't like the style": "Не подобається стиль",
 	"Don't like the style": "Не подобається стиль",
+	"Done": "",
 	"Download": "Завантажити",
 	"Download": "Завантажити",
 	"Download canceled": "Завантаження скасовано",
 	"Download canceled": "Завантаження скасовано",
 	"Download Database": "Завантажити базу даних",
 	"Download Database": "Завантажити базу даних",
@@ -312,6 +318,7 @@
 	"Manage Models": "Керування моделями",
 	"Manage Models": "Керування моделями",
 	"Manage Ollama Models": "Керування моделями Ollama",
 	"Manage Ollama Models": "Керування моделями Ollama",
 	"Manage Pipelines": "Управління Pipelines",
 	"Manage Pipelines": "Управління Pipelines",
+	"Manage Valves": "",
 	"March": "Березень",
 	"March": "Березень",
 	"Max Tokens (num_predict)": "Макс токенів (num_predict)",
 	"Max Tokens (num_predict)": "Макс токенів (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 моделі можна завантажити одночасно. Будь ласка, спробуйте пізніше.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 моделі можна завантажити одночасно. Будь ласка, спробуйте пізніше.",
@@ -461,10 +468,12 @@
 	"Seed": "Сід",
 	"Seed": "Сід",
 	"Select a base model": "Вибрати базову модель",
 	"Select a base model": "Вибрати базову модель",
 	"Select a engine": "Виберіть рушій",
 	"Select a engine": "Виберіть рушій",
+	"Select a function": "",
 	"Select a mode": "Оберіть режим",
 	"Select a mode": "Оберіть режим",
 	"Select a model": "Виберіть модель",
 	"Select a model": "Виберіть модель",
 	"Select a pipeline": "Виберіть pipeline",
 	"Select a pipeline": "Виберіть pipeline",
 	"Select a pipeline url": "Виберіть адресу pipeline",
 	"Select a pipeline url": "Виберіть адресу pipeline",
+	"Select a tool": "",
 	"Select an Ollama instance": "Виберіть екземпляр Ollama",
 	"Select an Ollama instance": "Виберіть екземпляр Ollama",
 	"Select Documents": "Виберіть документи",
 	"Select Documents": "Виберіть документи",
 	"Select model": "Вибрати модель",
 	"Select model": "Вибрати модель",
@@ -497,6 +506,7 @@
 	"Show Admin Details in Account Pending Overlay": "Відобразити дані адміна у вікні очікування облікового запису",
 	"Show Admin Details in Account Pending Overlay": "Відобразити дані адміна у вікні очікування облікового запису",
 	"Show Model": "Показати модель",
 	"Show Model": "Показати модель",
 	"Show shortcuts": "Показати клавіатурні скорочення",
 	"Show shortcuts": "Показати клавіатурні скорочення",
+	"Show your support!": "",
 	"Showcased creativity": "Продемонстрований креатив",
 	"Showcased creativity": "Продемонстрований креатив",
 	"sidebar": "бокова панель",
 	"sidebar": "бокова панель",
 	"Sign in": "Увійти",
 	"Sign in": "Увійти",
@@ -585,6 +595,7 @@
 	"Users": "Користувачі",
 	"Users": "Користувачі",
 	"Utilize": "Використовувати",
 	"Utilize": "Використовувати",
 	"Valid time units:": "Дійсні одиниці часу:",
 	"Valid time units:": "Дійсні одиниці часу:",
+	"Valves": "",
 	"variable": "змінна",
 	"variable": "змінна",
 	"variable to have them replaced with clipboard content.": "змінна, щоб замінити їх вмістом буфера обміну.",
 	"variable to have them replaced with clipboard content.": "змінна, щоб замінити їх вмістом буфера обміну.",
 	"Version": "Версія",
 	"Version": "Версія",

+ 11 - 0
src/lib/i18n/locales/vi-VN/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "Cho phép Xóa nội dung chat",
 	"Allow Chat Deletion": "Cho phép Xóa nội dung chat",
 	"Allow non-local voices": "Cho phép giọng nói không bản xứ",
 	"Allow non-local voices": "Cho phép giọng nói không bản xứ",
 	"Allow User Location": "Cho phép sử dụng vị trí người dùng",
 	"Allow User Location": "Cho phép sử dụng vị trí người dùng",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "ký tự số và gạch nối",
 	"alphanumeric characters and hyphens": "ký tự số và gạch nối",
 	"Already have an account?": "Bạn đã có tài khoản?",
 	"Already have an account?": "Bạn đã có tài khoản?",
 	"an assistant": "trợ lý",
 	"an assistant": "trợ lý",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "Đã xóa {{name}}",
 	"Deleted {{name}}": "Đã xóa {{name}}",
 	"Description": "Mô tả",
 	"Description": "Mô tả",
 	"Didn't fully follow instructions": "Không tuân theo chỉ dẫn một cách đầy đủ",
 	"Didn't fully follow instructions": "Không tuân theo chỉ dẫn một cách đầy đủ",
+	"Discover a function": "",
 	"Discover a model": "Khám phá model",
 	"Discover a model": "Khám phá model",
 	"Discover a prompt": "Khám phá thêm prompt mới",
 	"Discover a prompt": "Khám phá thêm prompt mới",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "Tìm kiếm, tải về và khám phá thêm các prompt tùy chỉnh",
 	"Discover, download, and explore custom prompts": "Tìm kiếm, tải về và khám phá thêm các prompt tùy chỉnh",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "Tìm kiếm, tải về và khám phá thêm các thiết lập mô hình sẵn",
 	"Discover, download, and explore model presets": "Tìm kiếm, tải về và khám phá thêm các thiết lập mô hình sẵn",
 	"Dismissible": "Có thể loại bỏ",
 	"Dismissible": "Có thể loại bỏ",
 	"Display Emoji in Call": "Hiển thị Emoji trong cuộc gọi",
 	"Display Emoji in Call": "Hiển thị Emoji trong cuộc gọi",
@@ -180,6 +185,7 @@
 	"Don't Allow": "Không Cho phép",
 	"Don't Allow": "Không Cho phép",
 	"Don't have an account?": "Không có tài khoản?",
 	"Don't have an account?": "Không có tài khoản?",
 	"Don't like the style": "Không thích phong cách trả lời",
 	"Don't like the style": "Không thích phong cách trả lời",
+	"Done": "",
 	"Download": "Tải về",
 	"Download": "Tải về",
 	"Download canceled": "Đã hủy download",
 	"Download canceled": "Đã hủy download",
 	"Download Database": "Tải xuống Cơ sở dữ liệu",
 	"Download Database": "Tải xuống Cơ sở dữ liệu",
@@ -312,6 +318,7 @@
 	"Manage Models": "Quản lý mô hình",
 	"Manage Models": "Quản lý mô hình",
 	"Manage Ollama Models": "Quản lý mô hình với Ollama",
 	"Manage Ollama Models": "Quản lý mô hình với Ollama",
 	"Manage Pipelines": "Quản lý Pipelines",
 	"Manage Pipelines": "Quản lý Pipelines",
+	"Manage Valves": "",
 	"March": "Tháng 3",
 	"March": "Tháng 3",
 	"Max Tokens (num_predict)": "Tokens tối đa (num_predict)",
 	"Max Tokens (num_predict)": "Tokens tối đa (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Tối đa 3 mô hình có thể được tải xuống cùng lúc. Vui lòng thử lại sau.",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Tối đa 3 mô hình có thể được tải xuống cùng lúc. Vui lòng thử lại sau.",
@@ -458,10 +465,12 @@
 	"Seed": "Seed",
 	"Seed": "Seed",
 	"Select a base model": "Chọn một base model",
 	"Select a base model": "Chọn một base model",
 	"Select a engine": "Chọn dịch vụ",
 	"Select a engine": "Chọn dịch vụ",
+	"Select a function": "",
 	"Select a mode": "Chọn một chế độ",
 	"Select a mode": "Chọn một chế độ",
 	"Select a model": "Chọn mô hình",
 	"Select a model": "Chọn mô hình",
 	"Select a pipeline": "Chọn một quy trình",
 	"Select a pipeline": "Chọn một quy trình",
 	"Select a pipeline url": "Chọn url quy trình",
 	"Select a pipeline url": "Chọn url quy trình",
+	"Select a tool": "",
 	"Select an Ollama instance": "Chọn một thực thể Ollama",
 	"Select an Ollama instance": "Chọn một thực thể Ollama",
 	"Select Documents": "Chọn tài liệu",
 	"Select Documents": "Chọn tài liệu",
 	"Select model": "Chọn model",
 	"Select model": "Chọn model",
@@ -494,6 +503,7 @@
 	"Show Admin Details in Account Pending Overlay": "Hiển thị thông tin của Quản trị viên trên màn hình hiển thị Tài khoản đang chờ xử lý",
 	"Show Admin Details in Account Pending Overlay": "Hiển thị thông tin của Quản trị viên trên màn hình hiển thị Tài khoản đang chờ xử lý",
 	"Show Model": "Hiện mô hình",
 	"Show Model": "Hiện mô hình",
 	"Show shortcuts": "Hiển thị phím tắt",
 	"Show shortcuts": "Hiển thị phím tắt",
+	"Show your support!": "",
 	"Showcased creativity": "Thể hiện sự sáng tạo",
 	"Showcased creativity": "Thể hiện sự sáng tạo",
 	"sidebar": "thanh bên",
 	"sidebar": "thanh bên",
 	"Sign in": "Đăng nhập",
 	"Sign in": "Đăng nhập",
@@ -582,6 +592,7 @@
 	"Users": "Người sử dụng",
 	"Users": "Người sử dụng",
 	"Utilize": "Sử dụng",
 	"Utilize": "Sử dụng",
 	"Valid time units:": "Đơn vị thời gian hợp lệ:",
 	"Valid time units:": "Đơn vị thời gian hợp lệ:",
+	"Valves": "",
 	"variable": "biến",
 	"variable": "biến",
 	"variable to have them replaced with clipboard content.": "biến để có chúng được thay thế bằng nội dung clipboard.",
 	"variable to have them replaced with clipboard content.": "biến để có chúng được thay thế bằng nội dung clipboard.",
 	"Version": "Version",
 	"Version": "Version",

+ 17 - 6
src/lib/i18n/locales/zh-CN/translation.json

@@ -43,6 +43,7 @@
 	"Allow Chat Deletion": "允许删除聊天记录",
 	"Allow Chat Deletion": "允许删除聊天记录",
 	"Allow non-local voices": "允许调用非本地音色",
 	"Allow non-local voices": "允许调用非本地音色",
 	"Allow User Location": "允许获取您的位置",
 	"Allow User Location": "允许获取您的位置",
+	"Allow Voice Interruption in Call": "",
 	"alphanumeric characters and hyphens": "字母数字字符和连字符",
 	"alphanumeric characters and hyphens": "字母数字字符和连字符",
 	"Already have an account?": "已经拥有账号了?",
 	"Already have an account?": "已经拥有账号了?",
 	"an assistant": "助手",
 	"an assistant": "助手",
@@ -99,7 +100,7 @@
 	"Clear memory": "清除记忆",
 	"Clear memory": "清除记忆",
 	"Click here for help.": "点击这里获取帮助。",
 	"Click here for help.": "点击这里获取帮助。",
 	"Click here to": "单击",
 	"Click here to": "单击",
-	"Click here to download user import template file.": "",
+	"Click here to download user import template file.": "单击此处下载用户导入所需的模板文件。",
 	"Click here to select": "点击这里选择",
 	"Click here to select": "点击这里选择",
 	"Click here to select a csv file.": "单击此处选择 csv 文件。",
 	"Click here to select a csv file.": "单击此处选择 csv 文件。",
 	"Click here to select a py file.": "单击此处选择 py 文件。",
 	"Click here to select a py file.": "单击此处选择 py 文件。",
@@ -135,8 +136,8 @@
 	"Create new secret key": "创建新安全密钥",
 	"Create new secret key": "创建新安全密钥",
 	"Created at": "创建于",
 	"Created at": "创建于",
 	"Created At": "创建于",
 	"Created At": "创建于",
-	"Created by": "",
-	"CSV Import": "",
+	"Created by": "作者",
+	"CSV Import": "通过 CSV 文件导入",
 	"Current Model": "当前模型",
 	"Current Model": "当前模型",
 	"Current Password": "当前密码",
 	"Current Password": "当前密码",
 	"Custom": "自定义",
 	"Custom": "自定义",
@@ -165,9 +166,13 @@
 	"Deleted {{name}}": "已删除 {{name}}",
 	"Deleted {{name}}": "已删除 {{name}}",
 	"Description": "描述",
 	"Description": "描述",
 	"Didn't fully follow instructions": "没有完全遵照指示",
 	"Didn't fully follow instructions": "没有完全遵照指示",
+	"Discover a function": "",
 	"Discover a model": "发现更多模型",
 	"Discover a model": "发现更多模型",
 	"Discover a prompt": "发现更多提示词",
 	"Discover a prompt": "发现更多提示词",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
 	"Discover, download, and explore custom prompts": "发现、下载并探索更多自定义提示词",
 	"Discover, download, and explore custom prompts": "发现、下载并探索更多自定义提示词",
+	"Discover, download, and explore custom tools": "",
 	"Discover, download, and explore model presets": "发现、下载并探索更多模型预设",
 	"Discover, download, and explore model presets": "发现、下载并探索更多模型预设",
 	"Dismissible": "是否可关闭",
 	"Dismissible": "是否可关闭",
 	"Display Emoji in Call": "在通话中显示 Emoji 表情符号",
 	"Display Emoji in Call": "在通话中显示 Emoji 表情符号",
@@ -180,6 +185,7 @@
 	"Don't Allow": "不允许",
 	"Don't Allow": "不允许",
 	"Don't have an account?": "没有账号?",
 	"Don't have an account?": "没有账号?",
 	"Don't like the style": "不喜欢这个文风",
 	"Don't like the style": "不喜欢这个文风",
+	"Done": "",
 	"Download": "下载",
 	"Download": "下载",
 	"Download canceled": "下载已取消",
 	"Download canceled": "下载已取消",
 	"Download Database": "下载数据库",
 	"Download Database": "下载数据库",
@@ -250,7 +256,7 @@
 	"Fluidly stream large external response chunks": "流畅地传输外部大型响应块数据",
 	"Fluidly stream large external response chunks": "流畅地传输外部大型响应块数据",
 	"Focus chat input": "聚焦对话输入",
 	"Focus chat input": "聚焦对话输入",
 	"Followed instructions perfectly": "完全按照指示执行",
 	"Followed instructions perfectly": "完全按照指示执行",
-	"Form": "",
+	"Form": "手动创建",
 	"Format your variables using square brackets like this:": "使用这样的方括号格式化你的变量:",
 	"Format your variables using square brackets like this:": "使用这样的方括号格式化你的变量:",
 	"Frequency Penalty": "频率惩罚",
 	"Frequency Penalty": "频率惩罚",
 	"Functions": "功能",
 	"Functions": "功能",
@@ -267,7 +273,7 @@
 	"Hello, {{name}}": "您好,{{name}}",
 	"Hello, {{name}}": "您好,{{name}}",
 	"Help": "帮助",
 	"Help": "帮助",
 	"Hide": "隐藏",
 	"Hide": "隐藏",
-	"Hide Model": "隐藏模型",
+	"Hide Model": "隐藏",
 	"How can I help you today?": "有什么我能帮您的吗?",
 	"How can I help you today?": "有什么我能帮您的吗?",
 	"Hybrid Search": "混合搜索",
 	"Hybrid Search": "混合搜索",
 	"Image Generation (Experimental)": "图像生成(实验性)",
 	"Image Generation (Experimental)": "图像生成(实验性)",
@@ -312,6 +318,7 @@
 	"Manage Models": "管理模型",
 	"Manage Models": "管理模型",
 	"Manage Ollama Models": "管理 Ollama 模型",
 	"Manage Ollama Models": "管理 Ollama 模型",
 	"Manage Pipelines": "管理 Pipeline",
 	"Manage Pipelines": "管理 Pipeline",
+	"Manage Valves": "",
 	"March": "三月",
 	"March": "三月",
 	"Max Tokens (num_predict)": "最多 Token (num_predict)",
 	"Max Tokens (num_predict)": "最多 Token (num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同时下载 3 个模型,请稍后重试。",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同时下载 3 个模型,请稍后重试。",
@@ -458,10 +465,12 @@
 	"Seed": "种子 (Seed)",
 	"Seed": "种子 (Seed)",
 	"Select a base model": "选择一个基础模型",
 	"Select a base model": "选择一个基础模型",
 	"Select a engine": "选择一个搜索引擎",
 	"Select a engine": "选择一个搜索引擎",
+	"Select a function": "",
 	"Select a mode": "选择一个模式",
 	"Select a mode": "选择一个模式",
 	"Select a model": "选择一个模型",
 	"Select a model": "选择一个模型",
 	"Select a pipeline": "选择一个管道",
 	"Select a pipeline": "选择一个管道",
 	"Select a pipeline url": "选择一个管道 URL",
 	"Select a pipeline url": "选择一个管道 URL",
+	"Select a tool": "",
 	"Select an Ollama instance": "选择一个 Ollama 实例",
 	"Select an Ollama instance": "选择一个 Ollama 实例",
 	"Select Documents": "选择文档",
 	"Select Documents": "选择文档",
 	"Select model": "选择模型",
 	"Select model": "选择模型",
@@ -492,8 +501,9 @@
 	"short-summary": "简短总结",
 	"short-summary": "简短总结",
 	"Show": "显示",
 	"Show": "显示",
 	"Show Admin Details in Account Pending Overlay": "在用户待激活界面中显示管理员邮箱等详细信息",
 	"Show Admin Details in Account Pending Overlay": "在用户待激活界面中显示管理员邮箱等详细信息",
-	"Show Model": "显示模型",
+	"Show Model": "显示",
 	"Show shortcuts": "显示快捷方式",
 	"Show shortcuts": "显示快捷方式",
+	"Show your support!": "",
 	"Showcased creativity": "很有创意",
 	"Showcased creativity": "很有创意",
 	"sidebar": "侧边栏",
 	"sidebar": "侧边栏",
 	"Sign in": "登录",
 	"Sign in": "登录",
@@ -582,6 +592,7 @@
 	"Users": "用户",
 	"Users": "用户",
 	"Utilize": "利用",
 	"Utilize": "利用",
 	"Valid time units:": "有效时间单位:",
 	"Valid time units:": "有效时间单位:",
+	"Valves": "",
 	"variable": "变量",
 	"variable": "变量",
 	"variable to have them replaced with clipboard content.": "变量将被剪贴板内容替换。",
 	"variable to have them replaced with clipboard content.": "变量将被剪贴板内容替换。",
 	"Version": "版本",
 	"Version": "版本",

+ 251 - 240
src/lib/i18n/locales/zh-TW/translation.json

@@ -4,36 +4,36 @@
 	"(e.g. `sh webui.sh --api`)": "(例如 `sh webui.sh --api`)",
 	"(e.g. `sh webui.sh --api`)": "(例如 `sh webui.sh --api`)",
 	"(latest)": "(最新版)",
 	"(latest)": "(最新版)",
 	"{{ models }}": "{{ models }}",
 	"{{ models }}": "{{ models }}",
-	"{{ owner }}: You cannot delete a base model": "{{ owner }}:你無法刪除基本模型",
+	"{{ owner }}: You cannot delete a base model": "{{ owner }}:您無法刪除基礎模型",
 	"{{modelName}} is thinking...": "{{modelName}} 正在思考...",
 	"{{modelName}} is thinking...": "{{modelName}} 正在思考...",
 	"{{user}}'s Chats": "{{user}} 的聊天",
 	"{{user}}'s Chats": "{{user}} 的聊天",
-	"{{webUIName}} Backend Required": "需要 {{webUIName}} 後",
-	"A task model is used when performing tasks such as generating titles for chats and web search queries": "在執行任務時使用任務模型,例如為聊天和網絡搜索查詢生成標題",
+	"{{webUIName}} Backend Required": "需要 {{webUIName}} 後",
+	"A task model is used when performing tasks such as generating titles for chats and web search queries": "在執行任務時使用任務模型,例如為聊天和網頁搜尋查詢生成標題",
 	"a user": "使用者",
 	"a user": "使用者",
 	"About": "關於",
 	"About": "關於",
 	"Account": "帳號",
 	"Account": "帳號",
-	"Account Activation Pending": "",
-	"Accurate information": "準確信息",
-	"Active Users": "",
+	"Account Activation Pending": "帳號啟用中",
+	"Accurate information": "準確資訊",
+	"Active Users": "活躍使用者",
 	"Add": "新增",
 	"Add": "新增",
 	"Add a model id": "新增模型 ID",
 	"Add a model id": "新增模型 ID",
-	"Add a short description about what this model does": "為這個模型添加一個簡短描述",
-	"Add a short title for this prompt": "為這個提示詞添加一個簡短的標題",
+	"Add a short description about what this model does": "為這個模型新增一個簡短描述",
+	"Add a short title for this prompt": "為這個提示詞新增一個簡短的標題",
 	"Add a tag": "新增標籤",
 	"Add a tag": "新增標籤",
-	"Add custom prompt": "新增自定義提示詞",
+	"Add custom prompt": "新增自提示詞",
 	"Add Docs": "新增文件",
 	"Add Docs": "新增文件",
 	"Add Files": "新增檔案",
 	"Add Files": "新增檔案",
 	"Add Memory": "新增記憶",
 	"Add Memory": "新增記憶",
 	"Add message": "新增訊息",
 	"Add message": "新增訊息",
 	"Add Model": "新增模型",
 	"Add Model": "新增模型",
 	"Add Tags": "新增標籤",
 	"Add Tags": "新增標籤",
-	"Add User": "新增用户",
+	"Add User": "新增使用者",
 	"Adjusting these settings will apply changes universally to all users.": "調整這些設定將對所有使用者進行更改。",
 	"Adjusting these settings will apply changes universally to all users.": "調整這些設定將對所有使用者進行更改。",
 	"admin": "管理員",
 	"admin": "管理員",
-	"Admin": "",
+	"Admin": "管理員",
 	"Admin Panel": "管理員控制台",
 	"Admin Panel": "管理員控制台",
 	"Admin Settings": "管理設定",
 	"Admin Settings": "管理設定",
-	"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "",
+	"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理員隨時可以使用所有工具;使用者需要在工作區中為每個模型分配工具。",
 	"Advanced Parameters": "進階參數",
 	"Advanced Parameters": "進階參數",
 	"Advanced Params": "進階參數",
 	"Advanced Params": "進階參數",
 	"all": "所有",
 	"all": "所有",
@@ -41,43 +41,44 @@
 	"All Users": "所有使用者",
 	"All Users": "所有使用者",
 	"Allow": "允許",
 	"Allow": "允許",
 	"Allow Chat Deletion": "允許刪除聊天紀錄",
 	"Allow Chat Deletion": "允許刪除聊天紀錄",
-	"Allow non-local voices": "",
-	"Allow User Location": "",
-	"alphanumeric characters and hyphens": "英文字母、數字(0~9)和連字符(-)",
+	"Allow non-local voices": "允許非本機語音",
+	"Allow User Location": "允許使用者位置",
+	"Allow Voice Interruption in Call": "",
+	"alphanumeric characters and hyphens": "英文字母、數字(0~9)和連字元(-)",
 	"Already have an account?": "已經有帳號了嗎?",
 	"Already have an account?": "已經有帳號了嗎?",
 	"an assistant": "助手",
 	"an assistant": "助手",
 	"and": "和",
 	"and": "和",
-	"and create a new shared link.": "創建一個新的共享連結。",
+	"and create a new shared link.": "並建立一個新的共享連結。",
 	"API Base URL": "API 基本 URL",
 	"API Base URL": "API 基本 URL",
-	"API Key": "API Key",
-	"API Key created.": "API Key",
-	"API keys": "API Keys",
-	"April": "4月",
-	"Archive": "存",
-	"Archive All Chats": "存所有聊天紀錄",
-	"Archived Chats": "聊天記錄存檔",
+	"API Key": "API 金鑰",
+	"API Key created.": "API 金鑰已建立。",
+	"API keys": "API 金鑰",
+	"April": "4 月",
+	"Archive": "存",
+	"Archive All Chats": "存所有聊天紀錄",
+	"Archived Chats": "已封存的聊天紀錄",
 	"are allowed - Activate this command by typing": "是允許的 - 透過輸入",
 	"are allowed - Activate this command by typing": "是允許的 - 透過輸入",
-	"Are you sure?": "確定嗎?",
+	"Are you sure?": "確定嗎?",
 	"Attach file": "附加檔案",
 	"Attach file": "附加檔案",
 	"Attention to detail": "細節精確",
 	"Attention to detail": "細節精確",
 	"Audio": "音訊",
 	"Audio": "音訊",
-	"August": "8月",
+	"August": "8 月",
 	"Auto-playback response": "自動播放回答",
 	"Auto-playback response": "自動播放回答",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 基本 URL",
 	"AUTOMATIC1111 Base URL": "AUTOMATIC1111 基本 URL",
 	"AUTOMATIC1111 Base URL is required.": "需要 AUTOMATIC1111 基本 URL",
 	"AUTOMATIC1111 Base URL is required.": "需要 AUTOMATIC1111 基本 URL",
-	"available!": "可以使用!",
+	"available!": "可用!",
 	"Back": "返回",
 	"Back": "返回",
 	"Bad Response": "錯誤回應",
 	"Bad Response": "錯誤回應",
 	"Banners": "橫幅",
 	"Banners": "橫幅",
-	"Base Model (From)": "基模型(來自)",
-	"Batch Size (num_batch)": "",
+	"Base Model (From)": "基模型(來自)",
+	"Batch Size (num_batch)": "批次大小(num_batch)",
 	"before": "前",
 	"before": "前",
 	"Being lazy": "懶人模式",
 	"Being lazy": "懶人模式",
-	"Brave Search API Key": "搜尋 API Key",
-	"Bypass SSL verification for Websites": "跳過 SSL 驗證",
-	"Call": "",
-	"Call feature is not supported when using Web STT engine": "",
-	"Camera": "",
+	"Brave Search API Key": "Brave 搜尋 API 金鑰",
+	"Bypass SSL verification for Websites": "跳過網站的 SSL 驗證",
+	"Call": "呼叫",
+	"Call feature is not supported when using Web STT engine": "使用 Web STT 引擎時不支援呼叫功能",
+	"Camera": "相機",
 	"Cancel": "取消",
 	"Cancel": "取消",
 	"Capabilities": "功能",
 	"Capabilities": "功能",
 	"Change Password": "修改密碼",
 	"Change Password": "修改密碼",
@@ -85,27 +86,27 @@
 	"Chat Background Image": "",
 	"Chat Background Image": "",
 	"Chat Bubble UI": "聊天氣泡介面",
 	"Chat Bubble UI": "聊天氣泡介面",
 	"Chat direction": "聊天方向",
 	"Chat direction": "聊天方向",
-	"Chat History": "聊天紀錄功能",
-	"Chat History is off for this browser.": "此瀏覽器已關閉聊天紀錄功能。",
+	"Chat History": "聊天紀錄",
+	"Chat History is off for this browser.": "此瀏覽器已關閉聊天紀錄。",
 	"Chats": "聊天",
 	"Chats": "聊天",
 	"Check Again": "重新檢查",
 	"Check Again": "重新檢查",
 	"Check for updates": "檢查更新",
 	"Check for updates": "檢查更新",
 	"Checking for updates...": "正在檢查更新...",
 	"Checking for updates...": "正在檢查更新...",
 	"Choose a model before saving...": "儲存前選擇一個模型...",
 	"Choose a model before saving...": "儲存前選擇一個模型...",
-	"Chunk Overlap": "Chunk Overlap",
-	"Chunk Params": "Chunk 參數",
-	"Chunk Size": "Chunk 大小",
+	"Chunk Overlap": "區塊重疊",
+	"Chunk Params": "區塊參數",
+	"Chunk Size": "區塊大小",
 	"Citation": "引文",
 	"Citation": "引文",
-	"Clear memory": "",
-	"Click here for help.": "點擊這裡尋找幫助。",
-	"Click here to": "點這裡",
-	"Click here to download user import template file.": "",
-	"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.": "點擊使用者 Role 按鈕以更改使用者的 Role。",
+	"Clear memory": "清除記憶",
+	"Click here for help.": "點選這裡尋求幫助。",
+	"Click here to": "點這裡",
+	"Click here to download user import template file.": "點選這裡下載使用者匯入的範本",
+	"Click here to select": "點這裡選擇",
+	"Click here to select a csv file.": "點這裡選擇 csv 檔案。",
+	"Click here to select a py file.": "點選這裡選擇 py 檔案。",
+	"Click here to select documents.": "點這裡選擇文件。",
+	"click here.": "點這裡。",
+	"Click on the user role button to change a user's role.": "點選使用者角色按鈕以更改使用者的角色。",
 	"Clone": "複製",
 	"Clone": "複製",
 	"Close": "關閉",
 	"Close": "關閉",
 	"Collection": "收藏",
 	"Collection": "收藏",
@@ -118,7 +119,7 @@
 	"Confirm Password": "確認密碼",
 	"Confirm Password": "確認密碼",
 	"Confirm your action": "",
 	"Confirm your action": "",
 	"Connections": "連線",
 	"Connections": "連線",
-	"Contact Admin for WebUI Access": "",
+	"Contact Admin for WebUI Access": "聯絡管理員以取得 WebUI 存取權",
 	"Content": "內容",
 	"Content": "內容",
 	"Context Length": "上下文長度",
 	"Context Length": "上下文長度",
 	"Continue Response": "繼續回答",
 	"Continue Response": "繼續回答",
@@ -131,8 +132,8 @@
 	"Copying to clipboard was successful!": "成功複製到剪貼簿!",
 	"Copying to clipboard was successful!": "成功複製到剪貼簿!",
 	"Create a model": "建立模型",
 	"Create a model": "建立模型",
 	"Create Account": "建立帳號",
 	"Create Account": "建立帳號",
-	"Create new key": "建立新鑰",
-	"Create new secret key": "建立新鑰",
+	"Create new key": "建立新鑰",
+	"Create new secret key": "建立新鑰",
 	"Created at": "建立於",
 	"Created at": "建立於",
 	"Created At": "建立於",
 	"Created At": "建立於",
 	"Created by": "",
 	"Created by": "",
@@ -140,18 +141,18 @@
 	"Current Model": "目前模型",
 	"Current Model": "目前模型",
 	"Current Password": "目前密碼",
 	"Current Password": "目前密碼",
 	"Custom": "自訂",
 	"Custom": "自訂",
-	"Customize models for a specific purpose": "為特定目的自定義模型",
+	"Customize models for a specific purpose": "為特定目的自模型",
 	"Dark": "暗色",
 	"Dark": "暗色",
-	"Dashboard": "",
+	"Dashboard": "儀表板",
 	"Database": "資料庫",
 	"Database": "資料庫",
-	"December": "12月",
+	"December": "12 月",
 	"Default": "預設",
 	"Default": "預設",
 	"Default (Automatic1111)": "預設(Automatic1111)",
 	"Default (Automatic1111)": "預設(Automatic1111)",
 	"Default (SentenceTransformers)": "預設(SentenceTransformers)",
 	"Default (SentenceTransformers)": "預設(SentenceTransformers)",
 	"Default Model": "預設模型",
 	"Default Model": "預設模型",
 	"Default model updated": "預設模型已更新",
 	"Default model updated": "預設模型已更新",
 	"Default Prompt Suggestions": "預設提示詞建議",
 	"Default Prompt Suggestions": "預設提示詞建議",
-	"Default User Role": "預設用戶 Role",
+	"Default User Role": "預設使用者角色",
 	"delete": "刪除",
 	"delete": "刪除",
 	"Delete": "刪除",
 	"Delete": "刪除",
 	"Delete a model": "刪除一個模型",
 	"Delete a model": "刪除一個模型",
@@ -160,178 +161,184 @@
 	"Delete Chat": "刪除聊天紀錄",
 	"Delete Chat": "刪除聊天紀錄",
 	"Delete chat?": "",
 	"Delete chat?": "",
 	"delete this link": "刪除此連結",
 	"delete this link": "刪除此連結",
-	"Delete User": "刪除用戶",
+	"Delete User": "刪除使用者",
 	"Deleted {{deleteModelTag}}": "已刪除 {{deleteModelTag}}",
 	"Deleted {{deleteModelTag}}": "已刪除 {{deleteModelTag}}",
 	"Deleted {{name}}": "已刪除 {{name}}",
 	"Deleted {{name}}": "已刪除 {{name}}",
 	"Description": "描述",
 	"Description": "描述",
-	"Didn't fully follow instructions": "無法完全遵循指示",
+	"Didn't fully follow instructions": "未完全遵循指示",
+	"Discover a function": "",
 	"Discover a model": "發現新模型",
 	"Discover a model": "發現新模型",
 	"Discover a prompt": "發現新提示詞",
 	"Discover a prompt": "發現新提示詞",
-	"Discover, download, and explore custom prompts": "發現、下載並探索他人設置的提示詞",
-	"Discover, download, and explore model presets": "發現、下載並探索他人設置的模型",
-	"Dismissible": "",
-	"Display Emoji in Call": "",
-	"Display the username instead of You in the Chat": "在聊天中顯示使用者名稱而不是「你」",
+	"Discover a tool": "",
+	"Discover, download, and explore custom functions": "",
+	"Discover, download, and explore custom prompts": "發現、下載並探索自訂提示詞",
+	"Discover, download, and explore custom tools": "",
+	"Discover, download, and explore model presets": "發現、下載並探索模型預設值",
+	"Dismissible": "可忽略",
+	"Display Emoji in Call": "在呼叫中顯示表情符號",
+	"Display the username instead of You in the Chat": "在聊天中顯示使用者名稱而不是「您」",
 	"Document": "文件",
 	"Document": "文件",
 	"Document Settings": "文件設定",
 	"Document Settings": "文件設定",
-	"Documentation": "",
+	"Documentation": "文件",
 	"Documents": "文件",
 	"Documents": "文件",
-	"does not make any external connections, and your data stays securely on your locally hosted server.": "不會與外部溝通,你的數據會安全地留在你的本機伺服器上。",
+	"does not make any external connections, and your data stays securely on your locally hosted server.": "不會與外部連線,您的資料會安全地留在您的本機伺服器上。",
 	"Don't Allow": "不允許",
 	"Don't Allow": "不允許",
 	"Don't have an account?": "還沒有註冊帳號?",
 	"Don't have an account?": "還沒有註冊帳號?",
 	"Don't like the style": "不喜歡這個樣式?",
 	"Don't like the style": "不喜歡這個樣式?",
+	"Done": "",
 	"Download": "下載",
 	"Download": "下載",
 	"Download canceled": "下載已取消",
 	"Download canceled": "下載已取消",
 	"Download Database": "下載資料庫",
 	"Download Database": "下載資料庫",
-	"Drop any files here to add to the conversation": "拖拽文件到此處以新增至對話",
+	"Drop any files here to add to the conversation": "拖拽任意檔案到此處以新增至對話",
 	"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例如 '30s', '10m'。有效的時間單位為 's', 'm', 'h'。",
 	"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例如 '30s', '10m'。有效的時間單位為 's', 'm', 'h'。",
 	"Edit": "編輯",
 	"Edit": "編輯",
 	"Edit Doc": "編輯文件",
 	"Edit Doc": "編輯文件",
-	"Edit Memory": "",
+	"Edit Memory": "編輯記憶",
 	"Edit User": "編輯使用者",
 	"Edit User": "編輯使用者",
 	"Email": "電子郵件",
 	"Email": "電子郵件",
-	"Embedding Batch Size": "",
+	"Embedding Batch Size": "嵌入批次大小",
 	"Embedding Model": "嵌入模型",
 	"Embedding Model": "嵌入模型",
 	"Embedding Model Engine": "嵌入模型引擎",
 	"Embedding Model Engine": "嵌入模型引擎",
 	"Embedding model set to \"{{embedding_model}}\"": "嵌入模型已設定為 \"{{embedding_model}}\"",
 	"Embedding model set to \"{{embedding_model}}\"": "嵌入模型已設定為 \"{{embedding_model}}\"",
-	"Enable Chat History": "啟用聊天歷史",
-	"Enable Community Sharing": "啟用社分享",
+	"Enable Chat History": "啟用聊天紀錄",
+	"Enable Community Sharing": "啟用社分享",
 	"Enable New Sign Ups": "允許註冊新帳號",
 	"Enable New Sign Ups": "允許註冊新帳號",
-	"Enable Web Search": "啟用網絡搜索",
-	"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確保的 CSV 檔案包含這四個欄位,並按照此順序:名稱、電子郵件、密碼、角色。",
+	"Enable Web Search": "啟用網頁搜尋",
+	"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確保的 CSV 檔案包含這四個欄位,並按照此順序:名稱、電子郵件、密碼、角色。",
 	"Enter {{role}} message here": "在這裡輸入 {{role}} 訊息",
 	"Enter {{role}} message here": "在這裡輸入 {{role}} 訊息",
 	"Enter a detail about yourself for your LLMs to recall": "輸入 LLM 記憶的詳細內容",
 	"Enter a detail about yourself for your LLMs to recall": "輸入 LLM 記憶的詳細內容",
-	"Enter Brave Search API Key": "輸入 Brave Search API Key",
-	"Enter Chunk Overlap": "輸入 Chunk Overlap",
-	"Enter Chunk Size": "輸入 Chunk 大小",
+	"Enter Brave Search API Key": "輸入 Brave 搜尋 API 金鑰",
+	"Enter Chunk Overlap": "輸入區塊重疊",
+	"Enter Chunk Size": "輸入區塊大小",
 	"Enter Github Raw URL": "輸入 Github Raw URL",
 	"Enter Github Raw URL": "輸入 Github Raw URL",
-	"Enter Google PSE API Key": "輸入 Google PSE API Key",
-	"Enter Google PSE Engine Id": "輸入 Google PSE Engine Id",
+	"Enter Google PSE API Key": "輸入 Google PSE API 金鑰",
+	"Enter Google PSE Engine Id": "輸入 Google PSE 引擎 ID",
 	"Enter Image Size (e.g. 512x512)": "輸入圖片大小(例如 512x512)",
 	"Enter Image Size (e.g. 512x512)": "輸入圖片大小(例如 512x512)",
 	"Enter language codes": "輸入語言代碼",
 	"Enter language codes": "輸入語言代碼",
 	"Enter model tag (e.g. {{modelTag}})": "輸入模型標籤(例如 {{modelTag}})",
 	"Enter model tag (e.g. {{modelTag}})": "輸入模型標籤(例如 {{modelTag}})",
 	"Enter Number of Steps (e.g. 50)": "輸入步數(例如 50)",
 	"Enter Number of Steps (e.g. 50)": "輸入步數(例如 50)",
 	"Enter Score": "輸入分數",
 	"Enter Score": "輸入分數",
 	"Enter Searxng Query URL": "輸入 Searxng 查詢 URL",
 	"Enter Searxng Query URL": "輸入 Searxng 查詢 URL",
-	"Enter Serper API Key": "輸入 Serper API Key",
-	"Enter Serply API Key": "",
-	"Enter Serpstack API Key": "輸入 Serpstack API Key",
+	"Enter Serper API Key": "輸入 Serper API 金鑰",
+	"Enter Serply API Key": "輸入 Serply API 金鑰",
+	"Enter Serpstack API Key": "輸入 Serpstack API 金鑰",
 	"Enter stop sequence": "輸入停止序列",
 	"Enter stop sequence": "輸入停止序列",
-	"Enter Tavily API Key": "",
+	"Enter Tavily API Key": "輸入 Tavily API 金鑰",
 	"Enter Top K": "輸入 Top K",
 	"Enter Top K": "輸入 Top K",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "輸入 URL(例如 http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://127.0.0.1:7860/)": "輸入 URL(例如 http://127.0.0.1:7860/)",
 	"Enter URL (e.g. http://localhost:11434)": "輸入 URL(例如 http://localhost:11434)",
 	"Enter URL (e.g. http://localhost:11434)": "輸入 URL(例如 http://localhost:11434)",
-	"Enter Your Email": "輸入的電子郵件",
-	"Enter Your Full Name": "輸入的全名",
-	"Enter Your Password": "輸入的密碼",
-	"Enter Your Role": "輸入的角色",
+	"Enter Your Email": "輸入的電子郵件",
+	"Enter Your Full Name": "輸入的全名",
+	"Enter Your Password": "輸入的密碼",
+	"Enter Your Role": "輸入的角色",
 	"Error": "錯誤",
 	"Error": "錯誤",
-	"Experimental": "實驗功能",
-	"Export": "出",
+	"Experimental": "實驗功能",
+	"Export": "出",
 	"Export All Chats (All Users)": "匯出所有聊天紀錄(所有使用者)",
 	"Export All Chats (All Users)": "匯出所有聊天紀錄(所有使用者)",
-	"Export chat (.json)": "",
+	"Export chat (.json)": "匯出聊天紀錄(.json)",
 	"Export Chats": "匯出聊天紀錄",
 	"Export Chats": "匯出聊天紀錄",
-	"Export Documents Mapping": "匯出文件映",
-	"Export Functions": "",
+	"Export Documents Mapping": "匯出文件映",
+	"Export Functions": "匯出功能",
 	"Export Models": "匯出模型",
 	"Export Models": "匯出模型",
 	"Export Prompts": "匯出提示詞",
 	"Export Prompts": "匯出提示詞",
-	"Export Tools": "",
-	"External Models": "",
-	"Failed to create API Key.": "無法建 API 金鑰。",
+	"Export Tools": "匯出工具",
+	"External Models": "外部模型",
+	"Failed to create API Key.": "無法建 API 金鑰。",
 	"Failed to read clipboard contents": "無法讀取剪貼簿內容",
 	"Failed to read clipboard contents": "無法讀取剪貼簿內容",
-	"Failed to update settings": "",
-	"February": "2月",
-	"Feel free to add specific details": "請自由添加詳細內容。",
-	"File": "",
+	"Failed to update settings": "無法更新設定",
+	"February": "2 月",
+	"Feel free to add specific details": "請隨意新增詳細內容。",
+	"File": "檔案",
 	"File Mode": "檔案模式",
 	"File Mode": "檔案模式",
 	"File not found.": "找不到檔案。",
 	"File not found.": "找不到檔案。",
-	"Filters": "",
-	"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "偽裝偽裝檢測:無法使用頭像作為頭像。預設為預設頭像。",
-	"Fluidly stream large external response chunks": "流暢地傳輸大型外部應區塊",
+	"Filters": "篩選器",
+	"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "偽造偵測:無法使用初始頭像。預設為預設個人影象。",
+	"Fluidly stream large external response chunks": "流暢地傳輸大型外部應區塊",
 	"Focus chat input": "聚焦聊天輸入框",
 	"Focus chat input": "聚焦聊天輸入框",
 	"Followed instructions perfectly": "完全遵循指示",
 	"Followed instructions perfectly": "完全遵循指示",
-	"Form": "",
-	"Format your variables using square brackets like this:": "像這樣使用方括號來格式化的變數:",
+	"Form": "表單",
+	"Format your variables using square brackets like this:": "像這樣使用方括號來格式化的變數:",
 	"Frequency Penalty": "頻率懲罰",
 	"Frequency Penalty": "頻率懲罰",
-	"Functions": "",
+	"Functions": "功能",
 	"General": "常用",
 	"General": "常用",
 	"General Settings": "常用設定",
 	"General Settings": "常用設定",
-	"Generate Image": "",
-	"Generating search query": "生成搜查詢",
-	"Generation Info": "生成信息",
+	"Generate Image": "生成圖片",
+	"Generating search query": "生成搜查詢",
+	"Generation Info": "生成資訊",
 	"Good Response": "優秀的回應",
 	"Good Response": "優秀的回應",
-	"Google PSE API Key": "Google PSE API Key",
-	"Google PSE Engine Id": "Google PSE Engine Id",
+	"Google PSE API Key": "Google PSE API 金鑰",
+	"Google PSE Engine Id": "Google PSE 引擎 ID",
 	"h:mm a": "h:mm a",
 	"h:mm a": "h:mm a",
 	"has no conversations.": "沒有對話",
 	"has no conversations.": "沒有對話",
-	"Hello, {{name}}": "好,{{name}}",
+	"Hello, {{name}}": "好,{{name}}",
 	"Help": "幫助",
 	"Help": "幫助",
 	"Hide": "隱藏",
 	"Hide": "隱藏",
-	"Hide Model": "",
-	"How can I help you today?": "今天能為你做什麼?",
-	"Hybrid Search": "混合搜",
-	"Image Generation (Experimental)": "圖像生成(實驗功能)",
-	"Image Generation Engine": "像生成引擎",
+	"Hide Model": "隱藏模型",
+	"How can I help you today?": "今天能為您做些什麼?",
+	"Hybrid Search": "混合搜",
+	"Image Generation (Experimental)": "影像生成(實驗性功能)",
+	"Image Generation Engine": "像生成引擎",
 	"Image Settings": "圖片設定",
 	"Image Settings": "圖片設定",
 	"Images": "圖片",
 	"Images": "圖片",
 	"Import Chats": "匯入聊天紀錄",
 	"Import Chats": "匯入聊天紀錄",
-	"Import Documents Mapping": "匯入文件映",
-	"Import Functions": "",
+	"Import Documents Mapping": "匯入文件映",
+	"Import Functions": "匯入功能",
 	"Import Models": "匯入模型",
 	"Import Models": "匯入模型",
 	"Import Prompts": "匯入提示詞",
 	"Import Prompts": "匯入提示詞",
-	"Import Tools": "",
-	"Include `--api` flag when running stable-diffusion-webui": "在行 stable-diffusion-webui 時加上 `--api` 標誌",
+	"Import Tools": "匯入工具",
+	"Include `--api` flag when running stable-diffusion-webui": "在行 stable-diffusion-webui 時加上 `--api` 標誌",
 	"Info": "資訊",
 	"Info": "資訊",
 	"Input commands": "輸入命令",
 	"Input commands": "輸入命令",
 	"Install from Github URL": "從 Github URL 安裝",
 	"Install from Github URL": "從 Github URL 安裝",
-	"Instant Auto-Send After Voice Transcription": "",
+	"Instant Auto-Send After Voice Transcription": "語音轉錄後立即自動傳送",
 	"Interface": "介面",
 	"Interface": "介面",
 	"Invalid Tag": "無效標籤",
 	"Invalid Tag": "無效標籤",
-	"January": "1月",
-	"join our Discord for help.": "加入我們的 Discord 尋幫助。",
+	"January": "1 月",
+	"join our Discord for help.": "加入我們的 Discord 尋幫助。",
 	"JSON": "JSON",
 	"JSON": "JSON",
 	"JSON Preview": "JSON 預覽",
 	"JSON Preview": "JSON 預覽",
-	"July": "7月",
-	"June": "6月",
+	"July": "7 月",
+	"June": "6 月",
 	"JWT Expiration": "JWT 過期時間",
 	"JWT Expiration": "JWT 過期時間",
 	"JWT Token": "JWT Token",
 	"JWT Token": "JWT Token",
 	"Keep Alive": "保持活躍",
 	"Keep Alive": "保持活躍",
 	"Keyboard shortcuts": "鍵盤快速鍵",
 	"Keyboard shortcuts": "鍵盤快速鍵",
-	"Knowledge": "",
+	"Knowledge": "知識",
 	"Language": "語言",
 	"Language": "語言",
 	"Last Active": "最後活動",
 	"Last Active": "最後活動",
-	"Last Modified": "",
+	"Last Modified": "最後修改",
 	"Light": "亮色",
 	"Light": "亮色",
-	"Listening...": "",
+	"Listening...": "正在聆聽...",
 	"LLMs can make mistakes. Verify important information.": "LLM 可能會產生錯誤。請驗證重要資訊。",
 	"LLMs can make mistakes. Verify important information.": "LLM 可能會產生錯誤。請驗證重要資訊。",
-	"Local Models": "",
+	"Local Models": "本機模型",
 	"LTR": "LTR",
 	"LTR": "LTR",
-	"Made by OpenWebUI Community": "由 OpenWebUI 社製作",
+	"Made by OpenWebUI Community": "由 OpenWebUI 社製作",
 	"Make sure to enclose them with": "請確保變數有被以下符號框住:",
 	"Make sure to enclose them with": "請確保變數有被以下符號框住:",
-	"Manage": "",
-	"Manage Models": "管理模",
+	"Manage": "管理",
+	"Manage Models": "管理模",
 	"Manage Ollama Models": "管理 Ollama 模型",
 	"Manage Ollama Models": "管理 Ollama 模型",
-	"Manage Pipelines": "管理管道",
-	"March": "3月",
+	"Manage Pipelines": "管理管線",
+	"Manage Valves": "",
+	"March": "3 月",
 	"Max Tokens (num_predict)": "最大 Token(num_predict)",
 	"Max Tokens (num_predict)": "最大 Token(num_predict)",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同時下載 3 個模型。請稍後再試。",
 	"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同時下載 3 個模型。請稍後再試。",
-	"May": "5月",
+	"May": "5 月",
 	"Memories accessible by LLMs will be shown here.": "LLM 記憶將會顯示在此處。",
 	"Memories accessible by LLMs will be shown here.": "LLM 記憶將會顯示在此處。",
 	"Memory": "記憶",
 	"Memory": "記憶",
-	"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "創建連結後發送的訊息將不會被共享。具有 URL 的用戶將會能夠檢視共享的聊天。",
-	"Minimum Score": "最分數",
+	"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "建立連結後傳送的訊息將不會被共享。具有 URL 的使用者將會能夠檢視共享的聊天。",
+	"Minimum Score": "最分數",
 	"Mirostat": "Mirostat",
 	"Mirostat": "Mirostat",
 	"Mirostat Eta": "Mirostat Eta",
 	"Mirostat Eta": "Mirostat Eta",
 	"Mirostat Tau": "Mirostat Tau",
 	"Mirostat Tau": "Mirostat Tau",
 	"MMMM DD, YYYY": "MMMM DD, YYYY",
 	"MMMM DD, YYYY": "MMMM DD, YYYY",
 	"MMMM DD, YYYY HH:mm": "MMMM DD, YYYY HH:mm",
 	"MMMM DD, YYYY HH:mm": "MMMM DD, YYYY HH:mm",
-	"MMMM DD, YYYY hh:mm:ss A": "",
+	"MMMM DD, YYYY hh:mm:ss A": "MMMM DD, YYYY hh:mm:ss A",
 	"Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' 模型已成功下載。",
 	"Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' 模型已成功下載。",
 	"Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' 模型已經在下載佇列中。",
 	"Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' 模型已經在下載佇列中。",
 	"Model {{modelId}} not found": "找不到 {{modelId}} 模型",
 	"Model {{modelId}} not found": "找不到 {{modelId}} 模型",
 	"Model {{modelName}} is not vision capable": "{{modelName}} 模型不適用於視覺",
 	"Model {{modelName}} is not vision capable": "{{modelName}} 模型不適用於視覺",
 	"Model {{name}} is now {{status}}": "{{name}} 模型現在是 {{status}}",
 	"Model {{name}} is now {{status}}": "{{name}} 模型現在是 {{status}}",
-	"Model filesystem path detected. Model shortname is required for update, cannot continue.": "模型文件系統路徑已檢測。需要更新模型短名,無法繼續。",
+	"Model filesystem path detected. Model shortname is required for update, cannot continue.": "已偵測到模型檔案系統路徑。需要更新模型簡稱,無法繼續。",
 	"Model ID": "模型 ID",
 	"Model ID": "模型 ID",
 	"Model not selected": "未選擇模型",
 	"Model not selected": "未選擇模型",
 	"Model Params": "模型參數",
 	"Model Params": "模型參數",
@@ -345,33 +352,33 @@
 	"Name your model": "請輸入模型名稱",
 	"Name your model": "請輸入模型名稱",
 	"New Chat": "新增聊天",
 	"New Chat": "新增聊天",
 	"New Password": "新密碼",
 	"New Password": "新密碼",
-	"No documents found": "",
+	"No documents found": "找不到文件",
 	"No results found": "沒有找到結果",
 	"No results found": "沒有找到結果",
-	"No search query generated": "沒有生成搜查詢",
+	"No search query generated": "沒有生成搜查詢",
 	"No source available": "沒有可用的來源",
 	"No source available": "沒有可用的來源",
 	"None": "無",
 	"None": "無",
-	"Not factually correct": "與真實資訊不符",
-	"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "註:如果設置最低分數,則搜索將只返回分數大於或等於最低分數的文檔。",
-	"Notifications": "桌面通知",
-	"November": "11月",
-	"num_thread (Ollama)": "num_thread(奧拉馬)",
+	"Not factually correct": "與真實資訊不符",
+	"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "註:如果設定最低分數,則搜尋將只返回分數大於或等於最低分數的文件。",
+	"Notifications": "通知",
+	"November": "11 月",
+	"num_thread (Ollama)": "num_thread(Ollama)",
 	"OAuth ID": "",
 	"OAuth ID": "",
 	"October": "10 月",
 	"October": "10 月",
 	"Off": "關閉",
 	"Off": "關閉",
 	"Okay, Let's Go!": "好的,啟動吧!",
 	"Okay, Let's Go!": "好的,啟動吧!",
-	"OLED Dark": "`",
+	"OLED Dark": "OLED 深色",
 	"Ollama": "Ollama",
 	"Ollama": "Ollama",
 	"Ollama API": "Ollama API",
 	"Ollama API": "Ollama API",
-	"Ollama API disabled": "Ollama API 已用",
-	"Ollama API is disabled": "",
+	"Ollama API disabled": "Ollama API 已用",
+	"Ollama API is disabled": "Ollama API 已停用",
 	"Ollama Version": "Ollama 版本",
 	"Ollama Version": "Ollama 版本",
 	"On": "開啟",
 	"On": "開啟",
 	"Only": "僅有",
 	"Only": "僅有",
-	"Only alphanumeric characters and hyphens are allowed in the command string.": "命令字串中只能包含英文字母、數字(0~9)和連字(-)。",
-	"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "哎呀!請稍等!的文件還在處理中。我們正最佳化文件,請耐心等待,一旦準備好,我們會通知。",
+	"Only alphanumeric characters and hyphens are allowed in the command string.": "命令字串中只能包含英文字母、數字(0~9)和連字(-)。",
+	"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "哎呀!請稍等!的文件還在處理中。我們正最佳化文件,請耐心等待,一旦準備好,我們會通知。",
 	"Oops! Looks like the URL is invalid. Please double-check and try again.": "哎呀!看起來 URL 無效。請仔細檢查後再試一次。",
 	"Oops! Looks like the URL is invalid. Please double-check and try again.": "哎呀!看起來 URL 無效。請仔細檢查後再試一次。",
-	"Oops! There was an error in the previous response. Please try again or contact admin.": "",
-	"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "哎呀!你正在使用不支援的方法(僅有前台)。請從後台提供 WebUI。",
+	"Oops! There was an error in the previous response. Please try again or contact admin.": "哎呀!先前的回應發生錯誤。請重試或聯絡管理員",
+	"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "哎呀!您正在使用不支援的方法(僅有前端)。請從後端提供 WebUI。",
 	"Open": "開啟",
 	"Open": "開啟",
 	"Open AI": "Open AI",
 	"Open AI": "Open AI",
 	"Open AI (Dall-E)": "Open AI (Dall-E)",
 	"Open AI (Dall-E)": "Open AI (Dall-E)",
@@ -385,22 +392,22 @@
 	"Other": "其他",
 	"Other": "其他",
 	"Password": "密碼",
 	"Password": "密碼",
 	"PDF document (.pdf)": "PDF 文件 (.pdf)",
 	"PDF document (.pdf)": "PDF 文件 (.pdf)",
-	"PDF Extract Images (OCR)": "PDF 像擷取(OCR 光學文字辨識)",
+	"PDF Extract Images (OCR)": "PDF 像擷取(OCR 光學文字辨識)",
 	"pending": "待審查",
 	"pending": "待審查",
-	"Permission denied when accessing media devices": "",
-	"Permission denied when accessing microphone": "",
+	"Permission denied when accessing media devices": "存取媒體裝置時被拒絕權限",
+	"Permission denied when accessing microphone": "存取麥克風時被拒絕權限",
 	"Permission denied when accessing microphone: {{error}}": "存取麥克風時被拒絕權限:{{error}}",
 	"Permission denied when accessing microphone: {{error}}": "存取麥克風時被拒絕權限:{{error}}",
 	"Personalization": "個人化",
 	"Personalization": "個人化",
 	"Pipelines": "管線",
 	"Pipelines": "管線",
-	"Pipelines Valves": "管線阀门",
+	"Pipelines Valves": "管線閥門",
 	"Plain text (.txt)": "純文字 (.txt)",
 	"Plain text (.txt)": "純文字 (.txt)",
 	"Playground": "AI 對話遊樂場",
 	"Playground": "AI 對話遊樂場",
 	"Positive attitude": "積極態度",
 	"Positive attitude": "積極態度",
 	"Previous 30 days": "前 30 天",
 	"Previous 30 days": "前 30 天",
 	"Previous 7 days": "前 7 天",
 	"Previous 7 days": "前 7 天",
-	"Profile Image": "個人像",
+	"Profile Image": "個人像",
 	"Prompt": "提示詞",
 	"Prompt": "提示詞",
-	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "提示詞(例如:告訴我關於羅馬帝國的趣事)",
+	"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "提示詞(例如:告訴我關於羅馬帝國的一些趣事)",
 	"Prompt Content": "提示詞內容",
 	"Prompt Content": "提示詞內容",
 	"Prompt suggestions": "提示詞建議",
 	"Prompt suggestions": "提示詞建議",
 	"Prompts": "提示詞",
 	"Prompts": "提示詞",
@@ -410,32 +417,32 @@
 	"RAG Template": "RAG 範例",
 	"RAG Template": "RAG 範例",
 	"Read Aloud": "讀出",
 	"Read Aloud": "讀出",
 	"Record voice": "錄音",
 	"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": "拒絕時不該拒絕",
+	"Redirecting you to OpenWebUI Community": "將重新導向到 OpenWebUI 社群",
+	"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "將自己稱為「使用者」(例如,「使用者正在學習西班牙語」)",
+	"Refused when it shouldn't have": "不該拒絕時拒絕了",
 	"Regenerate": "重新生成",
 	"Regenerate": "重新生成",
 	"Release Notes": "發布說明",
 	"Release Notes": "發布說明",
 	"Remove": "移除",
 	"Remove": "移除",
 	"Remove Model": "移除模型",
 	"Remove Model": "移除模型",
-	"Rename": "重命名",
+	"Rename": "重命名",
 	"Repeat Last N": "重複最後 N 次",
 	"Repeat Last N": "重複最後 N 次",
 	"Request Mode": "請求模式",
 	"Request Mode": "請求模式",
 	"Reranking Model": "重新排序模型",
 	"Reranking Model": "重新排序模型",
-	"Reranking model disabled": "重新排序模型已用",
+	"Reranking model disabled": "重新排序模型已用",
 	"Reranking model set to \"{{reranking_model}}\"": "重新排序模型設定為 \"{{reranking_model}}\"",
 	"Reranking model set to \"{{reranking_model}}\"": "重新排序模型設定為 \"{{reranking_model}}\"",
-	"Reset": "",
-	"Reset Upload Directory": "",
-	"Reset Vector Storage": "重向量儲存空間",
+	"Reset": "重設",
+	"Reset Upload Directory": "重設上傳目錄",
+	"Reset Vector Storage": "重向量儲存空間",
 	"Response AutoCopy to Clipboard": "自動複製回答到剪貼簿",
 	"Response AutoCopy to Clipboard": "自動複製回答到剪貼簿",
-	"Role": "Role",
+	"Role": "角色",
 	"Rosé Pine": "玫瑰松",
 	"Rosé Pine": "玫瑰松",
 	"Rosé Pine Dawn": "黎明玫瑰松",
 	"Rosé Pine Dawn": "黎明玫瑰松",
 	"RTL": "RTL",
 	"RTL": "RTL",
-	"Running": "",
+	"Running": "運作中",
 	"Save": "儲存",
 	"Save": "儲存",
 	"Save & Create": "儲存並建立",
 	"Save & Create": "儲存並建立",
 	"Save & Update": "儲存並更新",
 	"Save & Update": "儲存並更新",
-	"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "現已不支援將聊天紀錄儲存到瀏覽器儲存空間中。請點擊下面的按鈕下載並刪除你的聊天記錄。別擔心,你可以通過以下方式輕鬆地重新匯入你的聊天記錄到後台",
+	"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "現已不支援將聊天紀錄儲存到瀏覽器儲存空間中。請點選下面的按鈕下載並刪除您的聊天記錄。別擔心,您可以透過以下方式輕鬆地重新匯入您的聊天記錄到後端",
 	"Scan": "掃描",
 	"Scan": "掃描",
 	"Scan complete!": "掃描完成!",
 	"Scan complete!": "掃描完成!",
 	"Scan for documents from {{path}}": "從 {{path}} 掃描文件",
 	"Scan for documents from {{path}}": "從 {{path}} 掃描文件",
@@ -443,37 +450,39 @@
 	"Search a model": "搜尋模型",
 	"Search a model": "搜尋模型",
 	"Search Chats": "搜尋聊天",
 	"Search Chats": "搜尋聊天",
 	"Search Documents": "搜尋文件",
 	"Search Documents": "搜尋文件",
-	"Search Functions": "",
+	"Search Functions": "搜尋功能",
 	"Search Models": "搜尋模型",
 	"Search Models": "搜尋模型",
 	"Search Prompts": "搜尋提示詞",
 	"Search Prompts": "搜尋提示詞",
-	"Search Query Generation Prompt": "",
-	"Search Query Generation Prompt Length Threshold": "",
+	"Search Query Generation Prompt": "搜尋查詢生成提示詞",
+	"Search Query Generation Prompt Length Threshold": "搜尋查詢生成提示詞長度閾值",
 	"Search Result Count": "搜尋結果數量",
 	"Search Result Count": "搜尋結果數量",
-	"Search Tools": "",
-	"Searched {{count}} sites_other": "掃描 {{count}} 個網站_其他",
-	"Searching \"{{searchQuery}}\"": "",
+	"Search Tools": "搜尋工具",
+	"Searched {{count}} sites_other": "搜尋了 {{count}} 個網站",
+	"Searching \"{{searchQuery}}\"": "正在搜尋 \"{{searchQuery}}\"",
 	"Searxng Query URL": "Searxng 查詢 URL",
 	"Searxng Query URL": "Searxng 查詢 URL",
-	"See readme.md for instructions": "查看 readme.md 獲取指南",
-	"See what's new": "查看最新內容",
+	"See readme.md for instructions": "檢視 readme.md 取得指南",
+	"See what's new": "檢視最新內容",
 	"Seed": "種子",
 	"Seed": "種子",
 	"Select a base model": "選擇基礎模型",
 	"Select a base model": "選擇基礎模型",
-	"Select a engine": "",
+	"Select a engine": "選擇引擎",
+	"Select a function": "",
 	"Select a mode": "選擇模式",
 	"Select a mode": "選擇模式",
 	"Select a model": "選擇一個模型",
 	"Select a model": "選擇一個模型",
-	"Select a pipeline": "選擇管道",
-	"Select a pipeline url": "選擇管道 URL",
-	"Select an Ollama instance": "選擇 Ollama 實例",
-	"Select Documents": "",
+	"Select a pipeline": "選擇管線",
+	"Select a pipeline url": "選擇管線 URL",
+	"Select a tool": "",
+	"Select an Ollama instance": "選擇 Ollama 執行個體",
+	"Select Documents": "選擇文件",
 	"Select model": "選擇模型",
 	"Select model": "選擇模型",
-	"Select only one model to call": "",
-	"Selected model(s) do not support image inputs": "已選擇模型不支持圖像輸入",
+	"Select only one model to call": "僅選擇一個模型來呼叫",
+	"Selected model(s) do not support image inputs": "已選擇模型不支援影像輸入",
 	"Send": "傳送",
 	"Send": "傳送",
 	"Send a Message": "傳送訊息",
 	"Send a Message": "傳送訊息",
 	"Send message": "傳送訊息",
 	"Send message": "傳送訊息",
-	"September": "月",
-	"Serper API Key": "Serper API Key",
-	"Serply API Key": "",
-	"Serpstack API Key": "Serpstack API Key",
+	"September": "9 月",
+	"Serper API Key": "Serper API 金鑰",
+	"Serply API Key": "Serply API 金鑰",
+	"Serpstack API Key": "Serpstack API 金鑰",
 	"Server connection verified": "已驗證伺服器連線",
 	"Server connection verified": "已驗證伺服器連線",
 	"Set as default": "設為預設",
 	"Set as default": "設為預設",
 	"Set Default Model": "設定預設模型",
 	"Set Default Model": "設定預設模型",
@@ -485,15 +494,16 @@
 	"Set Voice": "設定語音",
 	"Set Voice": "設定語音",
 	"Settings": "設定",
 	"Settings": "設定",
 	"Settings saved successfully!": "成功儲存設定",
 	"Settings saved successfully!": "成功儲存設定",
-	"Settings updated successfully": "",
+	"Settings updated successfully": "設定更新成功",
 	"Share": "分享",
 	"Share": "分享",
 	"Share Chat": "分享聊天",
 	"Share Chat": "分享聊天",
 	"Share to OpenWebUI Community": "分享到 OpenWebUI 社群",
 	"Share to OpenWebUI Community": "分享到 OpenWebUI 社群",
 	"short-summary": "簡短摘要",
 	"short-summary": "簡短摘要",
 	"Show": "顯示",
 	"Show": "顯示",
-	"Show Admin Details in Account Pending Overlay": "",
-	"Show Model": "",
+	"Show Admin Details in Account Pending Overlay": "在帳號待審覆蓋層中顯示管理員詳細資訊",
+	"Show Model": "顯示模型",
 	"Show shortcuts": "顯示快速鍵",
 	"Show shortcuts": "顯示快速鍵",
+	"Show your support!": "",
 	"Showcased creativity": "展示創造性",
 	"Showcased creativity": "展示創造性",
 	"sidebar": "側邊欄",
 	"sidebar": "側邊欄",
 	"Sign in": "登入",
 	"Sign in": "登入",
@@ -504,115 +514,116 @@
 	"Speech recognition error: {{error}}": "語音識別錯誤:{{error}}",
 	"Speech recognition error: {{error}}": "語音識別錯誤:{{error}}",
 	"Speech-to-Text Engine": "語音轉文字引擎",
 	"Speech-to-Text Engine": "語音轉文字引擎",
 	"Stop Sequence": "停止序列",
 	"Stop Sequence": "停止序列",
-	"STT Model": "",
+	"STT Model": "STT 模型",
 	"STT Settings": "語音轉文字設定",
 	"STT Settings": "語音轉文字設定",
 	"Submit": "提交",
 	"Submit": "提交",
-	"Subtitle (e.g. about the Roman Empire)": "標題(例如:關於羅馬帝國)",
+	"Subtitle (e.g. about the Roman Empire)": "標題(例如:關於羅馬帝國)",
 	"Success": "成功",
 	"Success": "成功",
 	"Successfully updated.": "更新成功。",
 	"Successfully updated.": "更新成功。",
 	"Suggested": "建議",
 	"Suggested": "建議",
 	"System": "系統",
 	"System": "系統",
 	"System Prompt": "系統提示詞",
 	"System Prompt": "系統提示詞",
 	"Tags": "標籤",
 	"Tags": "標籤",
-	"Tap to interrupt": "",
-	"Tavily API Key": "",
+	"Tap to interrupt": "點選以中斷",
+	"Tavily API Key": "Tavily API 金鑰",
 	"Tell us more:": "告訴我們更多:",
 	"Tell us more:": "告訴我們更多:",
 	"Temperature": "溫度",
 	"Temperature": "溫度",
-	"Template": "模板",
-	"Text Completion": "文本補全(Text Completion)",
+	"Template": "範本",
+	"Text Completion": "文字補全",
 	"Text-to-Speech Engine": "文字轉語音引擎",
 	"Text-to-Speech Engine": "文字轉語音引擎",
 	"Tfs Z": "Tfs Z",
 	"Tfs Z": "Tfs Z",
-	"Thanks for your feedback!": "感謝的回饋!",
+	"Thanks for your feedback!": "感謝的回饋!",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分數應該介於 0.0(0%)和 1.0(100%)之間。",
 	"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分數應該介於 0.0(0%)和 1.0(100%)之間。",
 	"Theme": "主題",
 	"Theme": "主題",
-	"Thinking...": "",
-	"This action cannot be undone. Do you wish to continue?": "",
-	"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.": "",
+	"Thinking...": "正在思考...",
+	"This action cannot be undone. Do you wish to continue?": "此動作無法被復原。您想要繼續進行嗎?",
+	"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.": "此設定不會在瀏覽器或裝置間同步。",
 	"This setting does not sync across browsers or devices.": "此設定不會在瀏覽器或裝置間同步。",
 	"This will delete": "",
 	"This will delete": "",
 	"Thorough explanation": "詳細說明",
 	"Thorough explanation": "詳細說明",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "提示:透過在每次替換後在聊天輸入框中按 Tab 鍵連續更新多個變數。",
 	"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "提示:透過在每次替換後在聊天輸入框中按 Tab 鍵連續更新多個變數。",
 	"Title": "標題",
 	"Title": "標題",
 	"Title (e.g. Tell me a fun fact)": "標題(例如:告訴我一個有趣的事)",
 	"Title (e.g. Tell me a fun fact)": "標題(例如:告訴我一個有趣的事)",
-	"Title Auto-Generation": "自動生標題",
+	"Title Auto-Generation": "自動生標題",
 	"Title cannot be an empty string.": "標題不能為空字串",
 	"Title cannot be an empty string.": "標題不能為空字串",
-	"Title Generation Prompt": "自動生標題的提示詞",
+	"Title Generation Prompt": "自動生標題的提示詞",
 	"to": "到",
 	"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 add documents here, upload them to the \"Documents\" workspace first.": "",
+	"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.": "若要存取 WebUI,請聯絡管理員。管理員可以從管理面板管理使用者狀態。",
+	"To add documents here, upload them to the \"Documents\" workspace first.": "若要在此新增文件,請先將它們上傳到「文件」工作區。",
 	"to chat input.": "到聊天輸入框來啟動此命令。",
 	"to chat input.": "到聊天輸入框來啟動此命令。",
-	"To select filters here, add them to the \"Functions\" workspace first.": "",
-	"To select toolkits here, add them to the \"Tools\" workspace first.": "",
+	"To select filters here, add them to the \"Functions\" workspace first.": "若要在此選擇篩選器,請先將它們新增到「功能」工作區。",
+	"To select toolkits here, add them to the \"Tools\" workspace first.": "若要在此選擇工具包,請先將它們新增到「工具」工作區。",
 	"Today": "今天",
 	"Today": "今天",
 	"Toggle settings": "切換設定",
 	"Toggle settings": "切換設定",
 	"Toggle sidebar": "切換側邊欄",
 	"Toggle sidebar": "切換側邊欄",
-	"Tokens To Keep On Context Refresh (num_keep)": "",
-	"Tools": "",
+	"Tokens To Keep On Context Refresh (num_keep)": "上下文重新整理時保留的 Token 數量(num_keep)",
+	"Tools": "工具",
 	"Top K": "Top K",
 	"Top K": "Top K",
 	"Top P": "Top P",
 	"Top P": "Top P",
 	"Trouble accessing Ollama?": "存取 Ollama 時遇到問題?",
 	"Trouble accessing Ollama?": "存取 Ollama 時遇到問題?",
-	"TTS Model": "",
-	"TTS Settings": "文字轉語音設定",
-	"TTS Voice": "",
+	"TTS Model": "文字轉語音(TTS)模型",
+	"TTS Settings": "文字轉語音(TTS)設定",
+	"TTS Voice": "文字轉語音(TTS)聲調",
 	"Type": "類型",
 	"Type": "類型",
 	"Type Hugging Face Resolve (Download) URL": "輸入 Hugging Face 解析後的(下載)URL",
 	"Type Hugging Face Resolve (Download) URL": "輸入 Hugging Face 解析後的(下載)URL",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "哎呀!連線到 {{provider}} 時出現問題。",
 	"Uh-oh! There was an issue connecting to {{provider}}.": "哎呀!連線到 {{provider}} 時出現問題。",
-	"UI": "",
-	"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "",
-	"Update": "",
+	"UI": "使用者界面",
+	"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "未知的檔案類型 '{{file_type}}'。但仍會繼續上傳。",
+	"Update": "更新",
 	"Update and Copy Link": "更新並複製連結",
 	"Update and Copy Link": "更新並複製連結",
 	"Update password": "更新密碼",
 	"Update password": "更新密碼",
-	"Updated at": "",
-	"Upload": "",
+	"Updated at": "更新於",
+	"Upload": "上傳",
 	"Upload a GGUF model": "上傳一個 GGUF 模型",
 	"Upload a GGUF model": "上傳一個 GGUF 模型",
-	"Upload Files": "上傳文件",
-	"Upload Pipeline": "",
+	"Upload Files": "上傳檔案",
+	"Upload Pipeline": "上傳管線",
 	"Upload Progress": "上傳進度",
 	"Upload Progress": "上傳進度",
 	"URL Mode": "URL 模式",
 	"URL Mode": "URL 模式",
-	"Use '#' in the prompt input to load and select your documents.": "在輸入框中輸入 '#' 以載入並選擇的文件。",
+	"Use '#' in the prompt input to load and select your documents.": "在輸入框中輸入 '#' 以載入並選擇的文件。",
 	"Use Gravatar": "使用 Gravatar",
 	"Use Gravatar": "使用 Gravatar",
-	"Use Initials": "使用初始像",
-	"use_mlock (Ollama)": "use_mlock(奧拉馬)",
-	"use_mmap (Ollama)": "use_mmap (Ollama)",
+	"Use Initials": "使用初始像",
+	"use_mlock (Ollama)": "use_mlock(Ollama)",
+	"use_mmap (Ollama)": "use_mmap(Ollama)",
 	"user": "使用者",
 	"user": "使用者",
 	"User Permissions": "使用者權限",
 	"User Permissions": "使用者權限",
 	"Users": "使用者",
 	"Users": "使用者",
 	"Utilize": "使用",
 	"Utilize": "使用",
 	"Valid time units:": "有效時間單位:",
 	"Valid time units:": "有效時間單位:",
+	"Valves": "",
 	"variable": "變數",
 	"variable": "變數",
 	"variable to have them replaced with clipboard content.": "變數將替換為剪貼簿內容",
 	"variable to have them replaced with clipboard content.": "變數將替換為剪貼簿內容",
 	"Version": "版本",
 	"Version": "版本",
 	"Voice": "",
 	"Voice": "",
 	"Warning": "警告",
 	"Warning": "警告",
-	"Warning: If you update or change your embedding model, you will need to re-import all documents.": "警告:如果更新或更改你的嵌入模型,則需要重新導入所有文件",
+	"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": "Web 搜尋",
-	"Web Search Engine": "Web 搜尋引擎",
+	"Web API": "網頁 API",
+	"Web Loader Settings": "網頁載入器設定",
+	"Web Params": "網頁參數",
+	"Web Search": "網頁搜尋",
+	"Web Search Engine": "網頁搜尋引擎",
 	"Webhook URL": "Webhook URL",
 	"Webhook URL": "Webhook URL",
 	"WebUI Settings": "WebUI 設定",
 	"WebUI Settings": "WebUI 設定",
 	"WebUI will make requests to": "WebUI 將會存取",
 	"WebUI will make requests to": "WebUI 將會存取",
 	"What’s New in": "全新內容",
 	"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.": "當歷史被關閉時,這個瀏覽器上的新聊天將不會出現在任何裝置的歷史記錄中",
 	"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "當歷史被關閉時,這個瀏覽器上的新聊天將不會出現在任何裝置的歷史記錄中",
-	"Whisper (Local)": "",
-	"Widescreen Mode": "",
+	"Whisper (Local)": "Whisper(本地)",
+	"Widescreen Mode": "寬螢幕模式",
 	"Workspace": "工作區",
 	"Workspace": "工作區",
-	"Write a prompt suggestion (e.g. Who are you?)": "寫一個提示詞建議(例如:是誰?)",
+	"Write a prompt suggestion (e.g. Who are you?)": "寫一個提示詞建議(例如:是誰?)",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "寫一個 50 字的摘要來概括 [主題或關鍵詞]。",
 	"Write a summary in 50 words that summarizes [topic or keyword].": "寫一個 50 字的摘要來概括 [主題或關鍵詞]。",
 	"Yesterday": "昨天",
 	"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": "",
+	"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "您可以透過下方的「管理」按鈕新增記憶,個人化您的 LLM 互動,使其更有幫助並更符合您的需求。",
+	"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.": "已登入。",
 	"You're now logged in.": "已登入。",
-	"Your account status is currently pending activation.": "",
+	"Your account status is currently pending activation.": "您的帳號狀態目前待啟用。",
 	"Youtube": "Youtube",
 	"Youtube": "Youtube",
 	"Youtube Loader Settings": "Youtube 載入器設定"
 	"Youtube Loader Settings": "Youtube 載入器設定"
 }
 }

+ 27 - 4
src/lib/utils/index.ts

@@ -506,13 +506,36 @@ export const removeEmojis = (str) => {
 	return str.replace(emojiRegex, '');
 	return str.replace(emojiRegex, '');
 };
 };
 
 
+export const removeFormattings = (str) => {
+	return str.replace(/(\*)(.*?)\1/g, '').replace(/(```)(.*?)\1/gs, '');
+};
+
 export const extractSentences = (text) => {
 export const extractSentences = (text) => {
-	// Split the paragraph into sentences based on common punctuation marks
-	const sentences = text.split(/(?<=[.!?])\s+/);
+	// This regular expression matches code blocks marked by triple backticks
+	const codeBlockRegex = /```[\s\S]*?```/g;
+
+	let codeBlocks = [];
+	let index = 0;
+
+	// Temporarily replace code blocks with placeholders and store the blocks separately
+	text = text.replace(codeBlockRegex, (match) => {
+		let placeholder = `\u0000${index}\u0000`; // Use a unique placeholder
+		codeBlocks[index++] = match;
+		return placeholder;
+	});
+
+	// Split the modified text into sentences based on common punctuation marks, avoiding these blocks
+	let sentences = text.split(/(?<=[.!?])\s+/);
+
+	// Restore code blocks and process sentences
+	sentences = sentences.map((sentence) => {
+		// Check if the sentence includes a placeholder for a code block
+		return sentence.replace(/\u0000(\d+)\u0000/g, (_, idx) => codeBlocks[idx]);
+	});
 
 
 	return sentences
 	return sentences
-		.map((sentence) => removeEmojis(sentence.trim()))
-		.filter((sentence) => sentence !== '');
+		.map((sentence) => removeFormattings(removeEmojis(sentence.trim())))
+		.filter((sentence) => sentence);
 };
 };
 
 
 export const extractSentencesForAudio = (text) => {
 export const extractSentencesForAudio = (text) => {

+ 6 - 1
src/routes/(app)/+layout.svelte

@@ -29,13 +29,15 @@
 		showChangelog,
 		showChangelog,
 		config,
 		config,
 		showCallOverlay,
 		showCallOverlay,
-		tools
+		tools,
+		functions
 	} from '$lib/stores';
 	} from '$lib/stores';
 
 
 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
 	import Sidebar from '$lib/components/layout/Sidebar.svelte';
 	import Sidebar from '$lib/components/layout/Sidebar.svelte';
 	import ChangelogModal from '$lib/components/ChangelogModal.svelte';
 	import ChangelogModal from '$lib/components/ChangelogModal.svelte';
 	import AccountPending from '$lib/components/layout/Overlay/AccountPending.svelte';
 	import AccountPending from '$lib/components/layout/Overlay/AccountPending.svelte';
+	import { getFunctions } from '$lib/apis/functions';
 
 
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
@@ -93,6 +95,9 @@
 				(async () => {
 				(async () => {
 					tools.set(await getTools(localStorage.token));
 					tools.set(await getTools(localStorage.token));
 				})(),
 				})(),
+				(async () => {
+					functions.set(await getFunctions(localStorage.token));
+				})(),
 				(async () => {
 				(async () => {
 					banners.set(await getBanners(localStorage.token));
 					banners.set(await getBanners(localStorage.token));
 				})(),
 				})(),

+ 1 - 1
src/routes/(app)/playground/+page.svelte

@@ -1,7 +1,7 @@
 <script>
 <script>
 	import { showSidebar } from '$lib/stores';
 	import { showSidebar } from '$lib/stores';
 
 
-	import Playground from '$lib/components/workspace/Playground.svelte';
+	import Playground from '$lib/components/playground/Playground.svelte';
 </script>
 </script>
 
 
 <div
 <div

+ 1 - 1
src/routes/(app)/workspace/+layout.svelte

@@ -9,7 +9,7 @@
 	const i18n = getContext('i18n');
 	const i18n = getContext('i18n');
 
 
 	onMount(async () => {
 	onMount(async () => {
-		functions.set(await getFunctions(localStorage.token));
+		// functions.set(await getFunctions(localStorage.token));
 	});
 	});
 </script>
 </script>
 
 

+ 27 - 0
src/routes/+layout.svelte

@@ -37,6 +37,8 @@
 	let loaded = false;
 	let loaded = false;
 	const BREAKPOINT = 768;
 	const BREAKPOINT = 768;
 
 
+	let wakeLock = null;
+
 	onMount(async () => {
 	onMount(async () => {
 		theme.set(localStorage.theme);
 		theme.set(localStorage.theme);
 
 
@@ -51,6 +53,31 @@
 
 
 		window.addEventListener('resize', onResize);
 		window.addEventListener('resize', onResize);
 
 
+		const setWakeLock = async () => {
+			try {
+				wakeLock = await navigator.wakeLock.request('screen');
+			} catch (err) {
+				// The Wake Lock request has failed - usually system related, such as battery.
+				console.log(err);
+			}
+
+			wakeLock.addEventListener('release', () => {
+				// the wake lock has been released
+				console.log('Wake Lock released');
+			});
+		};
+
+		if ('wakeLock' in navigator) {
+			await setWakeLock();
+
+			document.addEventListener('visibilitychange', async () => {
+				// Re-request the wake lock if the document becomes visible
+				if (wakeLock !== null && document.visibilityState === 'visible') {
+					await setWakeLock();
+				}
+			});
+		}
+
 		let backendConfig = null;
 		let backendConfig = null;
 		try {
 		try {
 			backendConfig = await getBackendConfig();
 			backendConfig = await getBackendConfig();