Merge branch 'dev' into main

This commit is contained in:
Jarrod Lowe 2025-04-11 22:14:41 +12:00 committed by GitHub
commit a8bbaa61bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
96 changed files with 1848 additions and 905 deletions

View File

@ -73,8 +73,15 @@ def serve(
os.environ["LD_LIBRARY_PATH"] = ":".join(LD_LIBRARY_PATH) os.environ["LD_LIBRARY_PATH"] = ":".join(LD_LIBRARY_PATH)
import open_webui.main # we need set environment variables before importing main import open_webui.main # we need set environment variables before importing main
from open_webui.env import UVICORN_WORKERS # Import the workers setting
uvicorn.run(open_webui.main.app, host=host, port=port, forwarded_allow_ips="*") uvicorn.run(
open_webui.main.app,
host=host,
port=port,
forwarded_allow_ips="*",
workers=UVICORN_WORKERS
)
@app.command() @app.command()

View File

@ -201,6 +201,7 @@ def save_config(config):
T = TypeVar("T") T = TypeVar("T")
ENABLE_PERSISTENT_CONFIG = os.environ.get("ENABLE_PERSISTENT_CONFIG", "True").lower() == "true"
class PersistentConfig(Generic[T]): class PersistentConfig(Generic[T]):
def __init__(self, env_name: str, config_path: str, env_value: T): def __init__(self, env_name: str, config_path: str, env_value: T):
@ -208,7 +209,7 @@ class PersistentConfig(Generic[T]):
self.config_path = config_path self.config_path = config_path
self.env_value = env_value self.env_value = env_value
self.config_value = get_config_value(config_path) self.config_value = get_config_value(config_path)
if self.config_value is not None: if self.config_value is not None and ENABLE_PERSISTENT_CONFIG:
log.info(f"'{env_name}' loaded from the latest database entry") log.info(f"'{env_name}' loaded from the latest database entry")
self.value = self.config_value self.value = self.config_value
else: else:
@ -456,6 +457,12 @@ OAUTH_SCOPES = PersistentConfig(
os.environ.get("OAUTH_SCOPES", "openid email profile"), os.environ.get("OAUTH_SCOPES", "openid email profile"),
) )
OAUTH_CODE_CHALLENGE_METHOD = PersistentConfig(
"OAUTH_CODE_CHALLENGE_METHOD",
"oauth.oidc.code_challenge_method",
os.environ.get("OAUTH_CODE_CHALLENGE_METHOD", None),
)
OAUTH_PROVIDER_NAME = PersistentConfig( OAUTH_PROVIDER_NAME = PersistentConfig(
"OAUTH_PROVIDER_NAME", "OAUTH_PROVIDER_NAME",
"oauth.oidc.provider_name", "oauth.oidc.provider_name",
@ -560,7 +567,7 @@ def load_oauth_providers():
name="microsoft", name="microsoft",
client_id=MICROSOFT_CLIENT_ID.value, client_id=MICROSOFT_CLIENT_ID.value,
client_secret=MICROSOFT_CLIENT_SECRET.value, client_secret=MICROSOFT_CLIENT_SECRET.value,
server_metadata_url=f"https://login.microsoftonline.com/{MICROSOFT_CLIENT_TENANT_ID.value}/v2.0/.well-known/openid-configuration", server_metadata_url=f"https://login.microsoftonline.com/{MICROSOFT_CLIENT_TENANT_ID.value}/v2.0/.well-known/openid-configuration?appid={MICROSOFT_CLIENT_ID.value}",
client_kwargs={ client_kwargs={
"scope": MICROSOFT_OAUTH_SCOPE.value, "scope": MICROSOFT_OAUTH_SCOPE.value,
}, },
@ -601,14 +608,21 @@ def load_oauth_providers():
): ):
def oidc_oauth_register(client): def oidc_oauth_register(client):
client_kwargs = {
"scope": OAUTH_SCOPES.value,
}
if OAUTH_CODE_CHALLENGE_METHOD.value and OAUTH_CODE_CHALLENGE_METHOD.value == "S256":
client_kwargs["code_challenge_method"] = "S256"
elif OAUTH_CODE_CHALLENGE_METHOD.value:
raise Exception('Code challenge methods other than "%s" not supported. Given: "%s"' % ("S256", OAUTH_CODE_CHALLENGE_METHOD.value))
client.register( client.register(
name="oidc", name="oidc",
client_id=OAUTH_CLIENT_ID.value, client_id=OAUTH_CLIENT_ID.value,
client_secret=OAUTH_CLIENT_SECRET.value, client_secret=OAUTH_CLIENT_SECRET.value,
server_metadata_url=OPENID_PROVIDER_URL.value, server_metadata_url=OPENID_PROVIDER_URL.value,
client_kwargs={ client_kwargs=client_kwargs,
"scope": OAUTH_SCOPES.value,
},
redirect_uri=OPENID_REDIRECT_URI.value, redirect_uri=OPENID_REDIRECT_URI.value,
) )
@ -2141,6 +2155,18 @@ PERPLEXITY_API_KEY = PersistentConfig(
os.getenv("PERPLEXITY_API_KEY", ""), os.getenv("PERPLEXITY_API_KEY", ""),
) )
SOUGOU_API_SID = PersistentConfig(
"SOUGOU_API_SID",
"rag.web.search.sougou_api_sid",
os.getenv("SOUGOU_API_SID", ""),
)
SOUGOU_API_SK = PersistentConfig(
"SOUGOU_API_SK",
"rag.web.search.sougou_api_sk",
os.getenv("SOUGOU_API_SK", ""),
)
RAG_WEB_SEARCH_RESULT_COUNT = PersistentConfig( RAG_WEB_SEARCH_RESULT_COUNT = PersistentConfig(
"RAG_WEB_SEARCH_RESULT_COUNT", "RAG_WEB_SEARCH_RESULT_COUNT",
"rag.web.search.result_count", "rag.web.search.result_count",
@ -2472,6 +2498,24 @@ AUDIO_STT_MODEL = PersistentConfig(
os.getenv("AUDIO_STT_MODEL", ""), os.getenv("AUDIO_STT_MODEL", ""),
) )
AUDIO_STT_AZURE_API_KEY = PersistentConfig(
"AUDIO_STT_AZURE_API_KEY",
"audio.stt.azure.api_key",
os.getenv("AUDIO_STT_AZURE_API_KEY", ""),
)
AUDIO_STT_AZURE_REGION = PersistentConfig(
"AUDIO_STT_AZURE_REGION",
"audio.stt.azure.region",
os.getenv("AUDIO_STT_AZURE_REGION", ""),
)
AUDIO_STT_AZURE_LOCALES = PersistentConfig(
"AUDIO_STT_AZURE_LOCALES",
"audio.stt.azure.locales",
os.getenv("AUDIO_STT_AZURE_LOCALES", ""),
)
AUDIO_TTS_OPENAI_API_BASE_URL = PersistentConfig( AUDIO_TTS_OPENAI_API_BASE_URL = PersistentConfig(
"AUDIO_TTS_OPENAI_API_BASE_URL", "AUDIO_TTS_OPENAI_API_BASE_URL",
"audio.tts.openai.api_base_url", "audio.tts.openai.api_base_url",

View File

@ -31,6 +31,7 @@ class ERROR_MESSAGES(str, Enum):
USERNAME_TAKEN = ( USERNAME_TAKEN = (
"Uh-oh! This username is already registered. Please choose another username." "Uh-oh! This username is already registered. Please choose another username."
) )
PASSWORD_TOO_LONG = "Uh-oh! The password you entered is too long. Please make sure your password is less than 72 bytes long."
COMMAND_TAKEN = "Uh-oh! This command is already registered. Please choose another command string." COMMAND_TAKEN = "Uh-oh! This command is already registered. Please choose another command string."
FILE_EXISTS = "Uh-oh! This file is already registered. Please choose another file." FILE_EXISTS = "Uh-oh! This file is already registered. Please choose another file."

View File

@ -326,6 +326,20 @@ REDIS_URL = os.environ.get("REDIS_URL", "")
REDIS_SENTINEL_HOSTS = os.environ.get("REDIS_SENTINEL_HOSTS", "") REDIS_SENTINEL_HOSTS = os.environ.get("REDIS_SENTINEL_HOSTS", "")
REDIS_SENTINEL_PORT = os.environ.get("REDIS_SENTINEL_PORT", "26379") REDIS_SENTINEL_PORT = os.environ.get("REDIS_SENTINEL_PORT", "26379")
####################################
# UVICORN WORKERS
####################################
# Number of uvicorn worker processes for handling requests
UVICORN_WORKERS = os.environ.get("UVICORN_WORKERS", "1")
try:
UVICORN_WORKERS = int(UVICORN_WORKERS)
if UVICORN_WORKERS < 1:
UVICORN_WORKERS = 1
except ValueError:
UVICORN_WORKERS = 1
log.info(f"Invalid UVICORN_WORKERS value, defaulting to {UVICORN_WORKERS}")
#################################### ####################################
# WEBUI_AUTH (Required for security) # WEBUI_AUTH (Required for security)
#################################### ####################################
@ -411,6 +425,21 @@ else:
except Exception: except Exception:
AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST = 10 AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST = 10
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = os.environ.get(
"AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA", "10"
)
if AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA == "":
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = None
else:
try:
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = int(
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA
)
except Exception:
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = 10
#################################### ####################################
# OFFLINE_MODE # OFFLINE_MODE
#################################### ####################################
@ -463,3 +492,10 @@ OTEL_TRACES_SAMPLER = os.environ.get(
PIP_OPTIONS = os.getenv("PIP_OPTIONS", "").split() PIP_OPTIONS = os.getenv("PIP_OPTIONS", "").split()
PIP_PACKAGE_INDEX_OPTIONS = os.getenv("PIP_PACKAGE_INDEX_OPTIONS", "").split() PIP_PACKAGE_INDEX_OPTIONS = os.getenv("PIP_PACKAGE_INDEX_OPTIONS", "").split()
####################################
# PROGRESSIVE WEB APP OPTIONS
####################################
EXTERNAL_PWA_MANIFEST_URL = os.environ.get("EXTERNAL_PWA_MANIFEST_URL")

View File

@ -148,6 +148,9 @@ from open_webui.config import (
AUDIO_STT_MODEL, AUDIO_STT_MODEL,
AUDIO_STT_OPENAI_API_BASE_URL, AUDIO_STT_OPENAI_API_BASE_URL,
AUDIO_STT_OPENAI_API_KEY, AUDIO_STT_OPENAI_API_KEY,
AUDIO_STT_AZURE_API_KEY,
AUDIO_STT_AZURE_REGION,
AUDIO_STT_AZURE_LOCALES,
AUDIO_TTS_API_KEY, AUDIO_TTS_API_KEY,
AUDIO_TTS_ENGINE, AUDIO_TTS_ENGINE,
AUDIO_TTS_MODEL, AUDIO_TTS_MODEL,
@ -225,6 +228,8 @@ from open_webui.config import (
BRAVE_SEARCH_API_KEY, BRAVE_SEARCH_API_KEY,
EXA_API_KEY, EXA_API_KEY,
PERPLEXITY_API_KEY, PERPLEXITY_API_KEY,
SOUGOU_API_SID,
SOUGOU_API_SK,
KAGI_SEARCH_API_KEY, KAGI_SEARCH_API_KEY,
MOJEEK_SEARCH_API_KEY, MOJEEK_SEARCH_API_KEY,
BOCHA_SEARCH_API_KEY, BOCHA_SEARCH_API_KEY,
@ -341,6 +346,7 @@ from open_webui.env import (
RESET_CONFIG_ON_START, RESET_CONFIG_ON_START,
OFFLINE_MODE, OFFLINE_MODE,
ENABLE_OTEL, ENABLE_OTEL,
EXTERNAL_PWA_MANIFEST_URL,
) )
@ -427,6 +433,7 @@ async def lifespan(app: FastAPI):
app = FastAPI( app = FastAPI(
title="Open WebUI",
docs_url="/docs" if ENV == "dev" else None, docs_url="/docs" if ENV == "dev" else None,
openapi_url="/openapi.json" if ENV == "dev" else None, openapi_url="/openapi.json" if ENV == "dev" else None,
redoc_url=None, redoc_url=None,
@ -566,6 +573,7 @@ app.state.config.LDAP_CIPHERS = LDAP_CIPHERS
app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER
app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER
app.state.SIGNOUT_REDIRECT_URI = SIGNOUT_REDIRECT_URI app.state.SIGNOUT_REDIRECT_URI = SIGNOUT_REDIRECT_URI
app.state.EXTERNAL_PWA_MANIFEST_URL = EXTERNAL_PWA_MANIFEST_URL
app.state.USER_COUNT = None app.state.USER_COUNT = None
app.state.TOOLS = {} app.state.TOOLS = {}
@ -653,6 +661,8 @@ app.state.config.BING_SEARCH_V7_ENDPOINT = BING_SEARCH_V7_ENDPOINT
app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY
app.state.config.EXA_API_KEY = EXA_API_KEY app.state.config.EXA_API_KEY = EXA_API_KEY
app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY
app.state.config.SOUGOU_API_SID = SOUGOU_API_SID
app.state.config.SOUGOU_API_SK = SOUGOU_API_SK
app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = RAG_WEB_SEARCH_RESULT_COUNT app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = RAG_WEB_SEARCH_RESULT_COUNT
app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS = RAG_WEB_SEARCH_CONCURRENT_REQUESTS app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS = RAG_WEB_SEARCH_CONCURRENT_REQUESTS
@ -780,6 +790,10 @@ app.state.config.STT_MODEL = AUDIO_STT_MODEL
app.state.config.WHISPER_MODEL = WHISPER_MODEL app.state.config.WHISPER_MODEL = WHISPER_MODEL
app.state.config.DEEPGRAM_API_KEY = DEEPGRAM_API_KEY app.state.config.DEEPGRAM_API_KEY = DEEPGRAM_API_KEY
app.state.config.AUDIO_STT_AZURE_API_KEY = AUDIO_STT_AZURE_API_KEY
app.state.config.AUDIO_STT_AZURE_REGION = AUDIO_STT_AZURE_REGION
app.state.config.AUDIO_STT_AZURE_LOCALES = AUDIO_STT_AZURE_LOCALES
app.state.config.TTS_OPENAI_API_BASE_URL = AUDIO_TTS_OPENAI_API_BASE_URL app.state.config.TTS_OPENAI_API_BASE_URL = AUDIO_TTS_OPENAI_API_BASE_URL
app.state.config.TTS_OPENAI_API_KEY = AUDIO_TTS_OPENAI_API_KEY app.state.config.TTS_OPENAI_API_KEY = AUDIO_TTS_OPENAI_API_KEY
app.state.config.TTS_ENGINE = AUDIO_TTS_ENGINE app.state.config.TTS_ENGINE = AUDIO_TTS_ENGINE
@ -1055,6 +1069,7 @@ async def chat_completion(
model_item = form_data.pop("model_item", {}) model_item = form_data.pop("model_item", {})
tasks = form_data.pop("background_tasks", None) tasks = form_data.pop("background_tasks", None)
metadata = {}
try: try:
if not model_item.get("direct", False): if not model_item.get("direct", False):
model_id = form_data.get("model", None) model_id = form_data.get("model", None)
@ -1110,13 +1125,15 @@ async def chat_completion(
except Exception as e: except Exception as e:
log.debug(f"Error processing chat payload: {e}") log.debug(f"Error processing chat payload: {e}")
Chats.upsert_message_to_chat_by_id_and_message_id( if metadata.get("chat_id") and metadata.get("message_id"):
metadata["chat_id"], # Update the chat message with the error
metadata["message_id"], Chats.upsert_message_to_chat_by_id_and_message_id(
{ metadata["chat_id"],
"error": {"content": str(e)}, metadata["message_id"],
}, {
) "error": {"content": str(e)},
},
)
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
@ -1392,29 +1409,32 @@ async def oauth_callback(provider: str, request: Request, response: Response):
@app.get("/manifest.json") @app.get("/manifest.json")
async def get_manifest_json(): async def get_manifest_json():
return { if app.state.EXTERNAL_PWA_MANIFEST_URL:
"name": app.state.WEBUI_NAME, return requests.get(app.state.EXTERNAL_PWA_MANIFEST_URL).json()
"short_name": app.state.WEBUI_NAME, else:
"description": "Open WebUI is an open, extensible, user-friendly interface for AI that adapts to your workflow.", return {
"start_url": "/", "name": app.state.WEBUI_NAME,
"display": "standalone", "short_name": app.state.WEBUI_NAME,
"background_color": "#343541", "description": "Open WebUI is an open, extensible, user-friendly interface for AI that adapts to your workflow.",
"orientation": "natural", "start_url": "/",
"icons": [ "display": "standalone",
{ "background_color": "#343541",
"src": "/static/logo.png", "orientation": "natural",
"type": "image/png", "icons": [
"sizes": "500x500", {
"purpose": "any", "src": "/static/logo.png",
}, "type": "image/png",
{ "sizes": "500x500",
"src": "/static/logo.png", "purpose": "any",
"type": "image/png", },
"sizes": "500x500", {
"purpose": "maskable", "src": "/static/logo.png",
}, "type": "image/png",
], "sizes": "500x500",
} "purpose": "maskable",
},
],
}
@app.get("/opensearch.xml") @app.get("/opensearch.xml")

View File

@ -110,7 +110,7 @@ class YoutubeLoader:
transcript = " ".join( transcript = " ".join(
map( map(
lambda transcript_piece: transcript_piece["text"].strip(" "), lambda transcript_piece: transcript_piece.text.strip(" "),
transcript_pieces, transcript_pieces,
) )
) )

View File

@ -77,6 +77,7 @@ def query_doc(
collection_name: str, query_embedding: list[float], k: int, user: UserModel = None collection_name: str, query_embedding: list[float], k: int, user: UserModel = None
): ):
try: try:
log.debug(f"query_doc:doc {collection_name}")
result = VECTOR_DB_CLIENT.search( result = VECTOR_DB_CLIENT.search(
collection_name=collection_name, collection_name=collection_name,
vectors=[query_embedding], vectors=[query_embedding],
@ -94,6 +95,7 @@ def query_doc(
def get_doc(collection_name: str, user: UserModel = None): def get_doc(collection_name: str, user: UserModel = None):
try: try:
log.debug(f"get_doc:doc {collection_name}")
result = VECTOR_DB_CLIENT.get(collection_name=collection_name) result = VECTOR_DB_CLIENT.get(collection_name=collection_name)
if result: if result:
@ -116,6 +118,7 @@ def query_doc_with_hybrid_search(
r: float, r: float,
) -> dict: ) -> dict:
try: try:
log.debug(f"query_doc_with_hybrid_search:doc {collection_name}")
bm25_retriever = BM25Retriever.from_texts( bm25_retriever = BM25Retriever.from_texts(
texts=collection_result.documents[0], texts=collection_result.documents[0],
metadatas=collection_result.metadatas[0], metadatas=collection_result.metadatas[0],
@ -168,6 +171,7 @@ def query_doc_with_hybrid_search(
) )
return result return result
except Exception as e: except Exception as e:
log.exception(f"Error querying doc {collection_name} with hybrid search: {e}")
raise e raise e
@ -257,6 +261,7 @@ def query_collection(
) -> dict: ) -> dict:
results = [] results = []
for query in queries: for query in queries:
log.debug(f"query_collection:query {query}")
query_embedding = embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX) query_embedding = embedding_function(query, prefix=RAG_EMBEDDING_QUERY_PREFIX)
for collection_name in collection_names: for collection_name in collection_names:
if collection_name: if collection_name:
@ -292,6 +297,7 @@ def query_collection_with_hybrid_search(
collection_results = {} collection_results = {}
for collection_name in collection_names: for collection_name in collection_names:
try: try:
log.debug(f"query_collection_with_hybrid_search:VECTOR_DB_CLIENT.get:collection {collection_name}")
collection_results[collection_name] = VECTOR_DB_CLIENT.get( collection_results[collection_name] = VECTOR_DB_CLIENT.get(
collection_name=collection_name collection_name=collection_name
) )
@ -613,6 +619,7 @@ def generate_openai_batch_embeddings(
user: UserModel = None, user: UserModel = None,
) -> Optional[list[list[float]]]: ) -> Optional[list[list[float]]]:
try: try:
log.debug(f"generate_openai_batch_embeddings:model {model} batch size: {len(texts)}")
json_data = {"input": texts, "model": model} json_data = {"input": texts, "model": model}
if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str): if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str):
json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix
@ -655,6 +662,7 @@ def generate_ollama_batch_embeddings(
user: UserModel = None, user: UserModel = None,
) -> Optional[list[list[float]]]: ) -> Optional[list[list[float]]]:
try: try:
log.debug(f"generate_ollama_batch_embeddings:model {model} batch size: {len(texts)}")
json_data = {"input": texts, "model": model} json_data = {"input": texts, "model": model}
if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str): if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str):
json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix

View File

@ -3,6 +3,7 @@ from typing import Optional
from open_webui.retrieval.web.main import SearchResult, get_filtered_results from open_webui.retrieval.web.main import SearchResult, get_filtered_results
from duckduckgo_search import DDGS from duckduckgo_search import DDGS
from duckduckgo_search.exceptions import RatelimitException
from open_webui.env import SRC_LOG_LEVELS from open_webui.env import SRC_LOG_LEVELS
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -22,16 +23,15 @@ def search_duckduckgo(
list[SearchResult]: A list of search results list[SearchResult]: A list of search results
""" """
# Use the DDGS context manager to create a DDGS object # Use the DDGS context manager to create a DDGS object
search_results = []
with DDGS() as ddgs: with DDGS() as ddgs:
# Use the ddgs.text() method to perform the search # Use the ddgs.text() method to perform the search
ddgs_gen = ddgs.text( try:
query, safesearch="moderate", max_results=count, backend="api" search_results = ddgs.text(
) query, safesearch="moderate", max_results=count, backend="lite"
# Check if there are search results )
if ddgs_gen: except RatelimitException as e:
# Convert the search results into a list log.error(f"RatelimitException: {e}")
search_results = [r for r in ddgs_gen]
if filter_list: if filter_list:
search_results = get_filtered_results(search_results, filter_list) search_results = get_filtered_results(search_results, filter_list)

View File

@ -0,0 +1,60 @@
import logging
import json
from typing import Optional, List
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
from open_webui.env import SRC_LOG_LEVELS
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["RAG"])
def search_sougou(
sougou_api_sid: str,
sougou_api_sk: str,
query: str,
count: int,
filter_list: Optional[List[str]] = None,
) -> List[SearchResult]:
from tencentcloud.common.common_client import CommonClient
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import (
TencentCloudSDKException,
)
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
try:
cred = credential.Credential(sougou_api_sid, sougou_api_sk)
http_profile = HttpProfile()
http_profile.endpoint = "tms.tencentcloudapi.com"
client_profile = ClientProfile()
client_profile.http_profile = http_profile
params = json.dumps({"Query": query, "Cnt": 20})
common_client = CommonClient(
"tms", "2020-12-29", cred, "", profile=client_profile
)
results = [
json.loads(page)
for page in common_client.call_json("SearchPro", json.loads(params))[
"Response"
]["Pages"]
]
sorted_results = sorted(
results, key=lambda x: x.get("scour", 0.0), reverse=True
)
if filter_list:
sorted_results = get_filtered_results(sorted_results, filter_list)
return [
SearchResult(
link=result.get("url"),
title=result.get("title"),
snippet=result.get("passage"),
)
for result in sorted_results[:count]
]
except TencentCloudSDKException as err:
log.error(f"Error in Sougou search: {err}")
return []

View File

@ -50,6 +50,8 @@ router = APIRouter()
# Constants # Constants
MAX_FILE_SIZE_MB = 25 MAX_FILE_SIZE_MB = 25
MAX_FILE_SIZE = MAX_FILE_SIZE_MB * 1024 * 1024 # Convert MB to bytes MAX_FILE_SIZE = MAX_FILE_SIZE_MB * 1024 * 1024 # Convert MB to bytes
AZURE_MAX_FILE_SIZE_MB = 200
AZURE_MAX_FILE_SIZE = AZURE_MAX_FILE_SIZE_MB * 1024 * 1024 # Convert MB to bytes
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["AUDIO"]) log.setLevel(SRC_LOG_LEVELS["AUDIO"])
@ -68,8 +70,8 @@ from pydub import AudioSegment
from pydub.utils import mediainfo from pydub.utils import mediainfo
def is_mp4_audio(file_path): def get_audio_format(file_path):
"""Check if the given file is an MP4 audio file.""" """Check if the given file needs to be converted to a different format."""
if not os.path.isfile(file_path): if not os.path.isfile(file_path):
log.error(f"File not found: {file_path}") log.error(f"File not found: {file_path}")
return False return False
@ -80,13 +82,17 @@ def is_mp4_audio(file_path):
and info.get("codec_type") == "audio" and info.get("codec_type") == "audio"
and info.get("codec_tag_string") == "mp4a" and info.get("codec_tag_string") == "mp4a"
): ):
return True return "mp4"
return False elif info.get("format_name") == "ogg":
return "ogg"
elif info.get("format_name") == "matroska,webm":
return "webm"
return None
def convert_mp4_to_wav(file_path, output_path): def convert_audio_to_wav(file_path, output_path, conversion_type):
"""Convert MP4 audio file to WAV format.""" """Convert MP4/OGG audio file to WAV format."""
audio = AudioSegment.from_file(file_path, format="mp4") audio = AudioSegment.from_file(file_path, format=conversion_type)
audio.export(output_path, format="wav") audio.export(output_path, format="wav")
log.info(f"Converted {file_path} to {output_path}") log.info(f"Converted {file_path} to {output_path}")
@ -141,6 +147,9 @@ class STTConfigForm(BaseModel):
MODEL: str MODEL: str
WHISPER_MODEL: str WHISPER_MODEL: str
DEEPGRAM_API_KEY: str DEEPGRAM_API_KEY: str
AZURE_API_KEY: str
AZURE_REGION: str
AZURE_LOCALES: str
class AudioConfigUpdateForm(BaseModel): class AudioConfigUpdateForm(BaseModel):
@ -169,6 +178,9 @@ async def get_audio_config(request: Request, user=Depends(get_admin_user)):
"MODEL": request.app.state.config.STT_MODEL, "MODEL": request.app.state.config.STT_MODEL,
"WHISPER_MODEL": request.app.state.config.WHISPER_MODEL, "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL,
"DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY, "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY,
"AZURE_API_KEY": request.app.state.config.AUDIO_STT_AZURE_API_KEY,
"AZURE_REGION": request.app.state.config.AUDIO_STT_AZURE_REGION,
"AZURE_LOCALES": request.app.state.config.AUDIO_STT_AZURE_LOCALES,
}, },
} }
@ -195,6 +207,9 @@ async def update_audio_config(
request.app.state.config.STT_MODEL = form_data.stt.MODEL request.app.state.config.STT_MODEL = form_data.stt.MODEL
request.app.state.config.WHISPER_MODEL = form_data.stt.WHISPER_MODEL request.app.state.config.WHISPER_MODEL = form_data.stt.WHISPER_MODEL
request.app.state.config.DEEPGRAM_API_KEY = form_data.stt.DEEPGRAM_API_KEY request.app.state.config.DEEPGRAM_API_KEY = form_data.stt.DEEPGRAM_API_KEY
request.app.state.config.AUDIO_STT_AZURE_API_KEY = form_data.stt.AZURE_API_KEY
request.app.state.config.AUDIO_STT_AZURE_REGION = form_data.stt.AZURE_REGION
request.app.state.config.AUDIO_STT_AZURE_LOCALES = form_data.stt.AZURE_LOCALES
if request.app.state.config.STT_ENGINE == "": if request.app.state.config.STT_ENGINE == "":
request.app.state.faster_whisper_model = set_faster_whisper_model( request.app.state.faster_whisper_model = set_faster_whisper_model(
@ -220,6 +235,9 @@ async def update_audio_config(
"MODEL": request.app.state.config.STT_MODEL, "MODEL": request.app.state.config.STT_MODEL,
"WHISPER_MODEL": request.app.state.config.WHISPER_MODEL, "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL,
"DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY, "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY,
"AZURE_API_KEY": request.app.state.config.AUDIO_STT_AZURE_API_KEY,
"AZURE_REGION": request.app.state.config.AUDIO_STT_AZURE_REGION,
"AZURE_LOCALES": request.app.state.config.AUDIO_STT_AZURE_LOCALES,
}, },
} }
@ -496,10 +514,15 @@ def transcribe(request: Request, file_path):
log.debug(data) log.debug(data)
return data return data
elif request.app.state.config.STT_ENGINE == "openai": elif request.app.state.config.STT_ENGINE == "openai":
if is_mp4_audio(file_path): audio_format = get_audio_format(file_path)
os.rename(file_path, file_path.replace(".wav", ".mp4")) if audio_format:
# Convert MP4 audio file to WAV format os.rename(file_path, file_path.replace(".wav", f".{audio_format}"))
convert_mp4_to_wav(file_path.replace(".wav", ".mp4"), file_path) # Convert unsupported audio file to WAV format
convert_audio_to_wav(
file_path.replace(".wav", f".{audio_format}"),
file_path,
audio_format,
)
r = None r = None
try: try:
@ -598,6 +621,107 @@ def transcribe(request: Request, file_path):
detail = f"External: {e}" detail = f"External: {e}"
raise Exception(detail if detail else "Open WebUI: Server Connection Error") raise Exception(detail if detail else "Open WebUI: Server Connection Error")
elif request.app.state.config.STT_ENGINE == "azure":
# Check file exists and size
if not os.path.exists(file_path):
raise HTTPException(
status_code=400,
detail="Audio file not found"
)
# Check file size (Azure has a larger limit of 200MB)
file_size = os.path.getsize(file_path)
if file_size > AZURE_MAX_FILE_SIZE:
raise HTTPException(
status_code=400,
detail=f"File size exceeds Azure's limit of {AZURE_MAX_FILE_SIZE_MB}MB",
)
api_key = request.app.state.config.AUDIO_STT_AZURE_API_KEY
region = request.app.state.config.AUDIO_STT_AZURE_REGION
locales = request.app.state.config.AUDIO_STT_AZURE_LOCALES
# IF NO LOCALES, USE DEFAULTS
if len(locales) < 2:
locales = ['en-US', 'es-ES', 'es-MX', 'fr-FR', 'hi-IN',
'it-IT','de-DE', 'en-GB', 'en-IN', 'ja-JP',
'ko-KR', 'pt-BR', 'zh-CN']
locales = ','.join(locales)
if not api_key or not region:
raise HTTPException(
status_code=400,
detail="Azure API key and region are required for Azure STT",
)
r = None
try:
# Prepare the request
data = {'definition': json.dumps({
"locales": locales.split(','),
"diarization": {"maxSpeakers": 3,"enabled": True}
} if locales else {}
)
}
url = f"https://{region}.api.cognitive.microsoft.com/speechtotext/transcriptions:transcribe?api-version=2024-11-15"
# Use context manager to ensure file is properly closed
with open(file_path, 'rb') as audio_file:
r = requests.post(
url=url,
files={'audio': audio_file},
data=data,
headers={
'Ocp-Apim-Subscription-Key': api_key,
},
)
r.raise_for_status()
response = r.json()
# Extract transcript from response
if not response.get('combinedPhrases'):
raise ValueError("No transcription found in response")
# Get the full transcript from combinedPhrases
transcript = response['combinedPhrases'][0].get('text', '').strip()
if not transcript:
raise ValueError("Empty transcript in response")
data = {"text": transcript}
# Save transcript to json file (consistent with other providers)
transcript_file = f"{file_dir}/{id}.json"
with open(transcript_file, "w") as f:
json.dump(data, f)
log.debug(data)
return data
except (KeyError, IndexError, ValueError) as e:
log.exception("Error parsing Azure response")
raise HTTPException(
status_code=500,
detail=f"Failed to parse Azure response: {str(e)}",
)
except requests.exceptions.RequestException as e:
log.exception(e)
detail = None
try:
if r is not None and r.status_code != 200:
res = r.json()
if "error" in res:
detail = f"External: {res['error'].get('message', '')}"
except Exception:
detail = f"External: {e}"
raise HTTPException(
status_code=getattr(r, 'status_code', 500) if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)
def compress_audio(file_path): def compress_audio(file_path):
if os.path.getsize(file_path) > MAX_FILE_SIZE: if os.path.getsize(file_path) > MAX_FILE_SIZE:

View File

@ -231,11 +231,13 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
entry = connection_app.entries[0] entry = connection_app.entries[0]
username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower() username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower()
email = str(entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]) email = entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]
if not email or email == "" or email == "[]": if not email:
raise HTTPException(400, "User does not have a valid email address.") raise HTTPException(400, "User does not have a valid email address.")
else: elif isinstance(email, str):
email = email.lower() email = email.lower()
elif isinstance(email, list):
email = email[0].lower()
cn = str(entry["cn"]) cn = str(entry["cn"])
user_dn = entry.entry_dn user_dn = entry.entry_dn
@ -455,6 +457,13 @@ async def signup(request: Request, response: Response, form_data: SignupForm):
# Disable signup after the first user is created # Disable signup after the first user is created
request.app.state.config.ENABLE_SIGNUP = False request.app.state.config.ENABLE_SIGNUP = False
# The password passed to bcrypt must be 72 bytes or fewer. If it is longer, it will be truncated before hashing.
if len(form_data.password.encode("utf-8")) > 72:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.PASSWORD_TOO_LONG,
)
hashed = get_password_hash(form_data.password) hashed = get_password_hash(form_data.password)
user = Auths.insert_new_auth( user = Auths.insert_new_auth(
form_data.email.lower(), form_data.email.lower(),

View File

@ -1,6 +1,7 @@
import logging import logging
import os import os
import uuid import uuid
from fnmatch import fnmatch
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from urllib.parse import quote from urllib.parse import quote
@ -177,6 +178,47 @@ async def list_files(user=Depends(get_verified_user), content: bool = Query(True
return files return files
############################
# Search Files
############################
@router.get("/search", response_model=list[FileModelResponse])
async def search_files(
filename: str = Query(
...,
description="Filename pattern to search for. Supports wildcards such as '*.txt'",
),
content: bool = Query(True),
user=Depends(get_verified_user),
):
"""
Search for files by filename with support for wildcard patterns.
"""
# Get files according to user role
if user.role == "admin":
files = Files.get_files()
else:
files = Files.get_files_by_user_id(user.id)
# Get matching files
matching_files = [
file for file in files if fnmatch(file.filename.lower(), filename.lower())
]
if not matching_files:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="No files found matching the pattern.",
)
if not content:
for file in matching_files:
del file.data["content"]
return matching_files
############################ ############################
# Delete All Files # Delete All Files
############################ ############################

View File

@ -161,6 +161,72 @@ async def create_new_knowledge(
) )
############################
# ReindexKnowledgeFiles
############################
@router.post("/reindex", response_model=bool)
async def reindex_knowledge_files(
request: Request,
user=Depends(get_verified_user)
):
if user.role != "admin":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
knowledge_bases = Knowledges.get_knowledge_bases()
log.info(f"Starting reindexing for {len(knowledge_bases)} knowledge bases")
for knowledge_base in knowledge_bases:
try:
files = Files.get_files_by_ids(knowledge_base.data.get("file_ids", []))
try:
if VECTOR_DB_CLIENT.has_collection(collection_name=knowledge_base.id):
VECTOR_DB_CLIENT.delete_collection(
collection_name=knowledge_base.id
)
except Exception as e:
log.error(f"Error deleting collection {knowledge_base.id}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error deleting vector DB collection"
)
failed_files = []
for file in files:
try:
process_file(
request,
ProcessFileForm(file_id=file.id, collection_name=knowledge_base.id),
user=user,
)
except Exception as e:
log.error(f"Error processing file {file.filename} (ID: {file.id}): {str(e)}")
failed_files.append({"file_id": file.id, "error": str(e)})
continue
except Exception as e:
log.error(f"Error processing knowledge base {knowledge_base.id}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error processing knowledge base"
)
if failed_files:
log.warning(f"Failed to process {len(failed_files)} files in knowledge base {knowledge_base.id}")
for failed in failed_files:
log.warning(f"File ID: {failed['file_id']}, Error: {failed['error']}")
log.info("Reindexing completed successfully")
return True
############################ ############################
# GetKnowledgeById # GetKnowledgeById
############################ ############################
@ -676,3 +742,6 @@ def add_files_to_knowledge_batch(
return KnowledgeFilesResponse( return KnowledgeFilesResponse(
**knowledge.model_dump(), files=Files.get_files_by_ids(existing_file_ids) **knowledge.model_dump(), files=Files.get_files_by_ids(existing_file_ids)
) )

View File

@ -60,6 +60,7 @@ from open_webui.retrieval.web.tavily import search_tavily
from open_webui.retrieval.web.bing import search_bing from open_webui.retrieval.web.bing import search_bing
from open_webui.retrieval.web.exa import search_exa from open_webui.retrieval.web.exa import search_exa
from open_webui.retrieval.web.perplexity import search_perplexity from open_webui.retrieval.web.perplexity import search_perplexity
from open_webui.retrieval.web.sougou import search_sougou
from open_webui.retrieval.utils import ( from open_webui.retrieval.utils import (
get_embedding_function, get_embedding_function,
@ -411,6 +412,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
"bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
"exa_api_key": request.app.state.config.EXA_API_KEY, "exa_api_key": request.app.state.config.EXA_API_KEY,
"perplexity_api_key": request.app.state.config.PERPLEXITY_API_KEY, "perplexity_api_key": request.app.state.config.PERPLEXITY_API_KEY,
"sougou_api_sid": request.app.state.config.SOUGOU_API_SID,
"sougou_api_sk": request.app.state.config.SOUGOU_API_SK,
"result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
"trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV, "trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV,
"concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
@ -478,6 +481,8 @@ class WebSearchConfig(BaseModel):
bing_search_v7_subscription_key: Optional[str] = None bing_search_v7_subscription_key: Optional[str] = None
exa_api_key: Optional[str] = None exa_api_key: Optional[str] = None
perplexity_api_key: Optional[str] = None perplexity_api_key: Optional[str] = None
sougou_api_sid: Optional[str] = None
sougou_api_sk: Optional[str] = None
result_count: Optional[int] = None result_count: Optional[int] = None
concurrent_requests: Optional[int] = None concurrent_requests: Optional[int] = None
trust_env: Optional[bool] = None trust_env: Optional[bool] = None
@ -640,6 +645,12 @@ async def update_rag_config(
request.app.state.config.PERPLEXITY_API_KEY = ( request.app.state.config.PERPLEXITY_API_KEY = (
form_data.web.search.perplexity_api_key form_data.web.search.perplexity_api_key
) )
request.app.state.config.SOUGOU_API_SID = (
form_data.web.search.sougou_api_sid
)
request.app.state.config.SOUGOU_API_SK = (
form_data.web.search.sougou_api_sk
)
request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = ( request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = (
form_data.web.search.result_count form_data.web.search.result_count
@ -712,6 +723,8 @@ async def update_rag_config(
"bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
"exa_api_key": request.app.state.config.EXA_API_KEY, "exa_api_key": request.app.state.config.EXA_API_KEY,
"perplexity_api_key": request.app.state.config.PERPLEXITY_API_KEY, "perplexity_api_key": request.app.state.config.PERPLEXITY_API_KEY,
"sougou_api_sid": request.app.state.config.SOUGOU_API_SID,
"sougou_api_sk": request.app.state.config.SOUGOU_API_SK,
"result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
"concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
"trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV, "trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV,
@ -1267,6 +1280,7 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]:
- TAVILY_API_KEY - TAVILY_API_KEY
- EXA_API_KEY - EXA_API_KEY
- PERPLEXITY_API_KEY - PERPLEXITY_API_KEY
- SOUGOU_API_SID + SOUGOU_API_SK
- SEARCHAPI_API_KEY + SEARCHAPI_ENGINE (by default `google`) - SEARCHAPI_API_KEY + SEARCHAPI_ENGINE (by default `google`)
- SERPAPI_API_KEY + SERPAPI_ENGINE (by default `google`) - SERPAPI_API_KEY + SERPAPI_ENGINE (by default `google`)
Args: Args:
@ -1438,6 +1452,17 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]:
request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
) )
elif engine == 'sougou':
if request.app.state.config.SOUGOU_API_SID and request.app.state.config.SOUGOU_API_SK:
return search_sougou(
request.app.state.config.SOUGOU_API_SID,
request.app.state.config.SOUGOU_API_SK,
query,
request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
)
else:
raise Exception("No SOUGOU_API_SID or SOUGOU_API_SK found in environment variables")
else: else:
raise Exception("No search engine API key found in environment variables") raise Exception("No search engine API key found in environment variables")

View File

@ -10,11 +10,11 @@ from open_webui.models.tools import (
ToolUserResponse, ToolUserResponse,
Tools, Tools,
) )
from open_webui.utils.plugin import load_tools_module_by_id, replace_imports from open_webui.utils.plugin import load_tool_module_by_id, replace_imports
from open_webui.config import CACHE_DIR from open_webui.config import CACHE_DIR
from open_webui.constants import ERROR_MESSAGES from open_webui.constants import ERROR_MESSAGES
from fastapi import APIRouter, Depends, HTTPException, Request, status from fastapi import APIRouter, Depends, HTTPException, Request, status
from open_webui.utils.tools import get_tools_specs from open_webui.utils.tools import get_tool_specs
from open_webui.utils.auth import get_admin_user, get_verified_user from open_webui.utils.auth import get_admin_user, get_verified_user
from open_webui.utils.access_control import has_access, has_permission from open_webui.utils.access_control import has_access, has_permission
from open_webui.env import SRC_LOG_LEVELS from open_webui.env import SRC_LOG_LEVELS
@ -45,7 +45,7 @@ async def get_tools(request: Request, user=Depends(get_verified_user)):
) )
tools = Tools.get_tools() tools = Tools.get_tools()
for idx, server in enumerate(request.app.state.TOOL_SERVERS): for server in request.app.state.TOOL_SERVERS:
tools.append( tools.append(
ToolUserResponse( ToolUserResponse(
**{ **{
@ -60,7 +60,7 @@ async def get_tools(request: Request, user=Depends(get_verified_user)):
.get("description", ""), .get("description", ""),
}, },
"access_control": request.app.state.config.TOOL_SERVER_CONNECTIONS[ "access_control": request.app.state.config.TOOL_SERVER_CONNECTIONS[
idx server["idx"]
] ]
.get("config", {}) .get("config", {})
.get("access_control", None), .get("access_control", None),
@ -137,15 +137,15 @@ async def create_new_tools(
if tools is None: if tools is None:
try: try:
form_data.content = replace_imports(form_data.content) form_data.content = replace_imports(form_data.content)
tools_module, frontmatter = load_tools_module_by_id( tool_module, frontmatter = load_tool_module_by_id(
form_data.id, content=form_data.content form_data.id, content=form_data.content
) )
form_data.meta.manifest = frontmatter form_data.meta.manifest = frontmatter
TOOLS = request.app.state.TOOLS TOOLS = request.app.state.TOOLS
TOOLS[form_data.id] = tools_module TOOLS[form_data.id] = tool_module
specs = get_tools_specs(TOOLS[form_data.id]) specs = get_tool_specs(TOOLS[form_data.id])
tools = Tools.insert_new_tool(user.id, form_data, specs) tools = Tools.insert_new_tool(user.id, form_data, specs)
tool_cache_dir = CACHE_DIR / "tools" / form_data.id tool_cache_dir = CACHE_DIR / "tools" / form_data.id
@ -226,15 +226,13 @@ async def update_tools_by_id(
try: try:
form_data.content = replace_imports(form_data.content) form_data.content = replace_imports(form_data.content)
tools_module, frontmatter = load_tools_module_by_id( tool_module, frontmatter = load_tool_module_by_id(id, content=form_data.content)
id, content=form_data.content
)
form_data.meta.manifest = frontmatter form_data.meta.manifest = frontmatter
TOOLS = request.app.state.TOOLS TOOLS = request.app.state.TOOLS
TOOLS[id] = tools_module TOOLS[id] = tool_module
specs = get_tools_specs(TOOLS[id]) specs = get_tool_specs(TOOLS[id])
updated = { updated = {
**form_data.model_dump(exclude={"id"}), **form_data.model_dump(exclude={"id"}),
@ -332,7 +330,7 @@ async def get_tools_valves_spec_by_id(
if id in request.app.state.TOOLS: if id in request.app.state.TOOLS:
tools_module = request.app.state.TOOLS[id] tools_module = request.app.state.TOOLS[id]
else: else:
tools_module, _ = load_tools_module_by_id(id) tools_module, _ = load_tool_module_by_id(id)
request.app.state.TOOLS[id] = tools_module request.app.state.TOOLS[id] = tools_module
if hasattr(tools_module, "Valves"): if hasattr(tools_module, "Valves"):
@ -375,7 +373,7 @@ async def update_tools_valves_by_id(
if id in request.app.state.TOOLS: if id in request.app.state.TOOLS:
tools_module = request.app.state.TOOLS[id] tools_module = request.app.state.TOOLS[id]
else: else:
tools_module, _ = load_tools_module_by_id(id) tools_module, _ = load_tool_module_by_id(id)
request.app.state.TOOLS[id] = tools_module request.app.state.TOOLS[id] = tools_module
if not hasattr(tools_module, "Valves"): if not hasattr(tools_module, "Valves"):
@ -431,7 +429,7 @@ async def get_tools_user_valves_spec_by_id(
if id in request.app.state.TOOLS: if id in request.app.state.TOOLS:
tools_module = request.app.state.TOOLS[id] tools_module = request.app.state.TOOLS[id]
else: else:
tools_module, _ = load_tools_module_by_id(id) tools_module, _ = load_tool_module_by_id(id)
request.app.state.TOOLS[id] = tools_module request.app.state.TOOLS[id] = tools_module
if hasattr(tools_module, "UserValves"): if hasattr(tools_module, "UserValves"):
@ -455,7 +453,7 @@ async def update_tools_user_valves_by_id(
if id in request.app.state.TOOLS: if id in request.app.state.TOOLS:
tools_module = request.app.state.TOOLS[id] tools_module = request.app.state.TOOLS[id]
else: else:
tools_module, _ = load_tools_module_by_id(id) tools_module, _ = load_tool_module_by_id(id)
request.app.state.TOOLS[id] = tools_module request.app.state.TOOLS[id] = tools_module
if hasattr(tools_module, "UserValves"): if hasattr(tools_module, "UserValves"):

View File

@ -897,12 +897,16 @@ async def process_chat_payload(request, form_data, user, metadata, model):
# If context is not empty, insert it into the messages # If context is not empty, insert it into the messages
if len(sources) > 0: if len(sources) > 0:
context_string = "" context_string = ""
for source_idx, source in enumerate(sources): citated_file_idx = {}
for _, source in enumerate(sources, 1):
if "document" in source: if "document" in source:
for doc_idx, doc_context in enumerate(source["document"]): for doc_context, doc_meta in zip(
context_string += ( source["document"], source["metadata"]
f'<source id="{source_idx + 1}">{doc_context}</source>\n' ):
) file_id = doc_meta.get("file_id")
if file_id not in citated_file_idx:
citated_file_idx[file_id] = len(citated_file_idx) + 1
context_string += f'<source id="{citated_file_idx[file_id]}">{doc_context}</source>\n'
context_string = context_string.strip() context_string = context_string.strip()
prompt = get_last_user_message(form_data["messages"]) prompt = get_last_user_message(form_data["messages"])
@ -1609,6 +1613,9 @@ async def process_chat_response(
) )
if data: if data:
if "event" in data:
await event_emitter(data.get("event", {}))
if "selected_model_id" in data: if "selected_model_id" in data:
model_id = data["selected_model_id"] model_id = data["selected_model_id"]
Chats.upsert_message_to_chat_by_id_and_message_id( Chats.upsert_message_to_chat_by_id_and_message_id(
@ -1653,14 +1660,27 @@ async def process_chat_response(
) )
if tool_call_index is not None: if tool_call_index is not None:
if ( # Check if the tool call already exists
len(response_tool_calls) current_response_tool_call = None
<= tool_call_index for (
): response_tool_call
) in response_tool_calls:
if (
response_tool_call.get("index")
== tool_call_index
):
current_response_tool_call = (
response_tool_call
)
break
if current_response_tool_call is None:
# Add the new tool call
response_tool_calls.append( response_tool_calls.append(
delta_tool_call delta_tool_call
) )
else: else:
# Update the existing tool call
delta_name = delta_tool_call.get( delta_name = delta_tool_call.get(
"function", {} "function", {}
).get("name") ).get("name")
@ -1671,16 +1691,14 @@ async def process_chat_response(
) )
if delta_name: if delta_name:
response_tool_calls[ current_response_tool_call[
tool_call_index "function"
]["function"][ ]["name"] += delta_name
"name"
] += delta_name
if delta_arguments: if delta_arguments:
response_tool_calls[ current_response_tool_call[
tool_call_index "function"
]["function"][ ][
"arguments" "arguments"
] += delta_arguments ] += delta_arguments

View File

@ -68,7 +68,7 @@ def replace_imports(content):
return content return content
def load_tools_module_by_id(tool_id, content=None): def load_tool_module_by_id(tool_id, content=None):
if content is None: if content is None:
tool = Tools.get_tool_by_id(tool_id) tool = Tools.get_tool_by_id(tool_id)

View File

@ -4,19 +4,39 @@ import re
import inspect import inspect
import aiohttp import aiohttp
import asyncio import asyncio
import yaml
from typing import Any, Awaitable, Callable, get_type_hints, Dict, List, Union, Optional from pydantic import BaseModel
from pydantic.fields import FieldInfo
from typing import (
Any,
Awaitable,
Callable,
get_type_hints,
get_args,
get_origin,
Dict,
List,
Tuple,
Union,
Optional,
Type,
)
from functools import update_wrapper, partial from functools import update_wrapper, partial
from fastapi import Request from fastapi import Request
from pydantic import BaseModel, Field, create_model from pydantic import BaseModel, Field, create_model
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_core.utils.function_calling import (
convert_to_openai_function as convert_pydantic_model_to_openai_function_spec,
)
from open_webui.models.tools import Tools from open_webui.models.tools import Tools
from open_webui.models.users import UserModel from open_webui.models.users import UserModel
from open_webui.utils.plugin import load_tools_module_by_id from open_webui.utils.plugin import load_tool_module_by_id
from open_webui.env import AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA
import copy import copy
@ -55,7 +75,12 @@ def get_tools(
tool_server_connection = ( tool_server_connection = (
request.app.state.config.TOOL_SERVER_CONNECTIONS[server_idx] request.app.state.config.TOOL_SERVER_CONNECTIONS[server_idx]
) )
tool_server_data = request.app.state.TOOL_SERVERS[server_idx] tool_server_data = None
for server in request.app.state.TOOL_SERVERS:
if server["idx"] == server_idx:
tool_server_data = server
break
assert tool_server_data is not None
specs = tool_server_data.get("specs", []) specs = tool_server_data.get("specs", [])
for spec in specs: for spec in specs:
@ -112,7 +137,7 @@ def get_tools(
else: else:
module = request.app.state.TOOLS.get(tool_id, None) module = request.app.state.TOOLS.get(tool_id, None)
if module is None: if module is None:
module, _ = load_tools_module_by_id(tool_id) module, _ = load_tool_module_by_id(tool_id)
request.app.state.TOOLS[tool_id] = module request.app.state.TOOLS[tool_id] = module
extra_params["__id__"] = tool_id extra_params["__id__"] = tool_id
@ -233,7 +258,7 @@ def parse_docstring(docstring):
return param_descriptions return param_descriptions
def function_to_pydantic_model(func: Callable) -> type[BaseModel]: def convert_function_to_pydantic_model(func: Callable) -> type[BaseModel]:
""" """
Converts a Python function's type hints and docstring to a Pydantic model, Converts a Python function's type hints and docstring to a Pydantic model,
including support for nested types, default values, and descriptions. including support for nested types, default values, and descriptions.
@ -250,45 +275,57 @@ def function_to_pydantic_model(func: Callable) -> type[BaseModel]:
parameters = signature.parameters parameters = signature.parameters
docstring = func.__doc__ docstring = func.__doc__
descriptions = parse_docstring(docstring)
tool_description = parse_description(docstring) description = parse_description(docstring)
function_descriptions = parse_docstring(docstring)
field_defs = {} field_defs = {}
for name, param in parameters.items(): for name, param in parameters.items():
type_hint = type_hints.get(name, Any) type_hint = type_hints.get(name, Any)
default_value = param.default if param.default is not param.empty else ... default_value = param.default if param.default is not param.empty else ...
description = descriptions.get(name, None)
if not description: description = function_descriptions.get(name, None)
if description:
field_defs[name] = type_hint, Field(default_value, description=description)
else:
field_defs[name] = type_hint, default_value field_defs[name] = type_hint, default_value
continue
field_defs[name] = type_hint, Field(default_value, description=description)
model = create_model(func.__name__, **field_defs) model = create_model(func.__name__, **field_defs)
model.__doc__ = tool_description model.__doc__ = description
return model return model
def get_callable_attributes(tool: object) -> list[Callable]: def get_functions_from_tool(tool: object) -> list[Callable]:
return [ return [
getattr(tool, func) getattr(tool, func)
for func in dir(tool) for func in dir(tool)
if callable(getattr(tool, func)) if callable(
and not func.startswith("__") getattr(tool, func)
and not inspect.isclass(getattr(tool, func)) ) # checks if the attribute is callable (a method or function).
and not func.startswith(
"__"
) # filters out special (dunder) methods like init, str, etc. — these are usually built-in functions of an object that you might not need to use directly.
and not inspect.isclass(
getattr(tool, func)
) # ensures that the callable is not a class itself, just a method or function.
] ]
def get_tools_specs(tool_class: object) -> list[dict]: def get_tool_specs(tool_module: object) -> list[dict]:
function_model_list = map( function_models = map(
function_to_pydantic_model, get_callable_attributes(tool_class) convert_function_to_pydantic_model, get_functions_from_tool(tool_module)
) )
return [
convert_to_openai_function(function_model) specs = [
for function_model in function_model_list convert_pydantic_model_to_openai_function_spec(function_model)
for function_model in function_models
] ]
return specs
def resolve_schema(schema, components): def resolve_schema(schema, components):
""" """
@ -393,14 +430,21 @@ async def get_tool_server_data(token: str, url: str) -> Dict[str, Any]:
error = None error = None
try: try:
async with aiohttp.ClientSession() as session: timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get(url, headers=headers) as response: async with session.get(url, headers=headers) as response:
if response.status != 200: if response.status != 200:
error_body = await response.json() error_body = await response.json()
raise Exception(error_body) raise Exception(error_body)
res = await response.json()
# Check if URL ends with .yaml or .yml to determine format
if url.lower().endswith((".yaml", ".yml")):
text_content = await response.text()
res = yaml.safe_load(text_content)
else:
res = await response.json()
except Exception as err: except Exception as err:
print("Error:", err) log.exception(f"Could not fetch tool server spec from {url}")
if isinstance(err, dict) and "detail" in err: if isinstance(err, dict) and "detail" in err:
error = err["detail"] error = err["detail"]
else: else:

View File

@ -18,7 +18,7 @@ alembic==1.14.0
peewee==3.17.9 peewee==3.17.9
peewee-migrate==1.12.2 peewee-migrate==1.12.2
psycopg2-binary==2.9.9 psycopg2-binary==2.9.9
pgvector==0.3.5 pgvector==0.4.0
PyMySQL==1.1.1 PyMySQL==1.1.1
bcrypt==4.3.0 bcrypt==4.3.0
@ -44,7 +44,7 @@ langchain==0.3.19
langchain-community==0.3.18 langchain-community==0.3.18
fake-useragent==2.1.0 fake-useragent==2.1.0
chromadb==0.6.2 chromadb==0.6.3
pymilvus==2.5.0 pymilvus==2.5.0
qdrant-client~=1.12.0 qdrant-client~=1.12.0
opensearch-py==2.8.0 opensearch-py==2.8.0
@ -93,12 +93,12 @@ authlib==1.4.1
black==25.1.0 black==25.1.0
langfuse==2.44.0 langfuse==2.44.0
youtube-transcript-api==0.6.3 youtube-transcript-api==1.0.3
pytube==15.0.0 pytube==15.0.0
extract_msg extract_msg
pydub pydub
duckduckgo-search~=7.3.2 duckduckgo-search~=8.0.0
## Google Drive ## Google Drive
google-api-python-client google-api-python-client
@ -113,7 +113,7 @@ pytest-docker~=3.1.1
googleapis-common-protos==1.63.2 googleapis-common-protos==1.63.2
google-cloud-storage==2.19.0 google-cloud-storage==2.19.0
azure-identity==1.20.0 azure-identity==1.21.0
azure-storage-blob==12.24.1 azure-storage-blob==12.24.1
@ -123,15 +123,18 @@ ldap3==2.9.1
## Firecrawl ## Firecrawl
firecrawl-py==1.12.0 firecrawl-py==1.12.0
# Sougou API SDK(Tencentcloud SDK)
tencentcloud-sdk-python==3.0.1336
## Trace ## Trace
opentelemetry-api==1.30.0 opentelemetry-api==1.31.1
opentelemetry-sdk==1.30.0 opentelemetry-sdk==1.31.1
opentelemetry-exporter-otlp==1.30.0 opentelemetry-exporter-otlp==1.31.1
opentelemetry-instrumentation==0.51b0 opentelemetry-instrumentation==0.52b1
opentelemetry-instrumentation-fastapi==0.51b0 opentelemetry-instrumentation-fastapi==0.52b1
opentelemetry-instrumentation-sqlalchemy==0.51b0 opentelemetry-instrumentation-sqlalchemy==0.52b1
opentelemetry-instrumentation-redis==0.51b0 opentelemetry-instrumentation-redis==0.52b1
opentelemetry-instrumentation-requests==0.51b0 opentelemetry-instrumentation-requests==0.52b1
opentelemetry-instrumentation-logging==0.51b0 opentelemetry-instrumentation-logging==0.52b1
opentelemetry-instrumentation-httpx==0.51b0 opentelemetry-instrumentation-httpx==0.52b1
opentelemetry-instrumentation-aiohttp-client==0.51b0 opentelemetry-instrumentation-aiohttp-client==0.52b1

View File

@ -65,4 +65,4 @@ if [ -n "$SPACE_ID" ]; then
export WEBUI_URL=${SPACE_HOST} export WEBUI_URL=${SPACE_HOST}
fi fi
WEBUI_SECRET_KEY="$WEBUI_SECRET_KEY" exec uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips '*' WEBUI_SECRET_KEY="$WEBUI_SECRET_KEY" exec uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips '*' --workers "${UVICORN_WORKERS:-1}"

View File

@ -41,5 +41,6 @@ IF "%WEBUI_SECRET_KEY%%WEBUI_JWT_SECRET_KEY%" == " " (
:: Execute uvicorn :: Execute uvicorn
SET "WEBUI_SECRET_KEY=%WEBUI_SECRET_KEY%" SET "WEBUI_SECRET_KEY=%WEBUI_SECRET_KEY%"
uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' --ws auto IF "%UVICORN_WORKERS%"=="" SET UVICORN_WORKERS=1
uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' --workers %UVICORN_WORKERS% --ws auto
:: For ssl user uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' --ssl-keyfile "key.pem" --ssl-certfile "cert.pem" --ws auto :: For ssl user uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' --ssl-keyfile "key.pem" --ssl-certfile "cert.pem" --ws auto

86
package-lock.json generated
View File

@ -23,12 +23,13 @@
"@tiptap/extension-highlight": "^2.10.0", "@tiptap/extension-highlight": "^2.10.0",
"@tiptap/extension-placeholder": "^2.10.0", "@tiptap/extension-placeholder": "^2.10.0",
"@tiptap/extension-typography": "^2.10.0", "@tiptap/extension-typography": "^2.10.0",
"@tiptap/pm": "^2.10.0", "@tiptap/pm": "^2.11.7",
"@tiptap/starter-kit": "^2.10.0", "@tiptap/starter-kit": "^2.10.0",
"@xyflow/svelte": "^0.1.19", "@xyflow/svelte": "^0.1.19",
"async": "^3.2.5", "async": "^3.2.5",
"bits-ui": "^0.19.7", "bits-ui": "^0.19.7",
"codemirror": "^6.0.1", "codemirror": "^6.0.1",
"codemirror-lang-elixir": "^4.0.0",
"codemirror-lang-hcl": "^0.0.0-beta.2", "codemirror-lang-hcl": "^0.0.0-beta.2",
"crc-32": "^1.2.2", "crc-32": "^1.2.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
@ -69,7 +70,8 @@
"turndown": "^7.2.0", "turndown": "^7.2.0",
"undici": "^7.3.0", "undici": "^7.3.0",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"vite-plugin-static-copy": "^2.2.0" "vite-plugin-static-copy": "^2.2.0",
"yaml": "^2.7.1"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "3.2.2", "@sveltejs/adapter-auto": "3.2.2",
@ -3042,9 +3044,9 @@
} }
}, },
"node_modules/@tiptap/pm": { "node_modules/@tiptap/pm": {
"version": "2.10.0", "version": "2.11.7",
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.10.0.tgz", "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.11.7.tgz",
"integrity": "sha512-ohshlWf4MlW6D3rQkNQnhmiQ2w4pwRoQcJmTPt8UJoIDGkeKmZh494fQp4Aeh80XuGd81SsCv//1HJeyaeHJYQ==", "integrity": "sha512-7gEEfz2Q6bYKXM07vzLUD0vqXFhC5geWRA6LCozTiLdVFDdHWiBrvb2rtkL5T7mfLq03zc1QhH7rI3F6VntOEA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"prosemirror-changeset": "^2.2.1", "prosemirror-changeset": "^2.2.1",
@ -3061,10 +3063,10 @@
"prosemirror-schema-basic": "^1.2.3", "prosemirror-schema-basic": "^1.2.3",
"prosemirror-schema-list": "^1.4.1", "prosemirror-schema-list": "^1.4.1",
"prosemirror-state": "^1.4.3", "prosemirror-state": "^1.4.3",
"prosemirror-tables": "^1.6.1", "prosemirror-tables": "^1.6.4",
"prosemirror-trailing-node": "^3.0.0", "prosemirror-trailing-node": "^3.0.0",
"prosemirror-transform": "^1.10.2", "prosemirror-transform": "^1.10.2",
"prosemirror-view": "^1.36.0" "prosemirror-view": "^1.37.0"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@ -4625,6 +4627,15 @@
"@codemirror/view": "^6.0.0" "@codemirror/view": "^6.0.0"
} }
}, },
"node_modules/codemirror-lang-elixir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/codemirror-lang-elixir/-/codemirror-lang-elixir-4.0.0.tgz",
"integrity": "sha512-mzFesxo/t6KOxwnkqVd34R/q7yk+sMtHh6vUKGAvjwHmpL7bERHB+vQAsmU/nqrndkwVeJEHWGw/z/ybfdiudA==",
"dependencies": {
"@codemirror/language": "^6.0.0",
"lezer-elixir": "^1.0.0"
}
},
"node_modules/codemirror-lang-hcl": { "node_modules/codemirror-lang-hcl": {
"version": "0.0.0-beta.2", "version": "0.0.0-beta.2",
"resolved": "https://registry.npmjs.org/codemirror-lang-hcl/-/codemirror-lang-hcl-0.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/codemirror-lang-hcl/-/codemirror-lang-hcl-0.0.0-beta.2.tgz",
@ -7611,6 +7622,15 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/lezer-elixir": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/lezer-elixir/-/lezer-elixir-1.1.2.tgz",
"integrity": "sha512-K3yPMJcNhqCL6ugr5NkgOC1g37rcOM38XZezO9lBXy0LwWFd8zdWXfmRbY829vZVk0OGCQoI02yDWp9FF2OWZA==",
"dependencies": {
"@lezer/highlight": "^1.2.0",
"@lezer/lr": "^1.3.0"
}
},
"node_modules/lightningcss": { "node_modules/lightningcss": {
"version": "1.29.1", "version": "1.29.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz",
@ -9495,6 +9515,16 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/postcss-load-config/node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">= 6"
}
},
"node_modules/postcss-safe-parser": { "node_modules/postcss-safe-parser": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
@ -9783,9 +9813,10 @@
} }
}, },
"node_modules/prosemirror-model": { "node_modules/prosemirror-model": {
"version": "1.23.0", "version": "1.25.0",
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.23.0.tgz", "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.0.tgz",
"integrity": "sha512-Q/fgsgl/dlOAW9ILu4OOhYWQbc7TQd4BwKH/RwmUjyVf8682Be4zj3rOYdLnYEcGzyg8LL9Q5IWYKD8tdToreQ==", "integrity": "sha512-/8XUmxWf0pkj2BmtqZHYJipTBMHIdVjuvFzMvEoxrtyGNmfvdhBiRwYt/eFwy2wA9DtBW3RLqvZnjurEkHaFCw==",
"license": "MIT",
"dependencies": { "dependencies": {
"orderedmap": "^2.0.0" "orderedmap": "^2.0.0"
} }
@ -9819,16 +9850,16 @@
} }
}, },
"node_modules/prosemirror-tables": { "node_modules/prosemirror-tables": {
"version": "1.6.1", "version": "1.6.4",
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.1.tgz", "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.4.tgz",
"integrity": "sha512-p8WRJNA96jaNQjhJolmbxTzd6M4huRE5xQ8OxjvMhQUP0Nzpo4zz6TztEiwk6aoqGBhz9lxRWR1yRZLlpQN98w==", "integrity": "sha512-TkDY3Gw52gRFRfRn2f4wJv5WOgAOXLJA2CQJYIJ5+kdFbfj3acR4JUW6LX2e1hiEBiUwvEhzH5a3cZ5YSztpIA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"prosemirror-keymap": "^1.1.2", "prosemirror-keymap": "^1.2.2",
"prosemirror-model": "^1.8.1", "prosemirror-model": "^1.24.1",
"prosemirror-state": "^1.3.1", "prosemirror-state": "^1.4.3",
"prosemirror-transform": "^1.2.1", "prosemirror-transform": "^1.10.2",
"prosemirror-view": "^1.13.3" "prosemirror-view": "^1.37.2"
} }
}, },
"node_modules/prosemirror-trailing-node": { "node_modules/prosemirror-trailing-node": {
@ -9856,9 +9887,9 @@
} }
}, },
"node_modules/prosemirror-view": { "node_modules/prosemirror-view": {
"version": "1.36.0", "version": "1.39.1",
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.36.0.tgz", "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.39.1.tgz",
"integrity": "sha512-U0GQd5yFvV5qUtT41X1zCQfbw14vkbbKwLlQXhdylEmgpYVHkefXYcC4HHwWOfZa3x6Y8wxDLUBv7dxN5XQ3nA==", "integrity": "sha512-GhLxH1xwnqa5VjhJ29LfcQITNDp+f1jzmMPXQfGW9oNrF0lfjPzKvV5y/bjIQkyKpwCX3Fp+GA4dBpMMk8g+ZQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"prosemirror-model": "^1.20.0", "prosemirror-model": "^1.20.0",
@ -13011,12 +13042,15 @@
} }
}, },
"node_modules/yaml": { "node_modules/yaml": {
"version": "1.10.2", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
"dev": true, "license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": { "engines": {
"node": ">= 6" "node": ">= 14"
} }
}, },
"node_modules/yauzl": { "node_modules/yauzl": {

View File

@ -66,13 +66,14 @@
"@tiptap/extension-highlight": "^2.10.0", "@tiptap/extension-highlight": "^2.10.0",
"@tiptap/extension-placeholder": "^2.10.0", "@tiptap/extension-placeholder": "^2.10.0",
"@tiptap/extension-typography": "^2.10.0", "@tiptap/extension-typography": "^2.10.0",
"@tiptap/pm": "^2.10.0", "@tiptap/pm": "^2.11.7",
"@tiptap/starter-kit": "^2.10.0", "@tiptap/starter-kit": "^2.10.0",
"@xyflow/svelte": "^0.1.19", "@xyflow/svelte": "^0.1.19",
"async": "^3.2.5", "async": "^3.2.5",
"bits-ui": "^0.19.7", "bits-ui": "^0.19.7",
"codemirror": "^6.0.1", "codemirror": "^6.0.1",
"codemirror-lang-hcl": "^0.0.0-beta.2", "codemirror-lang-hcl": "^0.0.0-beta.2",
"codemirror-lang-elixir": "^4.0.0",
"crc-32": "^1.2.2", "crc-32": "^1.2.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"dompurify": "^3.1.6", "dompurify": "^3.1.6",
@ -112,7 +113,8 @@
"turndown": "^7.2.0", "turndown": "^7.2.0",
"undici": "^7.3.0", "undici": "^7.3.0",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"vite-plugin-static-copy": "^2.2.0" "vite-plugin-static-copy": "^2.2.0",
"yaml": "^2.7.1"
}, },
"engines": { "engines": {
"node": ">=18.13.0 <=22.x.x", "node": ">=18.13.0 <=22.x.x",

View File

@ -104,7 +104,7 @@ dependencies = [
"extract_msg", "extract_msg",
"pydub", "pydub",
"duckduckgo-search~=7.3.2", "duckduckgo-search~=8.0.0",
"google-api-python-client", "google-api-python-client",
"google-auth-httplib2", "google-auth-httplib2",
@ -125,6 +125,8 @@ dependencies = [
"firecrawl-py==1.12.0", "firecrawl-py==1.12.0",
"tencentcloud-sdk-python==3.0.1336",
"gcp-storage-emulator>=2024.8.3", "gcp-storage-emulator>=2024.8.3",
] ]
readme = "README.md" readme = "README.md"

View File

@ -91,10 +91,6 @@ textarea::placeholder {
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
} }
iframe {
@apply rounded-lg;
}
li p { li p {
display: inline; display: inline;
} }

View File

@ -9,7 +9,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="Open WebUI" /> <meta name="apple-mobile-web-app-title" content="Open WebUI" />
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover"

View File

@ -2,6 +2,7 @@ import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { convertOpenApiToToolPayload } from '$lib/utils'; import { convertOpenApiToToolPayload } from '$lib/utils';
import { getOpenAIModelsDirect } from './openai'; import { getOpenAIModelsDirect } from './openai';
import { parse } from 'yaml';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
export const getModels = async ( export const getModels = async (
@ -271,8 +272,15 @@ export const getToolServerData = async (token: string, url: string) => {
} }
}) })
.then(async (res) => { .then(async (res) => {
if (!res.ok) throw await res.json(); // Check if URL ends with .yaml or .yml to determine format
return res.json(); if (url.toLowerCase().endsWith('.yaml') || url.toLowerCase().endsWith('.yml')) {
if (!res.ok) throw await res.text();
const text = await res.text();
return parse(text);
} else {
if (!res.ok) throw await res.json();
return res.json();
}
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err);
@ -305,7 +313,7 @@ export const getToolServersData = async (i18n, servers: object[]) => {
.filter((server) => server?.config?.enable) .filter((server) => server?.config?.enable)
.map(async (server) => { .map(async (server) => {
const data = await getToolServerData( const data = await getToolServerData(
server?.key, (server?.auth_type ?? 'bearer') === 'bearer' ? server?.key : localStorage.token,
server?.url + '/' + (server?.path ?? 'openapi.json') server?.url + '/' + (server?.path ?? 'openapi.json')
).catch((err) => { ).catch((err) => {
toast.error( toast.error(

View File

@ -345,3 +345,32 @@ export const deleteKnowledgeById = async (token: string, id: string) => {
return res; return res;
}; };
export const reindexKnowledgeFiles = async (token: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/reindex`, {
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();
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};

View File

@ -39,6 +39,9 @@
let STT_ENGINE = ''; let STT_ENGINE = '';
let STT_MODEL = ''; let STT_MODEL = '';
let STT_WHISPER_MODEL = ''; let STT_WHISPER_MODEL = '';
let STT_AZURE_API_KEY = '';
let STT_AZURE_REGION = '';
let STT_AZURE_LOCALES = '';
let STT_DEEPGRAM_API_KEY = ''; let STT_DEEPGRAM_API_KEY = '';
let STT_WHISPER_MODEL_LOADING = false; let STT_WHISPER_MODEL_LOADING = false;
@ -103,12 +106,15 @@
AZURE_SPEECH_OUTPUT_FORMAT: TTS_AZURE_SPEECH_OUTPUT_FORMAT AZURE_SPEECH_OUTPUT_FORMAT: TTS_AZURE_SPEECH_OUTPUT_FORMAT
}, },
stt: { stt: {
OPENAI_API_BASE_URL: STT_OPENAI_API_BASE_URL, OPENAI_API_BASE_URL: STT_OPENAI_API_BASE_URL,
OPENAI_API_KEY: STT_OPENAI_API_KEY, OPENAI_API_KEY: STT_OPENAI_API_KEY,
ENGINE: STT_ENGINE, ENGINE: STT_ENGINE,
MODEL: STT_MODEL, MODEL: STT_MODEL,
WHISPER_MODEL: STT_WHISPER_MODEL, WHISPER_MODEL: STT_WHISPER_MODEL,
DEEPGRAM_API_KEY: STT_DEEPGRAM_API_KEY DEEPGRAM_API_KEY: STT_DEEPGRAM_API_KEY,
AZURE_API_KEY: STT_AZURE_API_KEY,
AZURE_REGION: STT_AZURE_REGION,
AZURE_LOCALES: STT_AZURE_LOCALES
} }
}); });
@ -148,6 +154,9 @@
STT_ENGINE = res.stt.ENGINE; STT_ENGINE = res.stt.ENGINE;
STT_MODEL = res.stt.MODEL; STT_MODEL = res.stt.MODEL;
STT_WHISPER_MODEL = res.stt.WHISPER_MODEL; STT_WHISPER_MODEL = res.stt.WHISPER_MODEL;
STT_AZURE_API_KEY = res.stt.AZURE_API_KEY;
STT_AZURE_REGION = res.stt.AZURE_REGION;
STT_AZURE_LOCALES = res.stt.AZURE_LOCALES;
STT_DEEPGRAM_API_KEY = res.stt.DEEPGRAM_API_KEY; STT_DEEPGRAM_API_KEY = res.stt.DEEPGRAM_API_KEY;
} }
@ -180,7 +189,8 @@
<option value="openai">OpenAI</option> <option value="openai">OpenAI</option>
<option value="web">{$i18n.t('Web API')}</option> <option value="web">{$i18n.t('Web API')}</option>
<option value="deepgram">Deepgram</option> <option value="deepgram">Deepgram</option>
</select> <option value="azure">Azure AI Speech</option>
</select>
</div> </div>
</div> </div>
@ -248,8 +258,35 @@
</a> </a>
</div> </div>
</div> </div>
{:else if STT_ENGINE === 'azure'}
<div>
<div class="mt-1 flex gap-2 mb-1">
<SensitiveInput placeholder={$i18n.t('API Key')} bind:value={STT_AZURE_API_KEY} required />
<input
class="flex-1 w-full rounded-lg py-2 pl-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
placeholder={$i18n.t('Azure Region')}
bind:value={STT_AZURE_REGION}
required
/>
</div>
<hr class="border-gray-100 dark:border-gray-850 my-2" />
<div>
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('Language Locales')}</div>
<div class="flex w-full">
<div class="flex-1">
<input
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
bind:value={STT_AZURE_LOCALES}
placeholder={$i18n.t('e.g., en-US,ja-JP (leave blank for auto-detect)')}
/>
</div>
</div>
</div>
</div>
{:else if STT_ENGINE === ''} {:else if STT_ENGINE === ''}
<div> <div>
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('STT Model')}</div> <div class=" mb-1.5 text-sm font-medium">{$i18n.t('STT Model')}</div>
<div class="flex w-full"> <div class="flex w-full">

View File

@ -13,17 +13,16 @@
updateEmbeddingConfig, updateEmbeddingConfig,
getRerankingConfig, getRerankingConfig,
updateRerankingConfig, updateRerankingConfig,
resetUploadDir,
getRAGConfig, getRAGConfig,
updateRAGConfig updateRAGConfig
} from '$lib/apis/retrieval'; } from '$lib/apis/retrieval';
import { knowledge, models } from '$lib/stores'; import { reindexKnowledgeFiles} from '$lib/apis/knowledge';
import { getKnowledgeBases } from '$lib/apis/knowledge'; import { deleteAllFiles } from '$lib/apis/files';
import { uploadDir, deleteAllFiles, deleteFileById } from '$lib/apis/files';
import ResetUploadDirConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import ResetUploadDirConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ReindexKnowledgeFilesConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import Switch from '$lib/components/common/Switch.svelte'; import Switch from '$lib/components/common/Switch.svelte';
@ -31,12 +30,12 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
let scanDirLoading = false;
let updateEmbeddingModelLoading = false; let updateEmbeddingModelLoading = false;
let updateRerankingModelLoading = false; let updateRerankingModelLoading = false;
let showResetConfirm = false; let showResetConfirm = false;
let showResetUploadDirConfirm = false; let showResetUploadDirConfirm = false;
let showReindexConfirm = false;
let embeddingEngine = ''; let embeddingEngine = '';
let embeddingModel = ''; let embeddingModel = '';
@ -333,6 +332,21 @@
}} }}
/> />
<ReindexKnowledgeFilesConfirmDialog
bind:show={showReindexConfirm}
on:confirm={async () => {
const res = await reindexKnowledgeFiles(localStorage.token).catch((error) => {
toast.error(`${error}`);
return null;
});
if (res) {
toast.success($i18n.t('Success'));
}
}}
/>
<form <form
class="flex flex-col h-full justify-between space-y-3 text-sm" class="flex flex-col h-full justify-between space-y-3 text-sm"
on:submit|preventDefault={() => { on:submit|preventDefault={() => {
@ -950,6 +964,21 @@
</button> </button>
</div> </div>
</div> </div>
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Reindex Knowledge Base Vectors')}
</div>
<div class="flex items-center relative">
<button
class="text-xs"
on:click={() => {
showReindexConfirm = true;
}}
>
{$i18n.t('Reindex')}
</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -30,7 +30,8 @@
'jina', 'jina',
'bing', 'bing',
'exa', 'exa',
'perplexity' 'perplexity',
'sougou'
]; ];
let youtubeLanguage = 'en'; let youtubeLanguage = 'en';
@ -404,6 +405,31 @@
/> />
</div> </div>
</div> </div>
{:else if webConfig.search.engine === 'sougou'}
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Sougou Search API sID')}
</div>
<SensitiveInput
placeholder={$i18n.t('Enter Sougou Search API sID')}
bind:value={webConfig.search.sougou_api_sid}
/>
</div>
</div>
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Sougou Search API SK')}
</div>
<SensitiveInput
placeholder={$i18n.t('Enter Sougou Search API SK')}
bind:value={webConfig.search.sougou_api_sk}
/>
</div>
</div>
{/if} {/if}
{/if} {/if}
@ -481,8 +507,12 @@
<div class="flex items-center relative"> <div class="flex items-center relative">
<Tooltip <Tooltip
content={webConfig.search.trust_env content={webConfig.search.trust_env
? 'Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents' ? $i18n.t(
: 'Use no proxy to fetch page contents.'} 'Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.'
)
: $i18n.t(
'Use no proxy to fetch page contents.'
)}
> >
<Switch bind:state={webConfig.search.trust_env} /> <Switch bind:state={webConfig.search.trust_env} />
</Tooltip> </Tooltip>

View File

@ -401,6 +401,7 @@
if (!$chatId) { if (!$chatId) {
chatIdUnsubscriber = chatId.subscribe(async (value) => { chatIdUnsubscriber = chatId.subscribe(async (value) => {
if (!value) { if (!value) {
await tick(); // Wait for DOM updates
await initNewChat(); await initNewChat();
} }
}); });
@ -1927,7 +1928,7 @@
: ' '} w-full max-w-full flex flex-col" : ' '} w-full max-w-full flex flex-col"
id="chat-container" id="chat-container"
> >
{#if chatIdProp === '' || (!loading && chatIdProp)} {#if !loading}
{#if $settings?.backgroundImageUrl ?? null} {#if $settings?.backgroundImageUrl ?? null}
<div <div
class="absolute {$showSidebar class="absolute {$showSidebar
@ -1941,27 +1942,27 @@
/> />
{/if} {/if}
<Navbar
bind:this={navbarElement}
chat={{
id: $chatId,
chat: {
title: $chatTitle,
models: selectedModels,
system: $settings.system ?? undefined,
params: params,
history: history,
timestamp: Date.now()
}
}}
title={$chatTitle}
bind:selectedModels
shareEnabled={!!history.currentId}
{initNewChat}
/>
<PaneGroup direction="horizontal" class="w-full h-full"> <PaneGroup direction="horizontal" class="w-full h-full">
<Pane defaultSize={50} class="h-full flex w-full relative"> <Pane defaultSize={50} class="h-full flex relative max-w-full flex-col">
<Navbar
bind:this={navbarElement}
chat={{
id: $chatId,
chat: {
title: $chatTitle,
models: selectedModels,
system: $settings.system ?? undefined,
params: params,
history: history,
timestamp: Date.now()
}
}}
title={$chatTitle}
bind:selectedModels
shareEnabled={!!history.currentId}
{initNewChat}
/>
{#if !history.currentId && !$chatId && selectedModels.length <= 1 && ($banners.length > 0 || ($config?.license_metadata?.type ?? null) === 'trial' || (($config?.license_metadata?.seats ?? null) !== null && $config?.user_count > $config?.license_metadata?.seats))} {#if !history.currentId && !$chatId && selectedModels.length <= 1 && ($banners.length > 0 || ($config?.license_metadata?.type ?? null) === 'trial' || (($config?.license_metadata?.seats ?? null) !== null && $config?.user_count > $config?.license_metadata?.seats))}
<div class="absolute top-12 left-0 right-0 w-full z-30"> <div class="absolute top-12 left-0 right-0 w-full z-30">
<div class=" flex flex-col gap-1 w-full"> <div class=" flex flex-col gap-1 w-full">

View File

@ -223,14 +223,14 @@
showControls.set(false); showControls.set(false);
}} }}
collapsible={true} collapsible={true}
class="pt-8" class=" z-10 "
> >
{#if $showControls} {#if $showControls}
<div class="pr-4 pb-8 flex max-h-full min-h-full"> <div class="flex max-h-full min-h-full">
<div <div
class="w-full {($showOverview || $showArtifacts) && !$showCallOverlay class="w-full {($showOverview || $showArtifacts) && !$showCallOverlay
? ' ' ? ' '
: 'px-4 py-4 bg-white dark:shadow-lg dark:bg-gray-850 border border-gray-100 dark:border-gray-850'} rounded-xl z-40 pointer-events-auto overflow-y-auto scrollbar-hidden" : 'px-4 py-4 bg-white dark:shadow-lg dark:bg-gray-850 border border-gray-100 dark:border-gray-850'} z-40 pointer-events-auto overflow-y-auto scrollbar-hidden"
> >
{#if $showCallOverlay} {#if $showCallOverlay}
<div class="w-full h-full flex justify-center"> <div class="w-full h-full flex justify-center">

View File

@ -1033,7 +1033,7 @@
{/if} {/if}
</div> </div>
<div class=" flex justify-between mt-1.5 mb-2.5 mx-0.5 max-w-full" dir="ltr"> <div class=" flex justify-between mt-1 mb-2.5 mx-0.5 max-w-full" dir="ltr">
<div class="ml-1 self-end flex items-center flex-1 max-w-[80%] gap-0.5"> <div class="ml-1 self-end flex items-center flex-1 max-w-[80%] gap-0.5">
<InputMenu <InputMenu
bind:selectedToolIds bind:selectedToolIds
@ -1102,7 +1102,7 @@
</button> </button>
</InputMenu> </InputMenu>
<div class="flex gap-[2px] items-center overflow-x-auto scrollbar-none flex-1"> <div class="flex gap-1 items-center overflow-x-auto scrollbar-none flex-1">
{#if toolServers.length + selectedToolIds.length > 0} {#if toolServers.length + selectedToolIds.length > 0}
<Tooltip <Tooltip
content={$i18n.t('{{COUNT}} Available Tools', { content={$i18n.t('{{COUNT}} Available Tools', {
@ -1132,10 +1132,10 @@
<button <button
on:click|preventDefault={() => (webSearchEnabled = !webSearchEnabled)} on:click|preventDefault={() => (webSearchEnabled = !webSearchEnabled)}
type="button" type="button"
class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden {webSearchEnabled || class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden border {webSearchEnabled ||
($settings?.webSearch ?? false) === 'always' ($settings?.webSearch ?? false) === 'always'
? 'bg-blue-100 dark:bg-blue-500/20 text-blue-500 dark:text-blue-400' ? 'bg-blue-100 dark:bg-blue-500/20 border-blue-400/20 text-blue-500 dark:text-blue-400'
: 'bg-transparent text-gray-600 dark:text-gray-300 border-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800'}" : 'bg-transparent border-transparent text-gray-600 dark:text-gray-300 border-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800'}"
> >
<GlobeAlt className="size-5" strokeWidth="1.75" /> <GlobeAlt className="size-5" strokeWidth="1.75" />
<span <span
@ -1152,9 +1152,9 @@
on:click|preventDefault={() => on:click|preventDefault={() =>
(imageGenerationEnabled = !imageGenerationEnabled)} (imageGenerationEnabled = !imageGenerationEnabled)}
type="button" type="button"
class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden {imageGenerationEnabled class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden border {imageGenerationEnabled
? 'bg-gray-100 dark:bg-gray-500/20 text-gray-600 dark:text-gray-400' ? 'bg-gray-50 dark:bg-gray-400/10 border-gray-100 dark:border-gray-700 text-gray-600 dark:text-gray-400'
: 'bg-transparent text-gray-600 dark:text-gray-300 border-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 '}" : 'bg-transparent border-transparent text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 '}"
> >
<Photo className="size-5" strokeWidth="1.75" /> <Photo className="size-5" strokeWidth="1.75" />
<span <span
@ -1171,9 +1171,9 @@
on:click|preventDefault={() => on:click|preventDefault={() =>
(codeInterpreterEnabled = !codeInterpreterEnabled)} (codeInterpreterEnabled = !codeInterpreterEnabled)}
type="button" type="button"
class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden {codeInterpreterEnabled class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden border {codeInterpreterEnabled
? 'bg-gray-100 dark:bg-gray-500/20 text-gray-600 dark:text-gray-400' ? 'bg-gray-50 dark:bg-gray-400/10 border-gray-100 dark:border-gray-700 text-gray-600 dark:text-gray-400 '
: 'bg-transparent text-gray-600 dark:text-gray-300 border-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 '}" : 'bg-transparent border-transparent text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 '}"
> >
<CommandLine className="size-5" strokeWidth="1.75" /> <CommandLine className="size-5" strokeWidth="1.75" />
<span <span
@ -1242,10 +1242,7 @@
<div class=" flex items-center"> <div class=" flex items-center">
<Tooltip content={$i18n.t('Call')}> <Tooltip content={$i18n.t('Call')}>
<button <button
class=" {webSearchEnabled || class=" bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full p-1.5 self-center"
($settings?.webSearch ?? false) === 'always'
? 'bg-blue-500 text-white hover:bg-blue-400 '
: 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100'} transition rounded-full p-1.5 self-center"
type="button" type="button"
on:click={async () => { on:click={async () => {
if (selectedModels.length > 1) { if (selectedModels.length > 1) {
@ -1311,9 +1308,7 @@
<button <button
id="send-message-button" id="send-message-button"
class="{!(prompt === '' && files.length === 0) class="{!(prompt === '' && files.length === 0)
? webSearchEnabled || ($settings?.webSearch ?? false) === 'always' ? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
? 'bg-blue-500 text-white hover:bg-blue-400 '
: 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center" : 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center"
type="submit" type="submit"
disabled={prompt === '' && files.length === 0} disabled={prompt === '' && files.length === 0}

View File

@ -4,7 +4,7 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
import Markdown from './Markdown.svelte'; import Markdown from './Markdown.svelte';
import { chatId, mobile, showArtifacts, showControls, showOverview } from '$lib/stores'; import { chatId, mobile, settings, showArtifacts, showControls, showOverview } from '$lib/stores';
import FloatingButtons from '../ContentRenderer/FloatingButtons.svelte'; import FloatingButtons from '../ContentRenderer/FloatingButtons.svelte';
import { createMessagesList } from '$lib/utils'; import { createMessagesList } from '$lib/utils';
@ -161,6 +161,7 @@
const { lang, code } = e.detail; const { lang, code } = e.detail;
if ( if (
($settings?.detectArtifacts ?? true) &&
(['html', 'svg'].includes(lang) || (lang === 'xml' && code.includes('svg'))) && (['html', 'svg'].includes(lang) || (lang === 'xml' && code.includes('svg'))) &&
!$mobile && !$mobile &&
$chatId $chatId

View File

@ -192,7 +192,7 @@
<div> <div>
<button <button
id="save-edit-message-button" id="save-edit-message-button"
class=" px-4 py-2 bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 border dark:border-gray-700 text-gray-700 dark:text-gray-200 transition rounded-3xl" class=" px-4 py-2 bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 border border-gray-100 dark:border-gray-700 text-gray-700 dark:text-gray-200 transition rounded-3xl"
on:click={() => { on:click={() => {
editMessageConfirmHandler(false); editMessageConfirmHandler(false);
}} }}

View File

@ -84,47 +84,49 @@
} }
); );
$: filteredItems = searchValue $: filteredItems = (
? fuse searchValue
.search(searchValue) ? fuse
.map((e) => { .search(searchValue)
return e.item; .map((e) => {
}) return e.item;
.filter((item) => { })
if (selectedTag === '') { .filter((item) => {
return true; if (selectedTag === '') {
} return true;
return (item.model?.tags ?? []).map((tag) => tag.name).includes(selectedTag); }
}) return (item.model?.tags ?? []).map((tag) => tag.name).includes(selectedTag);
.filter((item) => { })
if (selectedConnectionType === '') { .filter((item) => {
return true; if (selectedConnectionType === '') {
} else if (selectedConnectionType === 'ollama') { return true;
return item.model?.owned_by === 'ollama'; } else if (selectedConnectionType === 'ollama') {
} else if (selectedConnectionType === 'openai') { return item.model?.owned_by === 'ollama';
return item.model?.owned_by === 'openai'; } else if (selectedConnectionType === 'openai') {
} else if (selectedConnectionType === 'direct') { return item.model?.owned_by === 'openai';
return item.model?.direct; } else if (selectedConnectionType === 'direct') {
} return item.model?.direct;
}) }
: items })
.filter((item) => { : items
if (selectedTag === '') { .filter((item) => {
return true; if (selectedTag === '') {
} return true;
return (item.model?.tags ?? []).map((tag) => tag.name).includes(selectedTag); }
}) return (item.model?.tags ?? []).map((tag) => tag.name).includes(selectedTag);
.filter((item) => { })
if (selectedConnectionType === '') { .filter((item) => {
return true; if (selectedConnectionType === '') {
} else if (selectedConnectionType === 'ollama') { return true;
return item.model?.owned_by === 'ollama'; } else if (selectedConnectionType === 'ollama') {
} else if (selectedConnectionType === 'openai') { return item.model?.owned_by === 'ollama';
return item.model?.owned_by === 'openai'; } else if (selectedConnectionType === 'openai') {
} else if (selectedConnectionType === 'direct') { return item.model?.owned_by === 'openai';
return item.model?.direct; } else if (selectedConnectionType === 'direct') {
} return item.model?.direct;
}); }
})
).filter((item) => !(item.model?.info?.meta?.hidden ?? false));
$: if (selectedTag || selectedConnectionType) { $: if (selectedTag || selectedConnectionType) {
resetView(); resetView();
@ -282,7 +284,10 @@
ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false); ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
if (items) { if (items) {
tags = items.flatMap((item) => item.model?.tags ?? []).map((tag) => tag.name); tags = items
.filter((item) => !(item.model?.info?.meta?.hidden ?? false))
.flatMap((item) => item.model?.tags ?? [])
.map((tag) => tag.name);
// Remove duplicates and sort // Remove duplicates and sort
tags = Array.from(new Set(tags)).sort((a, b) => a.localeCompare(b)); tags = Array.from(new Set(tags)).sort((a, b) => a.localeCompare(b));
@ -373,7 +378,7 @@
</div> </div>
{/if} {/if}
<div class="px-3 mb-2 max-h-64 overflow-y-auto scrollbar-hidden group relative"> <div class="px-3 max-h-64 overflow-y-auto scrollbar-hidden group relative">
{#if tags && items.filter((item) => !(item.model?.info?.meta?.hidden ?? false)).length > 0} {#if tags && items.filter((item) => !(item.model?.info?.meta?.hidden ?? false)).length > 0}
<div <div
class=" flex w-full sticky top-0 z-10 bg-white dark:bg-gray-850 overflow-x-auto scrollbar-none" class=" flex w-full sticky top-0 z-10 bg-white dark:bg-gray-850 overflow-x-auto scrollbar-none"
@ -388,18 +393,20 @@
class="flex gap-1 w-fit text-center text-sm font-medium rounded-full bg-transparent px-1.5 pb-0.5" class="flex gap-1 w-fit text-center text-sm font-medium rounded-full bg-transparent px-1.5 pb-0.5"
bind:this={tagsContainerElement} bind:this={tagsContainerElement}
> >
<button {#if (items.find((item) => item.model?.owned_by === 'ollama') && items.find((item) => item.model?.owned_by === 'openai')) || items.find((item) => item.model?.direct) || tags.length > 0}
class="min-w-fit outline-none p-1.5 {selectedTag === '' && <button
selectedConnectionType === '' class="min-w-fit outline-none p-1.5 {selectedTag === '' &&
? '' selectedConnectionType === ''
: 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize" ? ''
on:click={() => { : 'text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition capitalize"
selectedConnectionType = ''; on:click={() => {
selectedTag = ''; selectedConnectionType = '';
}} selectedTag = '';
> }}
{$i18n.t('All')} >
</button> {$i18n.t('All')}
</button>
{/if}
{#if items.find((item) => item.model?.owned_by === 'ollama') && items.find((item) => item.model?.owned_by === 'openai')} {#if items.find((item) => item.model?.owned_by === 'ollama') && items.find((item) => item.model?.owned_by === 'openai')}
<button <button
@ -457,7 +464,7 @@
</div> </div>
{/if} {/if}
{#each filteredItems.filter((item) => !(item.model?.info?.meta?.hidden ?? false)) as item, index} {#each filteredItems as item, index}
<button <button
aria-label="model-item" aria-label="model-item"
class="flex w-full text-left font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-hidden transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg cursor-pointer data-highlighted:bg-muted {index === class="flex w-full text-left font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-hidden transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg cursor-pointer data-highlighted:bg-muted {index ===
@ -739,9 +746,7 @@
</div> </div>
{#if showTemporaryChatControl} {#if showTemporaryChatControl}
<hr class="border-gray-100 dark:border-gray-800" /> <div class="flex items-center mx-2 mb-2">
<div class="flex items-center mx-2 my-2">
<button <button
class="flex justify-between w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 px-3 text-sm text-gray-700 dark:text-gray-100 outline-hidden transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg cursor-pointer data-highlighted:bg-muted" class="flex justify-between w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 px-3 text-sm text-gray-700 dark:text-gray-100 outline-hidden transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg cursor-pointer data-highlighted:bg-muted"
on:click={async () => { on:click={async () => {

View File

@ -32,6 +32,8 @@
let showUsername = false; let showUsername = false;
let notificationSound = true; let notificationSound = true;
let detectArtifacts = true;
let richTextInput = true; let richTextInput = true;
let promptAutocomplete = false; let promptAutocomplete = false;
@ -176,6 +178,11 @@
saveSettings({ autoTags }); saveSettings({ autoTags });
}; };
const toggleDetectArtifacts = async () => {
detectArtifacts = !detectArtifacts;
saveSettings({ detectArtifacts });
};
const toggleRichTextInput = async () => { const toggleRichTextInput = async () => {
richTextInput = !richTextInput; richTextInput = !richTextInput;
saveSettings({ richTextInput }); saveSettings({ richTextInput });
@ -242,6 +249,7 @@
titleAutoGenerate = $settings?.title?.auto ?? true; titleAutoGenerate = $settings?.title?.auto ?? true;
autoTags = $settings.autoTags ?? true; autoTags = $settings.autoTags ?? true;
detectArtifacts = $settings.detectArtifacts ?? true;
responseAutoCopy = $settings.responseAutoCopy ?? false; responseAutoCopy = $settings.responseAutoCopy ?? false;
showUsername = $settings.showUsername ?? false; showUsername = $settings.showUsername ?? false;
@ -537,6 +545,28 @@
</div> </div>
</div> </div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">
{$i18n.t('Detect Artifacts Automatically')}
</div>
<button
class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => {
toggleDetectArtifacts();
}}
type="button"
>
{#if detectArtifacts === 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"> <div class=" self-center text-xs">

View File

@ -15,7 +15,7 @@
let selectedTools = []; let selectedTools = [];
$: selectedTools = $tools.filter((tool) => selectedToolIds.includes(tool.id)); $: selectedTools = ($tools ?? []).filter((tool) => selectedToolIds.includes(tool.id));
const i18n = getContext('i18n'); const i18n = getContext('i18n');
</script> </script>

View File

@ -98,6 +98,16 @@
} }
}) })
); );
languages.push(
LanguageDescription.of({
name: 'Elixir',
extensions: ['ex', 'exs'],
load() {
return import('codemirror-lang-elixir').then((m) => m.elixir());
}
})
);
const getLang = async () => { const getLang = async () => {
const language = languages.find((l) => l.alias.includes(lang)); const language = languages.find((l) => l.alias.includes(lang));
return await language?.load(); return await language?.load();
@ -232,4 +242,4 @@
}); });
</script> </script>
<div id="code-textarea-{id}" class="h-full w-full" /> <div id="code-textarea-{id}" class="h-full w-full text-sm" />

View File

@ -73,7 +73,7 @@
return JSON.stringify(parsed, null, 2); return JSON.stringify(parsed, null, 2);
} else { } else {
// It's a primitive value like a number, boolean, etc. // It's a primitive value like a number, boolean, etc.
return String(parsed); return `${JSON.stringify(String(parsed))}`;
} }
} catch (e) { } catch (e) {
// Not valid JSON, return as-is // Not valid JSON, return as-is

View File

@ -83,6 +83,8 @@
currentChatPage.set(1); currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage)); await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getPinnedChatList(localStorage.token)); await pinnedChats.set(await getPinnedChatList(localStorage.token));
dispatch('change');
} }
}; };

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "رفض عندما لا ينبغي أن يكون", "Refused when it shouldn't have": "رفض عندما لا ينبغي أن يكون",
"Regenerate": "تجديد", "Regenerate": "تجديد",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "ملاحظات الإصدار", "Release Notes": "ملاحظات الإصدار",
"Relevance": "", "Relevance": "",
"Remove": "إزالة", "Remove": "إزالة",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar أستخدم", "Use Gravatar": "Gravatar أستخدم",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Initials أستخدم", "Use Initials": "Initials أستخدم",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (أولاما)", "use_mlock (Ollama)": "use_mlock (أولاما)",
"use_mmap (Ollama)": "use_mmap (أولاما)", "use_mmap (Ollama)": "use_mmap (أولاما)",
"user": "مستخدم", "user": "مستخدم",

View File

@ -878,6 +878,8 @@
"References from": "مراجع من", "References from": "مراجع من",
"Refused when it shouldn't have": "رفض عندما لا ينبغي أن يكون", "Refused when it shouldn't have": "رفض عندما لا ينبغي أن يكون",
"Regenerate": "تجديد", "Regenerate": "تجديد",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "ملاحظات الإصدار", "Release Notes": "ملاحظات الإصدار",
"Relevance": "الصلة", "Relevance": "الصلة",
"Remove": "إزالة", "Remove": "إزالة",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar أستخدم", "Use Gravatar": "Gravatar أستخدم",
"Use groups to group your users and assign permissions.": "استخدم المجموعات لتجميع المستخدمين وتحديد الصلاحيات.", "Use groups to group your users and assign permissions.": "استخدم المجموعات لتجميع المستخدمين وتحديد الصلاحيات.",
"Use Initials": "Initials أستخدم", "Use Initials": "Initials أستخدم",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (أولاما)", "use_mlock (Ollama)": "use_mlock (أولاما)",
"use_mmap (Ollama)": "use_mmap (أولاما)", "use_mmap (Ollama)": "use_mmap (أولاما)",
"user": "مستخدم", "user": "مستخدم",

View File

@ -878,6 +878,8 @@
"References from": "Препратки от", "References from": "Препратки от",
"Refused when it shouldn't have": "Отказано, когато не трябва да бъде", "Refused when it shouldn't have": "Отказано, когато не трябва да бъде",
"Regenerate": "Регенериране", "Regenerate": "Регенериране",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Бележки по изданието", "Release Notes": "Бележки по изданието",
"Relevance": "Релевантност", "Relevance": "Релевантност",
"Remove": "Изтриване", "Remove": "Изтриване",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Използвайте Gravatar", "Use Gravatar": "Използвайте Gravatar",
"Use groups to group your users and assign permissions.": "Използвайте групи, за да групирате вашите потребители и да присвоите разрешения.", "Use groups to group your users and assign permissions.": "Използвайте групи, за да групирате вашите потребители и да присвоите разрешения.",
"Use Initials": "Използвайте инициали", "Use Initials": "Използвайте инициали",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "потребител", "user": "потребител",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "যদি উপযুক্ত নয়, তবে রেজিগেনেট করা হচ্ছে", "Refused when it shouldn't have": "যদি উপযুক্ত নয়, তবে রেজিগেনেট করা হচ্ছে",
"Regenerate": "রেজিগেনেট করুন", "Regenerate": "রেজিগেনেট করুন",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "রিলিজ নোটসমূহ", "Release Notes": "রিলিজ নোটসমূহ",
"Relevance": "", "Relevance": "",
"Remove": "রিমুভ করুন", "Remove": "রিমুভ করুন",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar ব্যবহার করুন", "Use Gravatar": "Gravatar ব্যবহার করুন",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "নামের আদ্যক্ষর ব্যবহার করুন", "Use Initials": "নামের আদ্যক্ষর ব্যবহার করুন",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (ওলামা)", "use_mlock (Ollama)": "use_mlock (ওলামা)",
"use_mmap (Ollama)": "use_mmap (ওলামা)", "use_mmap (Ollama)": "use_mmap (ওলামা)",
"user": "ব্যবহারকারী", "user": "ব্যবহারকারী",

View File

@ -878,6 +878,8 @@
"References from": "ནས་ལུང་འདྲེན།", "References from": "ནས་ལུང་འདྲེན།",
"Refused when it shouldn't have": "མི་དགོས་དུས་ཁས་མ་བླངས།", "Refused when it shouldn't have": "མི་དགོས་དུས་ཁས་མ་བླངས།",
"Regenerate": "བསྐྱར་བཟོ།", "Regenerate": "བསྐྱར་བཟོ།",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "འགྲེམས་སྤེལ་མཆན་བུ།", "Release Notes": "འགྲེམས་སྤེལ་མཆན་བུ།",
"Relevance": "འབྲེལ་ཡོད་རང་བཞིན།", "Relevance": "འབྲེལ་ཡོད་རང་བཞིན།",
"Remove": "འདོར་བ།", "Remove": "འདོར་བ།",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar བེད་སྤྱོད།", "Use Gravatar": "Gravatar བེད་སྤྱོད།",
"Use groups to group your users and assign permissions.": "ཁྱེད་ཀྱི་བེད་སྤྱོད་མཁན་ཚོགས་པ་བཟོ་བ་དང་དབང་ཚད་སྤྲོད་པར་ཚོགས་པ་བེད་སྤྱོད་གཏོང་བ།", "Use groups to group your users and assign permissions.": "ཁྱེད་ཀྱི་བེད་སྤྱོད་མཁན་ཚོགས་པ་བཟོ་བ་དང་དབང་ཚད་སྤྲོད་པར་ཚོགས་པ་བེད་སྤྱོད་གཏོང་བ།",
"Use Initials": "མིང་གི་ཡིག་འབྲུ་མགོ་མ་བེད་སྤྱོད།", "Use Initials": "མིང་གི་ཡིག་འབྲུ་མགོ་མ་བེད་སྤྱོད།",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "བེད་སྤྱོད་མཁན།", "user": "བེད་སྤྱོད་མཁན།",

View File

@ -6,7 +6,7 @@
"(latest)": "(últim)", "(latest)": "(últim)",
"(Ollama)": "(Ollama)", "(Ollama)": "(Ollama)",
"{{ models }}": "{{ models }}", "{{ models }}": "{{ models }}",
"{{COUNT}} Available Tools": "", "{{COUNT}} Available Tools": "{{COUNT}} eines disponibles",
"{{COUNT}} hidden lines": "{{COUNT}} línies ocultes", "{{COUNT}} hidden lines": "{{COUNT}} línies ocultes",
"{{COUNT}} Replies": "{{COUNT}} respostes", "{{COUNT}} Replies": "{{COUNT}} respostes",
"{{user}}'s Chats": "Els xats de {{user}}", "{{user}}'s Chats": "Els xats de {{user}}",
@ -108,10 +108,10 @@
"Attribute for Username": "Atribut per al Nom d'usuari", "Attribute for Username": "Atribut per al Nom d'usuari",
"Audio": "Àudio", "Audio": "Àudio",
"August": "Agost", "August": "Agost",
"Auth": "", "Auth": "Autenticació",
"Authenticate": "Autenticar", "Authenticate": "Autenticar",
"Authentication": "Autenticació", "Authentication": "Autenticació",
"Auto": "", "Auto": "Automàtic",
"Auto-Copy Response to Clipboard": "Copiar la resposta automàticament al porta-retalls", "Auto-Copy Response to Clipboard": "Copiar la resposta automàticament al porta-retalls",
"Auto-playback response": "Reproduir la resposta automàticament", "Auto-playback response": "Reproduir la resposta automàticament",
"Autocomplete Generation": "Generació automàtica", "Autocomplete Generation": "Generació automàtica",
@ -121,7 +121,7 @@
"AUTOMATIC1111 Base URL": "URL Base d'AUTOMATIC1111", "AUTOMATIC1111 Base URL": "URL Base d'AUTOMATIC1111",
"AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base d'AUTOMATIC1111.", "AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base d'AUTOMATIC1111.",
"Available list": "Llista de disponibles", "Available list": "Llista de disponibles",
"Available Tools": "", "Available Tools": "Eines disponibles",
"available!": "disponible!", "available!": "disponible!",
"Awful": "Terrible", "Awful": "Terrible",
"Azure AI Speech": "Azure AI Speech", "Azure AI Speech": "Azure AI Speech",
@ -220,10 +220,10 @@
"Confirm your new password": "Confirma la teva nova contrasenya", "Confirm your new password": "Confirma la teva nova contrasenya",
"Connect to your own OpenAI compatible API endpoints.": "Connecta als teus propis punts de connexió de l'API compatible amb OpenAI", "Connect to your own OpenAI compatible API endpoints.": "Connecta als teus propis punts de connexió de l'API compatible amb OpenAI",
"Connect to your own OpenAPI compatible external tool servers.": "Connecta als teus propis servidors d'eines externs compatibles amb OpenAPI", "Connect to your own OpenAPI compatible external tool servers.": "Connecta als teus propis servidors d'eines externs compatibles amb OpenAPI",
"Connection failed": "", "Connection failed": "La connexió ha fallat",
"Connection successful": "", "Connection successful": "Connexió correcta",
"Connections": "Connexions", "Connections": "Connexions",
"Connections saved successfully": "", "Connections saved successfully": "Les connexions s'han desat correctament",
"Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Restringeix l'esforç de raonament dels models de raonament. Només aplicable a models de raonament de proveïdors específics que donen suport a l'esforç de raonament.", "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Restringeix l'esforç de raonament dels models de raonament. Només aplicable a models de raonament de proveïdors específics que donen suport a l'esforç de raonament.",
"Contact Admin for WebUI Access": "Posat en contacte amb l'administrador per accedir a WebUI", "Contact Admin for WebUI Access": "Posat en contacte amb l'administrador per accedir a WebUI",
"Content": "Contingut", "Content": "Contingut",
@ -308,7 +308,7 @@
"Direct Connections": "Connexions directes", "Direct Connections": "Connexions directes",
"Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Les connexions directes permeten als usuaris connectar-se als seus propis endpoints d'API compatibles amb OpenAI.", "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Les connexions directes permeten als usuaris connectar-se als seus propis endpoints d'API compatibles amb OpenAI.",
"Direct Connections settings updated": "Configuració de les connexions directes actualitzada", "Direct Connections settings updated": "Configuració de les connexions directes actualitzada",
"Direct Tool Servers": "", "Direct Tool Servers": "Servidors d'eines directes",
"Disabled": "Deshabilitat", "Disabled": "Deshabilitat",
"Discover a function": "Descobrir una funció", "Discover a function": "Descobrir una funció",
"Discover a model": "Descobrir un model", "Discover a model": "Descobrir un model",
@ -385,7 +385,7 @@
"Enable Mirostat sampling for controlling perplexity.": "Permetre el mostreig de Mirostat per controlar la perplexitat", "Enable Mirostat sampling for controlling perplexity.": "Permetre el mostreig de Mirostat per controlar la perplexitat",
"Enable New Sign Ups": "Permetre nous registres", "Enable New Sign Ups": "Permetre nous registres",
"Enabled": "Habilitat", "Enabled": "Habilitat",
"Enforce Temporary Chat": "", "Enforce Temporary Chat": "Forçar els xats temporals",
"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.", "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 què els teus models de llenguatge puguin recordar", "Enter a detail about yourself for your LLMs to recall": "Introdueix un detall sobre tu què els teus models de llenguatge puguin recordar",
@ -418,7 +418,7 @@
"Enter Kagi Search API Key": "Introdueix la clau API de Kagi Search", "Enter Kagi Search API Key": "Introdueix la clau API de Kagi Search",
"Enter Key Behavior": "Introdueix el comportament de clau", "Enter Key Behavior": "Introdueix el comportament de clau",
"Enter language codes": "Introdueix els codis de llenguatge", "Enter language codes": "Introdueix els codis de llenguatge",
"Enter Mistral API Key": "", "Enter Mistral API Key": "Entra la clau API de Mistral",
"Enter Model ID": "Introdueix l'identificador del model", "Enter Model ID": "Introdueix l'identificador del model",
"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 Mojeek Search API Key": "Introdueix la clau API de Mojeek Search", "Enter Mojeek Search API Key": "Introdueix la clau API de Mojeek Search",
@ -443,7 +443,7 @@
"Enter server port": "Introdueix el port del servidor", "Enter server port": "Introdueix el port del servidor",
"Enter stop sequence": "Introdueix la seqüència de parada", "Enter stop sequence": "Introdueix la seqüència de parada",
"Enter system prompt": "Introdueix la indicació de sistema", "Enter system prompt": "Introdueix la indicació de sistema",
"Enter system prompt here": "", "Enter system prompt here": "Entra la indicació de sistema aquí",
"Enter Tavily API Key": "Introdueix la clau API de Tavily", "Enter Tavily API Key": "Introdueix la clau API de Tavily",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Entra la URL pública de WebUI. Aquesta URL s'utilitzarà per generar els enllaços en les notificacions.", "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Entra la URL pública de WebUI. Aquesta URL s'utilitzarà per generar els enllaços en les notificacions.",
"Enter Tika Server URL": "Introdueix l'URL del servidor Tika", "Enter Tika Server URL": "Introdueix l'URL del servidor Tika",
@ -457,7 +457,7 @@
"Enter Your Email": "Introdueix el teu correu electrònic", "Enter Your Email": "Introdueix el teu correu electrònic",
"Enter Your Full Name": "Introdueix el teu nom complet", "Enter Your Full Name": "Introdueix el teu nom complet",
"Enter your message": "Introdueix el teu missatge", "Enter your message": "Introdueix el teu missatge",
"Enter your name": "", "Enter your name": "Entra el teu nom",
"Enter your new password": "Introdueix la teva nova contrasenya", "Enter your new password": "Introdueix la teva nova contrasenya",
"Enter Your Password": "Introdueix la teva contrasenya", "Enter Your Password": "Introdueix la teva contrasenya",
"Enter Your Role": "Introdueix el teu rol", "Enter Your Role": "Introdueix el teu rol",
@ -477,7 +477,7 @@
"Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "S'ha superat el nombre de places a la vostra llicència. Poseu-vos en contacte amb el servei d'assistència per augmentar el nombre de places.", "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "S'ha superat el nombre de places a la vostra llicència. Poseu-vos en contacte amb el servei d'assistència per augmentar el nombre de places.",
"Exclude": "Excloure", "Exclude": "Excloure",
"Execute code for analysis": "Executar el codi per analitzar-lo", "Execute code for analysis": "Executar el codi per analitzar-lo",
"Executing **{{NAME}}**...": "", "Executing **{{NAME}}**...": "Executant **{{NAME}}**...",
"Expand": "Expandir", "Expand": "Expandir",
"Experimental": "Experimental", "Experimental": "Experimental",
"Explain": "Explicar", "Explain": "Explicar",
@ -502,7 +502,7 @@
"Failed to create API Key.": "No s'ha pogut crear la clau API.", "Failed to create API Key.": "No s'ha pogut crear la clau API.",
"Failed to fetch models": "No s'han pogut obtenir els models", "Failed to fetch models": "No s'han pogut obtenir els models",
"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 save connections": "", "Failed to save connections": "No s'han pogut desar les connexions",
"Failed to save models configuration": "No s'ha pogut desar la configuració dels models", "Failed to save models configuration": "No s'ha pogut desar la configuració dels models",
"Failed to update settings": "No s'han pogut actualitzar les preferències", "Failed to update settings": "No s'han pogut actualitzar les preferències",
"Failed to upload file.": "No s'ha pogut pujar l'arxiu.", "Failed to upload file.": "No s'ha pogut pujar l'arxiu.",
@ -535,7 +535,7 @@
"Forge new paths": "Crea nous camins", "Forge new paths": "Crea nous camins",
"Form": "Formulari", "Form": "Formulari",
"Format your variables using brackets like this:": "Formata les teves variables utilitzant claudàtors així:", "Format your variables using brackets like this:": "Formata les teves variables utilitzant claudàtors així:",
"Forwards system user session credentials to authenticate": "", "Forwards system user session credentials to authenticate": "Envia les credencials de l'usuari del sistema per autenticar",
"Frequency Penalty": "Penalització per freqüència", "Frequency Penalty": "Penalització per freqüència",
"Full Context Mode": "Mode de context complert", "Full Context Mode": "Mode de context complert",
"Function": "Funció", "Function": "Funció",
@ -581,7 +581,7 @@
"Hex Color": "Color hexadecimal", "Hex Color": "Color hexadecimal",
"Hex Color - Leave empty for default color": "Color hexadecimal - Deixar buit per a color per defecte", "Hex Color - Leave empty for default color": "Color hexadecimal - Deixar buit per a color per defecte",
"Hide": "Amaga", "Hide": "Amaga",
"Hide Model": "", "Hide Model": "Amagar el model",
"Home": "Inici", "Home": "Inici",
"Host": "Servidor", "Host": "Servidor",
"How can I help you today?": "Com et puc ajudar avui?", "How can I help you today?": "Com et puc ajudar avui?",
@ -641,7 +641,7 @@
"Knowledge Access": "Accés al coneixement", "Knowledge Access": "Accés al coneixement",
"Knowledge created successfully.": "Coneixement creat correctament.", "Knowledge created successfully.": "Coneixement creat correctament.",
"Knowledge deleted successfully.": "Coneixement eliminat correctament.", "Knowledge deleted successfully.": "Coneixement eliminat correctament.",
"Knowledge Public Sharing": "", "Knowledge Public Sharing": "Compartir públicament el Coneixement",
"Knowledge reset successfully.": "Coneixement restablert correctament.", "Knowledge reset successfully.": "Coneixement restablert correctament.",
"Knowledge updated successfully": "Coneixement actualitzat correctament.", "Knowledge updated successfully": "Coneixement actualitzat correctament.",
"Kokoro.js (Browser)": "Kokoro.js (Navegador)", "Kokoro.js (Browser)": "Kokoro.js (Navegador)",
@ -655,7 +655,7 @@
"LDAP": "LDAP", "LDAP": "LDAP",
"LDAP server updated": "Servidor LDAP actualitzat", "LDAP server updated": "Servidor LDAP actualitzat",
"Leaderboard": "Tauler de classificació", "Leaderboard": "Tauler de classificació",
"Learn more about OpenAPI tool servers.": "", "Learn more about OpenAPI tool servers.": "Aprèn més sobre els servidors d'eines OpenAPI",
"Leave empty for unlimited": "Deixar-ho buit per il·limitat", "Leave empty for unlimited": "Deixar-ho buit per il·limitat",
"Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/api/tags\"", "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/api/tags\"",
"Leave empty to include all models from \"{{url}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/models\"", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/models\"",
@ -706,16 +706,16 @@
"Mirostat": "Mirostat", "Mirostat": "Mirostat",
"Mirostat Eta": "Eta de Mirostat", "Mirostat Eta": "Eta de Mirostat",
"Mirostat Tau": "Tau de Mirostat", "Mirostat Tau": "Tau de Mirostat",
"Mistral OCR": "", "Mistral OCR": "Mistral OCR",
"Mistral OCR API Key required.": "", "Mistral OCR API Key required.": "És necessària la clau API de Mistral OCR",
"Model": "Model", "Model": "Model",
"Model '{{modelName}}' has been successfully downloaded.": "El model '{{modelName}}' s'ha descarregat correctament.", "Model '{{modelName}}' has been successfully downloaded.": "El model '{{modelName}}' s'ha descarregat correctament.",
"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": "No s'ha trobat el model {{modelId}}", "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 {{name}} ara és {{status}}", "Model {{name}} is now {{status}}": "El model {{name}} ara és {{status}}",
"Model {{name}} is now hidden": "", "Model {{name}} is now hidden": "El model {{name}} està ara amagat",
"Model {{name}} is now visible": "", "Model {{name}} is now visible": "El model {{name}} està ara visible",
"Model accepts image inputs": "El model accepta entrades d'imatge", "Model accepts image inputs": "El model accepta entrades d'imatge",
"Model created successfully!": "Model creat correctament", "Model created successfully!": "Model creat correctament",
"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 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.",
@ -731,7 +731,7 @@
"Models": "Models", "Models": "Models",
"Models Access": "Accés als models", "Models Access": "Accés als models",
"Models configuration saved successfully": "La configuració dels models s'ha desat correctament", "Models configuration saved successfully": "La configuració dels models s'ha desat correctament",
"Models Public Sharing": "", "Models Public Sharing": "Compartició pública de models",
"Mojeek Search API Key": "Clau API de Mojeek Search", "Mojeek Search API Key": "Clau API de Mojeek Search",
"more": "més", "more": "més",
"More": "Més", "More": "Més",
@ -794,7 +794,7 @@
"Open file": "Obrir arxiu", "Open file": "Obrir arxiu",
"Open in full screen": "Obrir en pantalla complerta", "Open in full screen": "Obrir en pantalla complerta",
"Open new chat": "Obre un xat nou", "Open new chat": "Obre un xat nou",
"Open WebUI can use tools provided by any OpenAPI server.": "", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI pot utilitzar eines de servidors OpenAPI.",
"Open WebUI uses faster-whisper internally.": "Open WebUI utilitza faster-whisper internament.", "Open WebUI uses faster-whisper internally.": "Open WebUI utilitza faster-whisper internament.",
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI utilitza incrustacions de SpeechT5 i CMU Arctic.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI utilitza incrustacions de SpeechT5 i CMU Arctic.",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versió d'Open WebUI (v{{OPEN_WEBUI_VERSION}}) és inferior a la versió requerida (v{{REQUIRED_VERSION}})", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versió d'Open WebUI (v{{OPEN_WEBUI_VERSION}}) és inferior a la versió requerida (v{{REQUIRED_VERSION}})",
@ -804,7 +804,7 @@
"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 API settings updated": "Configuració de l'API d'OpenAI actualitzada", "OpenAI API settings updated": "Configuració de l'API d'OpenAI actualitzada",
"OpenAI URL/Key required.": "URL/Clau d'OpenAI requerides.", "OpenAI URL/Key required.": "URL/Clau d'OpenAI requerides.",
"openapi.json Path": "", "openapi.json Path": "openapi.json",
"or": "o", "or": "o",
"Organize your users": "Organitza els teus usuaris", "Organize your users": "Organitza els teus usuaris",
"Other": "Altres", "Other": "Altres",
@ -836,8 +836,8 @@
"Please carefully review the following warnings:": "Si us plau, revisa els següents avisos amb cura:", "Please carefully review the following warnings:": "Si us plau, revisa els següents avisos amb cura:",
"Please do not close the settings page while loading the model.": "No tanquis la pàgina de configuració mentre carregues el model.", "Please do not close the settings page while loading the model.": "No tanquis la pàgina de configuració mentre carregues el model.",
"Please enter a prompt": "Si us plau, entra una indicació", "Please enter a prompt": "Si us plau, entra una indicació",
"Please enter a valid path": "", "Please enter a valid path": "Si us plau, entra un camí vàlid",
"Please enter a valid URL": "", "Please enter a valid URL": "Si us plau, entra una URL vàlida",
"Please fill in all fields.": "Emplena tots els camps, si us plau.", "Please fill in all fields.": "Emplena tots els camps, si us plau.",
"Please select a model first.": "Si us plau, selecciona un model primer", "Please select a model first.": "Si us plau, selecciona un model primer",
"Please select a model.": "Si us plau, selecciona un model.", "Please select a model.": "Si us plau, selecciona un model.",
@ -853,14 +853,14 @@
"Profile Image": "Imatge de perfil", "Profile Image": "Imatge de perfil",
"Prompt": "Indicació", "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 (e.g. Tell me a fun fact about the Roman Empire)": "Indicació (p.ex. Digues-me quelcom divertit sobre l'Imperi Romà)",
"Prompt Autocompletion": "", "Prompt Autocompletion": "Completar automàticament la indicació",
"Prompt Content": "Contingut de la indicació", "Prompt Content": "Contingut de la indicació",
"Prompt created successfully": "Indicació creada correctament", "Prompt created successfully": "Indicació creada correctament",
"Prompt suggestions": "Suggeriments d'indicacions", "Prompt suggestions": "Suggeriments d'indicacions",
"Prompt updated successfully": "Indicació actualitzada correctament", "Prompt updated successfully": "Indicació actualitzada correctament",
"Prompts": "Indicacions", "Prompts": "Indicacions",
"Prompts Access": "Accés a les indicacions", "Prompts Access": "Accés a les indicacions",
"Prompts Public Sharing": "", "Prompts Public Sharing": "Compartició pública de indicacions",
"Public": "Públic", "Public": "Públic",
"Pull \"{{searchValue}}\" from Ollama.com": "Obtenir \"{{searchValue}}\" de Ollama.com", "Pull \"{{searchValue}}\" from Ollama.com": "Obtenir \"{{searchValue}}\" de Ollama.com",
"Pull a model from Ollama.com": "Obtenir un model d'Ollama.com", "Pull a model from Ollama.com": "Obtenir un model d'Ollama.com",
@ -878,6 +878,8 @@
"References from": "Referències de", "References from": "Referències de",
"Refused when it shouldn't have": "Refusat quan no hauria d'haver estat", "Refused when it shouldn't have": "Refusat quan no hauria d'haver estat",
"Regenerate": "Regenerar", "Regenerate": "Regenerar",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notes de la versió", "Release Notes": "Notes de la versió",
"Relevance": "Rellevància", "Relevance": "Rellevància",
"Remove": "Eliminar", "Remove": "Eliminar",
@ -993,11 +995,11 @@
"Share": "Compartir", "Share": "Compartir",
"Share Chat": "Compartir el xat", "Share Chat": "Compartir el xat",
"Share to Open WebUI Community": "Compartir amb la comunitat OpenWebUI", "Share to Open WebUI Community": "Compartir amb la comunitat OpenWebUI",
"Sharing Permissions": "", "Sharing Permissions": "Compartir els permisos",
"Show": "Mostrar", "Show": "Mostrar",
"Show \"What's New\" modal on login": "Veure 'Què hi ha de nou' a l'entrada", "Show \"What's New\" modal on login": "Veure 'Què hi ha de nou' a l'entrada",
"Show Admin Details in Account Pending Overlay": "Mostrar els detalls de l'administrador a la superposició del compte pendent", "Show Admin Details in Account Pending Overlay": "Mostrar els detalls de l'administrador a la superposició del compte pendent",
"Show Model": "", "Show Model": "Mostrar el model",
"Show shortcuts": "Mostrar dreceres", "Show shortcuts": "Mostrar dreceres",
"Show your support!": "Mostra el teu suport!", "Show your support!": "Mostra el teu suport!",
"Showcased creativity": "Creativitat mostrada", "Showcased creativity": "Creativitat mostrada",
@ -1060,7 +1062,7 @@
"Thinking...": "Pensant...", "Thinking...": "Pensant...",
"This action cannot be undone. Do you wish to continue?": "Aquesta acció no es pot desfer. Vols continuar?", "This action cannot be undone. Do you wish to continue?": "Aquesta acció no es pot desfer. Vols continuar?",
"This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Aquest canal es va crear el dia {{createdAt}}. Aquest és el començament del canal {{channelName}}.", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Aquest canal es va crear el dia {{createdAt}}. Aquest és el començament del canal {{channelName}}.",
"This chat wont appear in history and your messages will not be saved.": "", "This chat wont appear in history and your messages will not be saved.": "Aquest xat no apareixerà a l'historial i els teus missatges no es desaran.",
"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 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 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 option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Aquesta opció controla quants tokens es conserven en actualitzar el context. Per exemple, si s'estableix en 2, es conservaran els darrers 2 tokens del context de conversa. Preservar el context pot ajudar a mantenir la continuïtat d'una conversa, però pot reduir la capacitat de respondre a nous temes.", "This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Aquesta opció controla quants tokens es conserven en actualitzar el context. Per exemple, si s'estableix en 2, es conservaran els darrers 2 tokens del context de conversa. Preservar el context pot ajudar a mantenir la continuïtat d'una conversa, però pot reduir la capacitat de respondre a nous temes.",
@ -1108,7 +1110,7 @@
"Tool ID": "ID de l'eina", "Tool ID": "ID de l'eina",
"Tool imported successfully": "Eina importada correctament", "Tool imported successfully": "Eina importada correctament",
"Tool Name": "Nom de l'eina", "Tool Name": "Nom de l'eina",
"Tool Servers": "", "Tool Servers": "Servidors d'eines",
"Tool updated successfully": "Eina actualitzada correctament", "Tool updated successfully": "Eina actualitzada correctament",
"Tools": "Eines", "Tools": "Eines",
"Tools Access": "Accés a les eines", "Tools Access": "Accés a les eines",
@ -1116,7 +1118,7 @@
"Tools Function Calling Prompt": "Indicació per a la crida de funcions", "Tools Function Calling Prompt": "Indicació per a la crida de funcions",
"Tools have a function calling system that allows arbitrary code execution": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari", "Tools have a function calling system that allows arbitrary code execution": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari",
"Tools have a function calling system that allows arbitrary code execution.": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari.", "Tools have a function calling system that allows arbitrary code execution.": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari.",
"Tools Public Sharing": "", "Tools Public Sharing": "Compartició pública d'eines",
"Top K": "Top K", "Top K": "Top K",
"Top K Reranker": "Top K Reranker", "Top K Reranker": "Top K Reranker",
"Top P": "Top P", "Top P": "Top P",
@ -1158,12 +1160,14 @@
"Use Gravatar": "Utilitzar Gravatar", "Use Gravatar": "Utilitzar Gravatar",
"Use groups to group your users and assign permissions.": "Utilitza grups per agrupar els usuaris i assignar permisos.", "Use groups to group your users and assign permissions.": "Utilitza grups per agrupar els usuaris i assignar permisos.",
"Use Initials": "Utilitzar inicials", "Use Initials": "Utilitzar inicials",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "Usuari", "User": "Usuari",
"User location successfully retrieved.": "Ubicació de l'usuari obtinguda correctament", "User location successfully retrieved.": "Ubicació de l'usuari obtinguda correctament",
"User Webhooks": "", "User Webhooks": "Webhooks d'usuari",
"Username": "Nom d'usuari", "Username": "Nom d'usuari",
"Users": "Usuaris", "Users": "Usuaris",
"Using the default arena model with all models. Click the plus button to add custom models.": "S'utilitza el model d'Arena predeterminat amb tots els models. Clica el botó més per afegir models personalitzats.", "Using the default arena model with all models. Click the plus button to add custom models.": "S'utilitza el model d'Arena predeterminat amb tots els models. Clica el botó més per afegir models personalitzats.",
@ -1178,7 +1182,7 @@
"Version": "Versió", "Version": "Versió",
"Version {{selectedVersion}} of {{totalVersions}}": "Versió {{selectedVersion}} de {{totalVersions}}", "Version {{selectedVersion}} of {{totalVersions}}": "Versió {{selectedVersion}} de {{totalVersions}}",
"View Replies": "Veure les respostes", "View Replies": "Veure les respostes",
"View Result from **{{NAME}}**": "", "View Result from **{{NAME}}**": "Veure el resultat de **{{NAME}}**",
"Visibility": "Visibilitat", "Visibility": "Visibilitat",
"Voice": "Veu", "Voice": "Veu",
"Voice Input": "Entrada de veu", "Voice Input": "Entrada de veu",
@ -1196,7 +1200,7 @@
"Webhook URL": "URL del webhook", "Webhook URL": "URL del webhook",
"WebUI Settings": "Preferències de WebUI", "WebUI Settings": "Preferències de WebUI",
"WebUI URL": "URL de WebUI", "WebUI URL": "URL de WebUI",
"WebUI will make requests to \"{{url}}\"": "", "WebUI will make requests to \"{{url}}\"": "WebUI farà peticions a \"{{url}}\"",
"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI farà peticions a \"{{url}}/api/chat\"", "WebUI will make requests to \"{{url}}/api/chat\"": "WebUI farà peticions a \"{{url}}/api/chat\"",
"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI farà peticions a \"{{url}}/chat/completions\"", "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI farà peticions a \"{{url}}/chat/completions\"",
"What are you trying to achieve?": "Què intentes aconseguir?", "What are you trying to achieve?": "Què intentes aconseguir?",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "", "Refused when it shouldn't have": "",
"Regenerate": "", "Regenerate": "",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Release Notes", "Release Notes": "Release Notes",
"Relevance": "", "Relevance": "",
"Remove": "", "Remove": "",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Paggamit sa Gravatar", "Use Gravatar": "Paggamit sa Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "", "Use Initials": "",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "tiggamit", "user": "tiggamit",

View File

@ -878,6 +878,8 @@
"References from": "Reference z", "References from": "Reference z",
"Refused when it shouldn't have": "Odmítnuto, když nemělo být.", "Refused when it shouldn't have": "Odmítnuto, když nemělo být.",
"Regenerate": "Regenerovat", "Regenerate": "Regenerovat",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Záznamy o vydání", "Release Notes": "Záznamy o vydání",
"Relevance": "Relevance", "Relevance": "Relevance",
"Remove": "Odebrat", "Remove": "Odebrat",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Použití Gravatar", "Use Gravatar": "Použití Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Použijte iniciály", "Use Initials": "Použijte iniciály",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "uživatel", "user": "uživatel",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Afvist, når den ikke burde have været det", "Refused when it shouldn't have": "Afvist, når den ikke burde have været det",
"Regenerate": "Regenerer", "Regenerate": "Regenerer",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Udgivelsesnoter", "Release Notes": "Udgivelsesnoter",
"Relevance": "", "Relevance": "",
"Remove": "Fjern", "Remove": "Fjern",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Brug Gravatar", "Use Gravatar": "Brug Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Brug initialer", "Use Initials": "Brug initialer",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "bruger", "user": "bruger",

View File

@ -878,6 +878,8 @@
"References from": "Referenzen aus", "References from": "Referenzen aus",
"Refused when it shouldn't have": "Abgelehnt, obwohl es nicht hätte abgelehnt werden sollen", "Refused when it shouldn't have": "Abgelehnt, obwohl es nicht hätte abgelehnt werden sollen",
"Regenerate": "Neu generieren", "Regenerate": "Neu generieren",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Veröffentlichungshinweise", "Release Notes": "Veröffentlichungshinweise",
"Relevance": "Relevanz", "Relevance": "Relevanz",
"Remove": "Entfernen", "Remove": "Entfernen",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar verwenden", "Use Gravatar": "Gravatar verwenden",
"Use groups to group your users and assign permissions.": "Nutzen Sie Gruppen, um Ihre Benutzer zu gruppieren und Berechtigungen zuzuweisen.", "Use groups to group your users and assign permissions.": "Nutzen Sie Gruppen, um Ihre Benutzer zu gruppieren und Berechtigungen zuzuweisen.",
"Use Initials": "Initialen verwenden", "Use Initials": "Initialen verwenden",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "Benutzer", "user": "Benutzer",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "", "Refused when it shouldn't have": "",
"Regenerate": "", "Regenerate": "",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Release Borks", "Release Notes": "Release Borks",
"Relevance": "", "Relevance": "",
"Remove": "", "Remove": "",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Use Gravatar much avatar", "Use Gravatar": "Use Gravatar much avatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Use Initials much initial", "Use Initials": "Use Initials much initial",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "user much user", "user": "user much user",

View File

@ -878,6 +878,8 @@
"References from": "Αναφορές από", "References from": "Αναφορές από",
"Refused when it shouldn't have": "Αρνήθηκε όταν δεν έπρεπε", "Refused when it shouldn't have": "Αρνήθηκε όταν δεν έπρεπε",
"Regenerate": "Αναγεννήστε", "Regenerate": "Αναγεννήστε",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Σημειώσεις Έκδοσης", "Release Notes": "Σημειώσεις Έκδοσης",
"Relevance": "Σχετικότητα", "Relevance": "Σχετικότητα",
"Remove": "Αφαίρεση", "Remove": "Αφαίρεση",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Χρησιμοποιήστε Gravatar", "Use Gravatar": "Χρησιμοποιήστε Gravatar",
"Use groups to group your users and assign permissions.": "Χρησιμοποιήστε ομάδες για να ομαδοποιήσετε τους χρήστες σας και να αναθέσετε δικαιώματα.", "Use groups to group your users and assign permissions.": "Χρησιμοποιήστε ομάδες για να ομαδοποιήσετε τους χρήστες σας και να αναθέσετε δικαιώματα.",
"Use Initials": "Χρησιμοποιήστε Αρχικά", "Use Initials": "Χρησιμοποιήστε Αρχικά",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "user", "user": "user",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "", "Refused when it shouldn't have": "",
"Regenerate": "", "Regenerate": "",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "", "Release Notes": "",
"Relevance": "", "Relevance": "",
"Remove": "", "Remove": "",
@ -1158,6 +1160,8 @@
"Use Gravatar": "", "Use Gravatar": "",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "", "Use Initials": "",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "", "user": "",

View File

@ -424,6 +424,8 @@
"Enter Mojeek Search API Key": "", "Enter Mojeek Search API Key": "",
"Enter Number of Steps (e.g. 50)": "", "Enter Number of Steps (e.g. 50)": "",
"Enter Perplexity API Key": "", "Enter Perplexity API Key": "",
"Enter Sougou Search API sID": "",
"Enter Sougou Search API SK": "",
"Enter proxy URL (e.g. https://user:password@host:port)": "", "Enter proxy URL (e.g. https://user:password@host:port)": "",
"Enter reasoning effort": "", "Enter reasoning effort": "",
"Enter Sampler (e.g. Euler a)": "", "Enter Sampler (e.g. Euler a)": "",
@ -822,6 +824,8 @@
"Permission denied when accessing microphone: {{error}}": "", "Permission denied when accessing microphone: {{error}}": "",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Sougou Search API sID": "",
"Sougou Search API SK": "",
"Personalization": "", "Personalization": "",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -878,6 +882,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "", "Refused when it shouldn't have": "",
"Regenerate": "", "Regenerate": "",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "", "Release Notes": "",
"Relevance": "", "Relevance": "",
"Remove": "", "Remove": "",
@ -1158,6 +1164,8 @@
"Use Gravatar": "", "Use Gravatar": "",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "", "Use Initials": "",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "", "user": "",

View File

@ -878,6 +878,8 @@
"References from": "Referencias desde", "References from": "Referencias desde",
"Refused when it shouldn't have": "Rechazado cuando no debería haberlo hecho", "Refused when it shouldn't have": "Rechazado cuando no debería haberlo hecho",
"Regenerate": "Regenerar", "Regenerate": "Regenerar",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notas de la Versión", "Release Notes": "Notas de la Versión",
"Relevance": "Relevancia", "Relevance": "Relevancia",
"Remove": "Eliminar", "Remove": "Eliminar",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Usar Gravatar", "Use Gravatar": "Usar Gravatar",
"Use groups to group your users and assign permissions.": "Usar grupos para agrupar a usuarios y asignar permisos.", "Use groups to group your users and assign permissions.": "Usar grupos para agrupar a usuarios y asignar permisos.",
"Use Initials": "Usar Iniciales", "Use Initials": "Usar Iniciales",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "usuario", "user": "usuario",

View File

@ -878,6 +878,8 @@
"References from": "Viited allikast", "References from": "Viited allikast",
"Refused when it shouldn't have": "Keeldus, kui ei oleks pidanud", "Refused when it shouldn't have": "Keeldus, kui ei oleks pidanud",
"Regenerate": "Regenereeri", "Regenerate": "Regenereeri",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Väljalaskemärkmed", "Release Notes": "Väljalaskemärkmed",
"Relevance": "Asjakohasus", "Relevance": "Asjakohasus",
"Remove": "Eemalda", "Remove": "Eemalda",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Kasuta Gravatari", "Use Gravatar": "Kasuta Gravatari",
"Use groups to group your users and assign permissions.": "Kasutage gruppe oma kasutajate grupeerimiseks ja õiguste määramiseks.", "Use groups to group your users and assign permissions.": "Kasutage gruppe oma kasutajate grupeerimiseks ja õiguste määramiseks.",
"Use Initials": "Kasuta initsiaale", "Use Initials": "Kasuta initsiaale",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "kasutaja", "user": "kasutaja",

View File

@ -878,6 +878,8 @@
"References from": "Erreferentziak hemendik", "References from": "Erreferentziak hemendik",
"Refused when it shouldn't have": "Ukatu duenean ukatu behar ez zuenean", "Refused when it shouldn't have": "Ukatu duenean ukatu behar ez zuenean",
"Regenerate": "Bersortu", "Regenerate": "Bersortu",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Bertsio oharrak", "Release Notes": "Bertsio oharrak",
"Relevance": "Garrantzia", "Relevance": "Garrantzia",
"Remove": "Kendu", "Remove": "Kendu",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Erabili Gravatar", "Use Gravatar": "Erabili Gravatar",
"Use groups to group your users and assign permissions.": "Erabili taldeak zure erabiltzaileak taldekatu eta baimenak esleitzeko.", "Use groups to group your users and assign permissions.": "Erabili taldeak zure erabiltzaileak taldekatu eta baimenak esleitzeko.",
"Use Initials": "Erabili inizialak", "Use Initials": "Erabili inizialak",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "erabiltzailea", "user": "erabiltzailea",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "رد شده زمانی که باید نباشد", "Refused when it shouldn't have": "رد شده زمانی که باید نباشد",
"Regenerate": "ری\u200cسازی", "Regenerate": "ری\u200cسازی",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "یادداشت\u200cهای انتشار", "Release Notes": "یادداشت\u200cهای انتشار",
"Relevance": "ارتباط", "Relevance": "ارتباط",
"Remove": "حذف", "Remove": "حذف",
@ -1158,6 +1160,8 @@
"Use Gravatar": "استفاده از گراواتار", "Use Gravatar": "استفاده از گراواتار",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "استفاده از سرواژه", "Use Initials": "استفاده از سرواژه",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (اولاما)", "use_mlock (Ollama)": "use_mlock (اولاما)",
"use_mmap (Ollama)": "use_mmap (اولاما)", "use_mmap (Ollama)": "use_mmap (اولاما)",
"user": "کاربر", "user": "کاربر",

View File

@ -878,6 +878,8 @@
"References from": "Viitteet lähteistä", "References from": "Viitteet lähteistä",
"Refused when it shouldn't have": "Kieltäytyi, vaikka ei olisi pitänyt", "Refused when it shouldn't have": "Kieltäytyi, vaikka ei olisi pitänyt",
"Regenerate": "Uudelleentuota", "Regenerate": "Uudelleentuota",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Julkaisutiedot", "Release Notes": "Julkaisutiedot",
"Relevance": "Relevanssi", "Relevance": "Relevanssi",
"Remove": "Poista", "Remove": "Poista",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Käytä Gravataria", "Use Gravatar": "Käytä Gravataria",
"Use groups to group your users and assign permissions.": "Käytä ryhmiä jäsentääksesi käyttäjiä ja antaaksesi käyttöoikeuksia.", "Use groups to group your users and assign permissions.": "Käytä ryhmiä jäsentääksesi käyttäjiä ja antaaksesi käyttöoikeuksia.",
"Use Initials": "Käytä alkukirjaimia", "Use Initials": "Käytä alkukirjaimia",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "käyttäjä", "user": "käyttäjä",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Refusé alors qu'il n'aurait pas dû l'être", "Refused when it shouldn't have": "Refusé alors qu'il n'aurait pas dû l'être",
"Regenerate": "Regénérer", "Regenerate": "Regénérer",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notes de publication", "Release Notes": "Notes de publication",
"Relevance": "", "Relevance": "",
"Remove": "Retirer", "Remove": "Retirer",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Utilisez Gravatar", "Use Gravatar": "Utilisez Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Utiliser les initiales", "Use Initials": "Utiliser les initiales",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (Ollama)", "use_mlock (Ollama)": "use_mlock (Ollama)",
"use_mmap (Ollama)": "utiliser mmap (Ollama)", "use_mmap (Ollama)": "utiliser mmap (Ollama)",
"user": "utilisateur", "user": "utilisateur",

View File

@ -878,6 +878,8 @@
"References from": "Références de", "References from": "Références de",
"Refused when it shouldn't have": "Refusé alors qu'il n'aurait pas dû l'être", "Refused when it shouldn't have": "Refusé alors qu'il n'aurait pas dû l'être",
"Regenerate": "Regénérer", "Regenerate": "Regénérer",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notes de mise à jour", "Release Notes": "Notes de mise à jour",
"Relevance": "Pertinence", "Relevance": "Pertinence",
"Remove": "Retirer", "Remove": "Retirer",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Utiliser Gravatar", "Use Gravatar": "Utiliser Gravatar",
"Use groups to group your users and assign permissions.": "Utilisez des groupes pour regrouper vos utilisateurs et attribuer des permissions.", "Use groups to group your users and assign permissions.": "Utilisez des groupes pour regrouper vos utilisateurs et attribuer des permissions.",
"Use Initials": "Utiliser les initiales", "Use Initials": "Utiliser les initiales",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "Utiliser mlock (Ollama)", "use_mlock (Ollama)": "Utiliser mlock (Ollama)",
"use_mmap (Ollama)": "Utiliser mmap (Ollama)", "use_mmap (Ollama)": "Utiliser mmap (Ollama)",
"user": "utilisateur", "user": "utilisateur",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "נדחה כאשר לא היה צריך", "Refused when it shouldn't have": "נדחה כאשר לא היה צריך",
"Regenerate": "הפק מחדש", "Regenerate": "הפק מחדש",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "הערות שחרור", "Release Notes": "הערות שחרור",
"Relevance": "", "Relevance": "",
"Remove": "הסר", "Remove": "הסר",
@ -1158,6 +1160,8 @@
"Use Gravatar": "שימוש ב Gravatar", "Use Gravatar": "שימוש ב Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "שימוש ב initials", "Use Initials": "שימוש ב initials",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (אולמה)", "use_mlock (Ollama)": "use_mlock (אולמה)",
"use_mmap (Ollama)": "use_mmap (Ollama)", "use_mmap (Ollama)": "use_mmap (Ollama)",
"user": "משתמש", "user": "משתמש",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "जब ऐसा नहीं होना चाहिए था तो मना कर दिया", "Refused when it shouldn't have": "जब ऐसा नहीं होना चाहिए था तो मना कर दिया",
"Regenerate": "पुनः जेनरेट", "Regenerate": "पुनः जेनरेट",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "रिलीज नोट्स", "Release Notes": "रिलीज नोट्स",
"Relevance": "", "Relevance": "",
"Remove": "हटा दें", "Remove": "हटा दें",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar का प्रयोग करें", "Use Gravatar": "Gravatar का प्रयोग करें",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "प्रथमाक्षर का प्रयोग करें", "Use Initials": "प्रथमाक्षर का प्रयोग करें",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (ओलामा)", "use_mlock (Ollama)": "use_mlock (ओलामा)",
"use_mmap (Ollama)": "use_mmap (ओलामा)", "use_mmap (Ollama)": "use_mmap (ओलामा)",
"user": "उपयोगकर्ता", "user": "उपयोगकर्ता",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Odbijen kada nije trebao biti", "Refused when it shouldn't have": "Odbijen kada nije trebao biti",
"Regenerate": "Regeneriraj", "Regenerate": "Regeneriraj",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Bilješke o izdanju", "Release Notes": "Bilješke o izdanju",
"Relevance": "", "Relevance": "",
"Remove": "Ukloni", "Remove": "Ukloni",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Koristi Gravatar", "Use Gravatar": "Koristi Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Koristi inicijale", "Use Initials": "Koristi inicijale",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "korisnik", "user": "korisnik",

File diff suppressed because it is too large Load Diff

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Menolak ketika seharusnya tidak", "Refused when it shouldn't have": "Menolak ketika seharusnya tidak",
"Regenerate": "Regenerasi", "Regenerate": "Regenerasi",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Catatan Rilis", "Release Notes": "Catatan Rilis",
"Relevance": "", "Relevance": "",
"Remove": "Hapus", "Remove": "Hapus",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gunakan Gravatar", "Use Gravatar": "Gunakan Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Gunakan Inisial", "Use Initials": "Gunakan Inisial",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "pengguna", "user": "pengguna",

View File

@ -878,6 +878,8 @@
"References from": "Tagairtí ó", "References from": "Tagairtí ó",
"Refused when it shouldn't have": "Diúltaíodh nuair nár chóir dó", "Refused when it shouldn't have": "Diúltaíodh nuair nár chóir dó",
"Regenerate": "Athghiniúint", "Regenerate": "Athghiniúint",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Nótaí Scaoilte", "Release Notes": "Nótaí Scaoilte",
"Relevance": "Ábharthacht", "Relevance": "Ábharthacht",
"Remove": "Bain", "Remove": "Bain",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Úsáid Gravatar", "Use Gravatar": "Úsáid Gravatar",
"Use groups to group your users and assign permissions.": "Úsáid grúpaí chun d'úsáideoirí a ghrúpáil agus ceadanna a shannadh", "Use groups to group your users and assign permissions.": "Úsáid grúpaí chun d'úsáideoirí a ghrúpáil agus ceadanna a shannadh",
"Use Initials": "Úsáid ceannlitreacha", "Use Initials": "Úsáid ceannlitreacha",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "úsáideoir", "user": "úsáideoir",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Rifiutato quando non avrebbe dovuto", "Refused when it shouldn't have": "Rifiutato quando non avrebbe dovuto",
"Regenerate": "Rigenera", "Regenerate": "Rigenera",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Note di rilascio", "Release Notes": "Note di rilascio",
"Relevance": "", "Relevance": "",
"Remove": "Rimuovi", "Remove": "Rimuovi",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Usa Gravatar", "Use Gravatar": "Usa Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Usa iniziali", "Use Initials": "Usa iniziali",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "utente", "user": "utente",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "拒否すべきでないのに拒否した", "Refused when it shouldn't have": "拒否すべきでないのに拒否した",
"Regenerate": "再生成", "Regenerate": "再生成",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "リリースノート", "Release Notes": "リリースノート",
"Relevance": "", "Relevance": "",
"Remove": "削除", "Remove": "削除",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar を使用する", "Use Gravatar": "Gravatar を使用する",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "初期値を使用する", "Use Initials": "初期値を使用する",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "ユーザー", "user": "ユーザー",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "უარა, როგორც უნდა იყოს", "Refused when it shouldn't have": "უარა, როგორც უნდა იყოს",
"Regenerate": "თავიდან გენერაცია", "Regenerate": "თავიდან გენერაცია",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "გამოცემის შენიშვნები", "Release Notes": "გამოცემის შენიშვნები",
"Relevance": "შესაბამისობა", "Relevance": "შესაბამისობა",
"Remove": "წაშლა", "Remove": "წაშლა",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar-ის გამოყენება", "Use Gravatar": "Gravatar-ის გამოყენება",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "ინიციალების გამოყენება", "Use Initials": "ინიციალების გამოყენება",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "მომხმარებელი", "user": "მომხმარებელი",

View File

@ -878,6 +878,8 @@
"References from": "출처", "References from": "출처",
"Refused when it shouldn't have": "허용되지 않았지만 허용되어야 합니다.", "Refused when it shouldn't have": "허용되지 않았지만 허용되어야 합니다.",
"Regenerate": "재생성", "Regenerate": "재생성",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "릴리스 노트", "Release Notes": "릴리스 노트",
"Relevance": "관련도", "Relevance": "관련도",
"Remove": "삭제", "Remove": "삭제",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar 사용", "Use Gravatar": "Gravatar 사용",
"Use groups to group your users and assign permissions.": "그룹을 사용하여 사용자를 그룹화하고 권한을 할당하세요.", "Use groups to group your users and assign permissions.": "그룹을 사용하여 사용자를 그룹화하고 권한을 할당하세요.",
"Use Initials": "초성 사용", "Use Initials": "초성 사용",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (올라마)", "use_mlock (Ollama)": "use_mlock (올라마)",
"use_mmap (Ollama)": "use_mmap (올라마)", "use_mmap (Ollama)": "use_mmap (올라마)",
"user": "사용자", "user": "사용자",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Atmesta kai neturėtų būti atmesta", "Refused when it shouldn't have": "Atmesta kai neturėtų būti atmesta",
"Regenerate": "Generuoti iš naujo", "Regenerate": "Generuoti iš naujo",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Naujovės", "Release Notes": "Naujovės",
"Relevance": "", "Relevance": "",
"Remove": "Pašalinti", "Remove": "Pašalinti",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Naudoti Gravatar", "Use Gravatar": "Naudoti Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Naudotojo inicialai", "Use Initials": "Naudotojo inicialai",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "naudotojas", "user": "naudotojas",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Menolak dimana ia tidak sepatutnya", "Refused when it shouldn't have": "Menolak dimana ia tidak sepatutnya",
"Regenerate": "Jana semula", "Regenerate": "Jana semula",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Nota Keluaran", "Release Notes": "Nota Keluaran",
"Relevance": "", "Relevance": "",
"Remove": "Hapuskan", "Remove": "Hapuskan",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gunakan Gravatar", "Use Gravatar": "Gunakan Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Gunakan nama pendek", "Use Initials": "Gunakan nama pendek",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (Ollama)", "use_mlock (Ollama)": "use_mlock (Ollama)",
"use_mmap (Ollama)": "se_mmap (Ollama)", "use_mmap (Ollama)": "se_mmap (Ollama)",
"user": "pengguna", "user": "pengguna",

View File

@ -878,6 +878,8 @@
"References from": "Henviser fra", "References from": "Henviser fra",
"Refused when it shouldn't have": "Avvist når det ikke burde ha blitt det", "Refused when it shouldn't have": "Avvist når det ikke burde ha blitt det",
"Regenerate": "Generer på nytt", "Regenerate": "Generer på nytt",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Utgivelsesnotater", "Release Notes": "Utgivelsesnotater",
"Relevance": "Relevans", "Relevance": "Relevans",
"Remove": "Fjern", "Remove": "Fjern",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Bruk Gravatar", "Use Gravatar": "Bruk Gravatar",
"Use groups to group your users and assign permissions.": "Bruk grupper til å samle brukere og tildele tillatelser.", "Use groups to group your users and assign permissions.": "Bruk grupper til å samle brukere og tildele tillatelser.",
"Use Initials": "Bruk initialer", "Use Initials": "Bruk initialer",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "bruker", "user": "bruker",

View File

@ -878,6 +878,8 @@
"References from": "Referenties van", "References from": "Referenties van",
"Refused when it shouldn't have": "Geweigerd terwijl het niet had moeten", "Refused when it shouldn't have": "Geweigerd terwijl het niet had moeten",
"Regenerate": "Regenereren", "Regenerate": "Regenereren",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Release-opmerkingen", "Release Notes": "Release-opmerkingen",
"Relevance": "Relevantie", "Relevance": "Relevantie",
"Remove": "Verwijderen", "Remove": "Verwijderen",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gebruik Gravatar", "Use Gravatar": "Gebruik Gravatar",
"Use groups to group your users and assign permissions.": "Gebruik groepen om gebruikers te groeperen en rechten aan te wijzen", "Use groups to group your users and assign permissions.": "Gebruik groepen om gebruikers te groeperen en rechten aan te wijzen",
"Use Initials": "Gebruik initialen", "Use Initials": "Gebruik initialen",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "gebruiker", "user": "gebruiker",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "ਜਦੋਂ ਇਹ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਸੀ ਤਾਂ ਇਨਕਾਰ ਕੀਤਾ", "Refused when it shouldn't have": "ਜਦੋਂ ਇਹ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਸੀ ਤਾਂ ਇਨਕਾਰ ਕੀਤਾ",
"Regenerate": "ਮੁੜ ਬਣਾਓ", "Regenerate": "ਮੁੜ ਬਣਾਓ",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "ਰਿਲੀਜ਼ ਨੋਟਸ", "Release Notes": "ਰਿਲੀਜ਼ ਨੋਟਸ",
"Relevance": "", "Relevance": "",
"Remove": "ਹਟਾਓ", "Remove": "ਹਟਾਓ",
@ -1158,6 +1160,8 @@
"Use Gravatar": "ਗ੍ਰਾਵਾਟਾਰ ਵਰਤੋ", "Use Gravatar": "ਗ੍ਰਾਵਾਟਾਰ ਵਰਤੋ",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "ਸ਼ੁਰੂਆਤੀ ਅੱਖਰ ਵਰਤੋ", "Use Initials": "ਸ਼ੁਰੂਆਤੀ ਅੱਖਰ ਵਰਤੋ",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "use_mlock (ਓਲਾਮਾ)", "use_mlock (Ollama)": "use_mlock (ਓਲਾਮਾ)",
"use_mmap (Ollama)": "use_mmap (ਓਲਾਮਾ)", "use_mmap (Ollama)": "use_mmap (ਓਲਾਮਾ)",
"user": "ਉਪਭੋਗਤਾ", "user": "ਉਪਭੋਗਤਾ",

View File

@ -878,6 +878,8 @@
"References from": "Odniesienia do", "References from": "Odniesienia do",
"Refused when it shouldn't have": "Odmówił, gdy nie powinien", "Refused when it shouldn't have": "Odmówił, gdy nie powinien",
"Regenerate": "Wygeneruj ponownie", "Regenerate": "Wygeneruj ponownie",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notatki do wydania", "Release Notes": "Notatki do wydania",
"Relevance": "Trafność", "Relevance": "Trafność",
"Remove": "Usuń", "Remove": "Usuń",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Użyj Gravatara", "Use Gravatar": "Użyj Gravatara",
"Use groups to group your users and assign permissions.": "Wykorzystaj grupy do grupowania użytkowników i przypisywania uprawnień.", "Use groups to group your users and assign permissions.": "Wykorzystaj grupy do grupowania użytkowników i przypisywania uprawnień.",
"Use Initials": "Użyj inicjałów", "Use Initials": "Użyj inicjałów",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "użyj_mlock (Ollama)", "use_mlock (Ollama)": "użyj_mlock (Ollama)",
"use_mmap (Ollama)": "użyj_mmap (Ollama)", "use_mmap (Ollama)": "użyj_mmap (Ollama)",
"user": "użytkownik", "user": "użytkownik",

View File

@ -878,6 +878,8 @@
"References from": "Referências de", "References from": "Referências de",
"Refused when it shouldn't have": "Recusado quando não deveria", "Refused when it shouldn't have": "Recusado quando não deveria",
"Regenerate": "Gerar novamente", "Regenerate": "Gerar novamente",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notas de Lançamento", "Release Notes": "Notas de Lançamento",
"Relevance": "Relevância", "Relevance": "Relevância",
"Remove": "Remover", "Remove": "Remover",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Usar Gravatar", "Use Gravatar": "Usar Gravatar",
"Use groups to group your users and assign permissions.": "Use grupos para agrupar seus usuários e atribuir permissões.", "Use groups to group your users and assign permissions.": "Use grupos para agrupar seus usuários e atribuir permissões.",
"Use Initials": "Usar Iniciais", "Use Initials": "Usar Iniciais",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "usuário", "user": "usuário",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Recusado quando não deveria", "Refused when it shouldn't have": "Recusado quando não deveria",
"Regenerate": "Regenerar", "Regenerate": "Regenerar",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Notas de Lançamento", "Release Notes": "Notas de Lançamento",
"Relevance": "", "Relevance": "",
"Remove": "Remover", "Remove": "Remover",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Usar Gravatar", "Use Gravatar": "Usar Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Usar Iniciais", "Use Initials": "Usar Iniciais",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "utilizador", "user": "utilizador",

View File

@ -878,6 +878,8 @@
"References from": "Referințe din", "References from": "Referințe din",
"Refused when it shouldn't have": "Refuzat când nu ar fi trebuit", "Refused when it shouldn't have": "Refuzat când nu ar fi trebuit",
"Regenerate": "Regenerare", "Regenerate": "Regenerare",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Note de Lansare", "Release Notes": "Note de Lansare",
"Relevance": "Relevanță", "Relevance": "Relevanță",
"Remove": "Înlătură", "Remove": "Înlătură",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Folosește Gravatar", "Use Gravatar": "Folosește Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Folosește Inițialele", "Use Initials": "Folosește Inițialele",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "utilizator", "user": "utilizator",

View File

@ -6,7 +6,7 @@
"(latest)": "(последняя)", "(latest)": "(последняя)",
"(Ollama)": "", "(Ollama)": "",
"{{ models }}": "{{ модели }}", "{{ models }}": "{{ модели }}",
"{{COUNT}} Available Tools": "", "{{COUNT}} Available Tools": "{{COUNT}} доступных инструментов",
"{{COUNT}} hidden lines": "{{COUNT}} скрытых строк", "{{COUNT}} hidden lines": "{{COUNT}} скрытых строк",
"{{COUNT}} Replies": "{{COUNT}} Ответов", "{{COUNT}} Replies": "{{COUNT}} Ответов",
"{{user}}'s Chats": "Чаты {{user}}'а", "{{user}}'s Chats": "Чаты {{user}}'а",
@ -49,10 +49,10 @@
"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": "Все",
"All Documents": "Все документы", "All Documents": "Все документы",
@ -108,10 +108,10 @@
"Attribute for Username": "Атрибут для имени пользователя", "Attribute for Username": "Атрибут для имени пользователя",
"Audio": "Аудио", "Audio": "Аудио",
"August": "Август", "August": "Август",
"Auth": "", "Auth": "Вход",
"Authenticate": "Аутентификация", "Authenticate": "Аутентификация",
"Authentication": "Аутентификация", "Authentication": "Аутентификация",
"Auto": "", "Auto": "Автоматически",
"Auto-Copy Response to Clipboard": "Автоматическое копирование ответа в буфер обмена", "Auto-Copy Response to Clipboard": "Автоматическое копирование ответа в буфер обмена",
"Auto-playback response": "Автоматическое воспроизведение ответа", "Auto-playback response": "Автоматическое воспроизведение ответа",
"Autocomplete Generation": "Генерация автозаполнения", "Autocomplete Generation": "Генерация автозаполнения",
@ -121,7 +121,7 @@
"AUTOMATIC1111 Base URL": "Базовый URL адрес AUTOMATIC1111", "AUTOMATIC1111 Base URL": "Базовый URL адрес AUTOMATIC1111",
"AUTOMATIC1111 Base URL is required.": "Необходим базовый адрес URL AUTOMATIC1111.", "AUTOMATIC1111 Base URL is required.": "Необходим базовый адрес URL AUTOMATIC1111.",
"Available list": "Список доступных", "Available list": "Список доступных",
"Available Tools": "", "Available Tools": "Доступные инструменты",
"available!": "доступно!", "available!": "доступно!",
"Awful": "Ужасно", "Awful": "Ужасно",
"Azure AI Speech": "Azure AI Speech", "Azure AI Speech": "Azure AI Speech",
@ -220,10 +220,10 @@
"Confirm your new password": "Подтвердите свой новый пароль", "Confirm your new password": "Подтвердите свой новый пароль",
"Connect to your own OpenAI compatible API endpoints.": "Подключитесь к своим собственным энд-поинтам API, совместимым с OpenAI.", "Connect to your own OpenAI compatible API endpoints.": "Подключитесь к своим собственным энд-поинтам API, совместимым с OpenAI.",
"Connect to your own OpenAPI compatible external tool servers.": "Подключитесь к вашим собственным внешним инструментальным серверам, совместимым с OpenAPI.", "Connect to your own OpenAPI compatible external tool servers.": "Подключитесь к вашим собственным внешним инструментальным серверам, совместимым с OpenAPI.",
"Connection failed": "", "Connection failed": "Подключение не удалось",
"Connection successful": "", "Connection successful": "Успешное подключение",
"Connections": "Подключения", "Connections": "Подключения",
"Connections saved successfully": "", "Connections saved successfully": "Подключение успешно сохранено",
"Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Ограничивает усилия по обоснованию для моделей обоснования. Применимо только к моделям обоснования от конкретных поставщиков, которые поддерживают усилия по обоснованию.", "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Ограничивает усилия по обоснованию для моделей обоснования. Применимо только к моделям обоснования от конкретных поставщиков, которые поддерживают усилия по обоснованию.",
"Contact Admin for WebUI Access": "Обратитесь к администратору для получения доступа к WebUI", "Contact Admin for WebUI Access": "Обратитесь к администратору для получения доступа к WebUI",
"Content": "Содержание", "Content": "Содержание",
@ -254,7 +254,7 @@
"Create Admin Account": "Создать Аккаунт Администратора", "Create Admin Account": "Создать Аккаунт Администратора",
"Create Channel": "Создать Канал", "Create Channel": "Создать Канал",
"Create Group": "Создать Группу", "Create Group": "Создать Группу",
"Create Knowledge": "Создать Знания", "Create Knowledge": "Создать Знание",
"Create new key": "Создать новый ключ", "Create new key": "Создать новый ключ",
"Create new secret key": "Создать новый секретный ключ", "Create new secret key": "Создать новый секретный ключ",
"Created at": "Создано", "Created at": "Создано",
@ -304,11 +304,11 @@
"Describe your knowledge base and objectives": "Опишите свою базу знаний и цели", "Describe your knowledge base and objectives": "Опишите свою базу знаний и цели",
"Description": "Описание", "Description": "Описание",
"Didn't fully follow instructions": "Не полностью следует инструкциям", "Didn't fully follow instructions": "Не полностью следует инструкциям",
"Direct": "", "Direct": "Прямое",
"Direct Connections": "Прямые подключения", "Direct Connections": "Прямые подключения",
"Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Прямые подключения позволяют пользователям подключаться к своим собственным конечным точкам API, совместимым с OpenAI.", "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Прямые подключения позволяют пользователям подключаться к своим собственным конечным точкам API, совместимым с OpenAI.",
"Direct Connections settings updated": "Настройки прямых подключений обновлены", "Direct Connections settings updated": "Настройки прямых подключений обновлены",
"Direct Tool Servers": "", "Direct Tool Servers": "Прямые сервера инструментов",
"Disabled": "Отключено", "Disabled": "Отключено",
"Discover a function": "Найти функцию", "Discover a function": "Найти функцию",
"Discover a model": "Найти модель", "Discover a model": "Найти модель",
@ -329,7 +329,7 @@
"Do not install functions from sources you do not fully trust.": "Не устанавливайте функции из источников, которым вы не полностью доверяете.", "Do not install functions from sources you do not fully trust.": "Не устанавливайте функции из источников, которым вы не полностью доверяете.",
"Do not install tools from sources you do not fully trust.": "Не устанавливайте инструменты из источников, которым вы не полностью доверяете.", "Do not install tools from sources you do not fully trust.": "Не устанавливайте инструменты из источников, которым вы не полностью доверяете.",
"Docling": "", "Docling": "",
"Docling Server URL required.": "", "Docling Server URL required.": "Необходим URL сервера Docling",
"Document": "Документ", "Document": "Документ",
"Document Intelligence": "Интеллектуальный анализ документов", "Document Intelligence": "Интеллектуальный анализ документов",
"Document Intelligence endpoint and key required.": "Требуется энд-поинт анализа документов и ключ.", "Document Intelligence endpoint and key required.": "Требуется энд-поинт анализа документов и ключ.",
@ -350,7 +350,7 @@
"Draw": "Рисовать", "Draw": "Рисовать",
"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'.",
"e.g. \"json\" or a JSON schema": "", "e.g. \"json\" or a JSON schema": "например, \"json\" или схему JSON",
"e.g. 60": "например, 60", "e.g. 60": "например, 60",
"e.g. A filter to remove profanity from text": "например, фильтр для удаления ненормативной лексики из текста", "e.g. A filter to remove profanity from text": "например, фильтр для удаления ненормативной лексики из текста",
"e.g. My Filter": "например, мой фильтр", "e.g. My Filter": "например, мой фильтр",
@ -385,7 +385,7 @@
"Enable Mirostat sampling for controlling perplexity.": "Включите выборку Mirostat для контроля путаницы.", "Enable Mirostat sampling for controlling perplexity.": "Включите выборку Mirostat для контроля путаницы.",
"Enable New Sign Ups": "Разрешить новые регистрации", "Enable New Sign Ups": "Разрешить новые регистрации",
"Enabled": "Включено", "Enabled": "Включено",
"Enforce Temporary Chat": "", "Enforce Temporary Chat": "Принудительный временный чат",
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Убедитесь, что ваш CSV-файл включает в себя 4 столбца в следующем порядке: Имя, Электронная почта, Пароль, Роль.", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Убедитесь, что ваш CSV-файл включает в себя 4 столбца в следующем порядке: Имя, Электронная почта, Пароль, Роль.",
"Enter {{role}} message here": "Введите сообщение {{role}} здесь", "Enter {{role}} message here": "Введите сообщение {{role}} здесь",
"Enter a detail about yourself for your LLMs to recall": "Введите детали о себе, чтобы LLMs могли запомнить", "Enter a detail about yourself for your LLMs to recall": "Введите детали о себе, чтобы LLMs могли запомнить",
@ -402,7 +402,7 @@
"Enter Chunk Size": "Введите размер фрагмента", "Enter Chunk Size": "Введите размер фрагмента",
"Enter comma-seperated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Введите пары \"token:bias_value\", разделенные запятыми (пример: 5432:100, 413:-100).", "Enter comma-seperated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Введите пары \"token:bias_value\", разделенные запятыми (пример: 5432:100, 413:-100).",
"Enter description": "Введите описание", "Enter description": "Введите описание",
"Enter Docling Server URL": "", "Enter Docling Server URL": "Введите URL сервера Docling",
"Enter Document Intelligence Endpoint": "Введите энд-поинт анализа документов", "Enter Document Intelligence Endpoint": "Введите энд-поинт анализа документов",
"Enter Document Intelligence Key": "Введите ключ для анализа документов", "Enter Document Intelligence Key": "Введите ключ для анализа документов",
"Enter domains separated by commas (e.g., example.com,site.org)": "Введите домены, разделенные запятыми (например, example.com,site.org)", "Enter domains separated by commas (e.g., example.com,site.org)": "Введите домены, разделенные запятыми (например, example.com,site.org)",
@ -418,7 +418,7 @@
"Enter Kagi Search API Key": "Введите ключ API поиска Kagi", "Enter Kagi Search API Key": "Введите ключ API поиска Kagi",
"Enter Key Behavior": "Введите ключ поведения", "Enter Key Behavior": "Введите ключ поведения",
"Enter language codes": "Введите коды языков", "Enter language codes": "Введите коды языков",
"Enter Mistral API Key": "", "Enter Mistral API Key": "Введите ключ API для Mistral",
"Enter Model ID": "Введите ID модели", "Enter Model ID": "Введите ID модели",
"Enter model tag (e.g. {{modelTag}})": "Введите тег модели (например, {{modelTag}})", "Enter model tag (e.g. {{modelTag}})": "Введите тег модели (например, {{modelTag}})",
"Enter Mojeek Search API Key": "Введите ключ API поиска Mojeek", "Enter Mojeek Search API Key": "Введите ключ API поиска Mojeek",
@ -443,21 +443,21 @@
"Enter server port": "Введите порт сервера", "Enter server port": "Введите порт сервера",
"Enter stop sequence": "Введите последовательность остановки", "Enter stop sequence": "Введите последовательность остановки",
"Enter system prompt": "Введите системный промпт", "Enter system prompt": "Введите системный промпт",
"Enter system prompt here": "", "Enter system prompt here": "Введите системный промпт здесь",
"Enter Tavily API Key": "Введите ключ API Tavily", "Enter Tavily API Key": "Введите ключ API Tavily",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Введите общедоступный URL вашего WebUI. Этот URL будет использоваться для создания ссылок в уведомлениях.", "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Введите общедоступный URL вашего WebUI. Этот URL будет использоваться для создания ссылок в уведомлениях.",
"Enter Tika Server URL": "Введите URL-адрес сервера Tika", "Enter Tika Server URL": "Введите URL-адрес сервера Tika",
"Enter timeout in seconds": "Введите время ожидания в секундах", "Enter timeout in seconds": "Введите время ожидания в секундах",
"Enter to Send": "Enter для отправки", "Enter to Send": "Enter для отправки",
"Enter Top K": "Введите Top K", "Enter Top K": "Введите Top K",
"Enter Top K Reranker": "", "Enter Top K Reranker": "Введите 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 current password": "Введите ваш текущий пароль", "Enter your current password": "Введите ваш текущий пароль",
"Enter Your Email": "Введите вашу электронную почту", "Enter Your Email": "Введите вашу электронную почту",
"Enter Your Full Name": "Введите ваше полное имя", "Enter Your Full Name": "Введите ваше полное имя",
"Enter your message": "Введите ваше сообщение", "Enter your message": "Введите ваше сообщение",
"Enter your name": "", "Enter your name": "Введите ваше имя",
"Enter your new password": "Введите свой новый пароль", "Enter your new password": "Введите свой новый пароль",
"Enter Your Password": "Введите ваш пароль", "Enter Your Password": "Введите ваш пароль",
"Enter Your Role": "Введите вашу роль", "Enter Your Role": "Введите вашу роль",
@ -477,7 +477,7 @@
"Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "Превышено количество мест в вашей лицензии. Пожалуйста, свяжитесь со службой поддержки, чтобы увеличить количество мест.", "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "Превышено количество мест в вашей лицензии. Пожалуйста, свяжитесь со службой поддержки, чтобы увеличить количество мест.",
"Exclude": "Исключать", "Exclude": "Исключать",
"Execute code for analysis": "Выполнить код для анализа", "Execute code for analysis": "Выполнить код для анализа",
"Executing **{{NAME}}**...": "", "Executing **{{NAME}}**...": "Выполняю **{{NAME}}**...",
"Expand": "Расширить", "Expand": "Расширить",
"Experimental": "Экспериментальное", "Experimental": "Экспериментальное",
"Explain": "Объяснить", "Explain": "Объяснить",
@ -495,14 +495,14 @@
"Export Prompts": "Экспортировать промпты", "Export Prompts": "Экспортировать промпты",
"Export to CSV": "Экспортировать в CSV", "Export to CSV": "Экспортировать в CSV",
"Export Tools": "Экспортировать инструменты", "Export Tools": "Экспортировать инструменты",
"External": "", "External": "Внешнее",
"External Models": "Внешние модели", "External Models": "Внешние модели",
"Failed to add file.": "Не удалось добавить файл.", "Failed to add file.": "Не удалось добавить файл.",
"Failed to connect to {{URL}} OpenAPI tool server": "", "Failed to connect to {{URL}} OpenAPI tool server": "Не удалось подключиться к серверу инструмента OpenAI {{URL}}",
"Failed to create API Key.": "Не удалось создать ключ API.", "Failed to create API Key.": "Не удалось создать ключ API.",
"Failed to fetch models": "Не удалось получить модели", "Failed to fetch models": "Не удалось получить модели",
"Failed to read clipboard contents": "Не удалось прочитать содержимое буфера обмена", "Failed to read clipboard contents": "Не удалось прочитать содержимое буфера обмена",
"Failed to save connections": "", "Failed to save connections": "Не удалось сохранить подключения",
"Failed to save models configuration": "Не удалось сохранить конфигурацию моделей", "Failed to save models configuration": "Не удалось сохранить конфигурацию моделей",
"Failed to update settings": "Не удалось обновить настройки", "Failed to update settings": "Не удалось обновить настройки",
"Failed to upload file.": "Не удалось загрузить файл.", "Failed to upload file.": "Не удалось загрузить файл.",
@ -535,7 +535,7 @@
"Forge new paths": "Прокладывайте новые пути", "Forge new paths": "Прокладывайте новые пути",
"Form": "Форма", "Form": "Форма",
"Format your variables using brackets like this:": "Отформатируйте переменные, используя такие : скобки", "Format your variables using brackets like this:": "Отформатируйте переменные, используя такие : скобки",
"Forwards system user session credentials to authenticate": "", "Forwards system user session credentials to authenticate": "Перенаправляет учетные данные сеанса системного пользователя для проверки подлинности",
"Frequency Penalty": "Штраф за частоту", "Frequency Penalty": "Штраф за частоту",
"Full Context Mode": "Режим полного контекста", "Full Context Mode": "Режим полного контекста",
"Function": "Функция", "Function": "Функция",
@ -581,7 +581,7 @@
"Hex Color": "Цвет Hex", "Hex Color": "Цвет Hex",
"Hex Color - Leave empty for default color": "Цвет Hex - оставьте пустым значение цвета по умолчанию", "Hex Color - Leave empty for default color": "Цвет Hex - оставьте пустым значение цвета по умолчанию",
"Hide": "Скрыть", "Hide": "Скрыть",
"Hide Model": "", "Hide Model": "Скрыть модель",
"Home": "Домой", "Home": "Домой",
"Host": "Хост", "Host": "Хост",
"How can I help you today?": "Чем я могу помочь вам сегодня?", "How can I help you today?": "Чем я могу помочь вам сегодня?",
@ -612,14 +612,14 @@
"Include `--api` flag when running stable-diffusion-webui": "Добавьте флаг `--api` при запуске stable-diffusion-webui", "Include `--api` flag when running stable-diffusion-webui": "Добавьте флаг `--api` при запуске stable-diffusion-webui",
"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Влияет на то, насколько быстро алгоритм реагирует на обратную связь из сгенерированного текста. Более низкая скорость обучения приведет к более медленной корректировке, в то время как более высокая скорость обучения сделает алгоритм более отзывчивым.", "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Влияет на то, насколько быстро алгоритм реагирует на обратную связь из сгенерированного текста. Более низкая скорость обучения приведет к более медленной корректировке, в то время как более высокая скорость обучения сделает алгоритм более отзывчивым.",
"Info": "Информация", "Info": "Информация",
"Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Вводите весь контент в качестве контекста для комплексной обработки, это рекомендуется для сложных запросов.",
"Input commands": "Введите команды", "Input commands": "Введите команды",
"Install from Github URL": "Установка с URL-адреса Github", "Install from Github URL": "Установка с URL-адреса Github",
"Instant Auto-Send After Voice Transcription": "Мгновенная автоматическая отправка после расшифровки голоса", "Instant Auto-Send After Voice Transcription": "Мгновенная автоматическая отправка после расшифровки голоса",
"Integration": "Интеграция", "Integration": "Интеграция",
"Interface": "Интерфейс", "Interface": "Интерфейс",
"Invalid file format.": "Неверный формат файла.", "Invalid file format.": "Неверный формат файла.",
"Invalid JSON schema": "", "Invalid JSON schema": "Недопустимая схема JSON",
"Invalid Tag": "Недопустимый тег", "Invalid Tag": "Недопустимый тег",
"is typing...": "печатает...", "is typing...": "печатает...",
"January": "Январь", "January": "Январь",
@ -641,7 +641,7 @@
"Knowledge Access": "Доступ к Знаниям", "Knowledge Access": "Доступ к Знаниям",
"Knowledge created successfully.": "Знания созданы успешно.", "Knowledge created successfully.": "Знания созданы успешно.",
"Knowledge deleted successfully.": "Знания успешно удалены.", "Knowledge deleted successfully.": "Знания успешно удалены.",
"Knowledge Public Sharing": "", "Knowledge Public Sharing": "Публичный обмен знаниями",
"Knowledge reset successfully.": "Знания успешно сброшены.", "Knowledge reset successfully.": "Знания успешно сброшены.",
"Knowledge updated successfully": "Знания успешно обновлены", "Knowledge updated successfully": "Знания успешно обновлены",
"Kokoro.js (Browser)": "Kokoro.js (Браузер)", "Kokoro.js (Browser)": "Kokoro.js (Браузер)",
@ -655,10 +655,10 @@
"LDAP": "", "LDAP": "",
"LDAP server updated": "LDAP сервер обновлен", "LDAP server updated": "LDAP сервер обновлен",
"Leaderboard": "Таблица Лидеров", "Leaderboard": "Таблица Лидеров",
"Learn more about OpenAPI tool servers.": "", "Learn more about OpenAPI tool servers.": "Узнайте больше о серверах инструментов OpenAPI.",
"Leave empty for unlimited": "Оставьте пустым для неограниченного", "Leave empty for unlimited": "Оставьте пустым для неограниченного",
"Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "", "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Оставьте пустым, чтобы включить все модели из конечной точки \"{{url}}/api/tags\"",
"Leave empty to include all models from \"{{url}}/models\" endpoint": "", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Оставьте поле пустым, чтобы включить все модели из конечной точки \"{{url}}/models\"",
"Leave empty to include all models or select specific models": "Оставьте поле пустым, чтобы включить все модели или выбрать конкретные модели", "Leave empty to include all models or select specific models": "Оставьте поле пустым, чтобы включить все модели или выбрать конкретные модели",
"Leave empty to use the default prompt, or enter a custom prompt": "Оставьте пустым, чтобы использовать промпт по умолчанию, или введите пользовательский промпт", "Leave empty to use the default prompt, or enter a custom prompt": "Оставьте пустым, чтобы использовать промпт по умолчанию, или введите пользовательский промпт",
"Leave model field empty to use the default model.": "Оставьте поле model пустым, чтобы использовать модель по умолчанию.", "Leave model field empty to use the default model.": "Оставьте поле model пустым, чтобы использовать модель по умолчанию.",
@ -668,8 +668,8 @@
"Llama.cpp": "", "Llama.cpp": "",
"LLMs can make mistakes. Verify important information.": "LLMs могут допускать ошибки. Проверяйте важную информацию.", "LLMs can make mistakes. Verify important information.": "LLMs могут допускать ошибки. Проверяйте важную информацию.",
"Loader": "Загрузчик", "Loader": "Загрузчик",
"Loading Kokoro.js...": "", "Loading Kokoro.js...": "Загрузка Kokoro.js",
"Local": "", "Local": "Локально",
"Local Models": "Локальные модели", "Local Models": "Локальные модели",
"Location access not allowed": "Доступ к местоположению запрещен", "Location access not allowed": "Доступ к местоположению запрещен",
"Logit Bias": "", "Logit Bias": "",
@ -707,15 +707,15 @@
"Mirostat Eta": "Mirostat Eta", "Mirostat Eta": "Mirostat Eta",
"Mirostat Tau": "Mirostat Tau", "Mirostat Tau": "Mirostat Tau",
"Mistral OCR": "", "Mistral OCR": "",
"Mistral OCR API Key required.": "", "Mistral OCR API Key required.": "Требуется API ключ Mistral OCR.",
"Model": "Модель", "Model": "Модель",
"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 {{name}} is now hidden": "", "Model {{name}} is now hidden": "Модель {{name}} теперь скрыта",
"Model {{name}} is now visible": "", "Model {{name}} is now visible": "Модель {{name}} теперь видна",
"Model accepts image inputs": "Модель принимает изображения как входные данные", "Model accepts image inputs": "Модель принимает изображения как входные данные",
"Model created successfully!": "Модель успешно создана!", "Model created successfully!": "Модель успешно создана!",
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "Обнаружен путь к файловой системе модели. Для обновления требуется краткое имя модели, не удается продолжить.", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Обнаружен путь к файловой системе модели. Для обновления требуется краткое имя модели, не удается продолжить.",
@ -731,7 +731,7 @@
"Models": "Модели", "Models": "Модели",
"Models Access": "Доступ к Моделям", "Models Access": "Доступ к Моделям",
"Models configuration saved successfully": "Конфигурация модели успешно сохранена.", "Models configuration saved successfully": "Конфигурация модели успешно сохранена.",
"Models Public Sharing": "", "Models Public Sharing": "Публичный обмен моделями",
"Mojeek Search API Key": "Ключ API для поиска Mojeek", "Mojeek Search API Key": "Ключ API для поиска Mojeek",
"more": "больше", "more": "больше",
"More": "Больше", "More": "Больше",
@ -794,7 +794,7 @@
"Open file": "Открыть файл", "Open file": "Открыть файл",
"Open in full screen": "Открыть на весь экран", "Open in full screen": "Открыть на весь экран",
"Open new chat": "Открыть новый чат", "Open new chat": "Открыть новый чат",
"Open WebUI can use tools provided by any OpenAPI server.": "", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI может использовать инструменты, предоставляемые любым сервером OpenAPI.",
"Open WebUI uses faster-whisper internally.": "Open WebUI использует более быстрый внутренний интерфейс whisper.", "Open WebUI uses faster-whisper internally.": "Open WebUI использует более быстрый внутренний интерфейс whisper.",
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "В Open WebUI используются встраиваемые движки генерации речи SpeechT5 и CMU Arctic.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "В Open WebUI используются встраиваемые движки генерации речи SpeechT5 и CMU Arctic.",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Версия Open WebUI (v{{OPEN_WEBUI_VERSION}}) ниже требуемой версии (v{{REQUIRED_VERSION}})", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Версия Open WebUI (v{{OPEN_WEBUI_VERSION}}) ниже требуемой версии (v{{REQUIRED_VERSION}})",
@ -804,7 +804,7 @@
"OpenAI API Key is required.": "Требуется ключ API OpenAI.", "OpenAI API Key is required.": "Требуется ключ API OpenAI.",
"OpenAI API settings updated": "Настройки OpenAI API обновлены", "OpenAI API settings updated": "Настройки OpenAI API обновлены",
"OpenAI URL/Key required.": "Требуется URL-адрес API OpenAI или ключ API.", "OpenAI URL/Key required.": "Требуется URL-адрес API OpenAI или ключ API.",
"openapi.json Path": "", "openapi.json Path": "Путь openapi.json",
"or": "или", "or": "или",
"Organize your users": "Организуйте своих пользователей", "Organize your users": "Организуйте своих пользователей",
"Other": "Прочее", "Other": "Прочее",
@ -836,8 +836,8 @@
"Please carefully review the following warnings:": "Пожалуйста, внимательно ознакомьтесь со следующими предупреждениями:", "Please carefully review the following warnings:": "Пожалуйста, внимательно ознакомьтесь со следующими предупреждениями:",
"Please do not close the settings page while loading the model.": "Пожалуйста, не закрывайте страницу настроек во время загрузки модели.", "Please do not close the settings page while loading the model.": "Пожалуйста, не закрывайте страницу настроек во время загрузки модели.",
"Please enter a prompt": "Пожалуйста, введите подсказку", "Please enter a prompt": "Пожалуйста, введите подсказку",
"Please enter a valid path": "", "Please enter a valid path": "Пожалуйста, введите правильный путь",
"Please enter a valid URL": "", "Please enter a valid URL": "Пожалуйста, введите правильный URL",
"Please fill in all fields.": "Пожалуйста, заполните все поля.", "Please fill in all fields.": "Пожалуйста, заполните все поля.",
"Please select a model first.": "Пожалуйста, сначала выберите модель.", "Please select a model first.": "Пожалуйста, сначала выберите модель.",
"Please select a model.": "Пожалуйста, выберите модель.", "Please select a model.": "Пожалуйста, выберите модель.",
@ -849,7 +849,7 @@
"Presence Penalty": "Штраф за присутствие", "Presence Penalty": "Штраф за присутствие",
"Previous 30 days": "Предыдущие 30 дней", "Previous 30 days": "Предыдущие 30 дней",
"Previous 7 days": "Предыдущие 7 дней", "Previous 7 days": "Предыдущие 7 дней",
"Private": "", "Private": "Частное",
"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)": "Промпт (например, Расскажи мне интересный факт о Римской империи)",
@ -860,8 +860,8 @@
"Prompt updated successfully": "Промпт успешно обновлён", "Prompt updated successfully": "Промпт успешно обновлён",
"Prompts": "Промпты", "Prompts": "Промпты",
"Prompts Access": "Доступ к промптам", "Prompts Access": "Доступ к промптам",
"Prompts Public Sharing": "", "Prompts Public Sharing": "Публичный обмен промптами",
"Public": "", "Public": "Публичное",
"Pull \"{{searchValue}}\" from Ollama.com": "Загрузить \"{{searchValue}}\" с Ollama.com", "Pull \"{{searchValue}}\" from Ollama.com": "Загрузить \"{{searchValue}}\" с Ollama.com",
"Pull a model from Ollama.com": "Загрузить модель с Ollama.com", "Pull a model from Ollama.com": "Загрузить модель с Ollama.com",
"Query Generation Prompt": "Запрос на генерацию промпта", "Query Generation Prompt": "Запрос на генерацию промпта",
@ -878,6 +878,8 @@
"References from": "Отсылки к", "References from": "Отсылки к",
"Refused when it shouldn't have": "Отказано в доступе, когда это не должно было произойти", "Refused when it shouldn't have": "Отказано в доступе, когда это не должно было произойти",
"Regenerate": "Перегенерировать", "Regenerate": "Перегенерировать",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Примечания к выпуску", "Release Notes": "Примечания к выпуску",
"Relevance": "Актуальность", "Relevance": "Актуальность",
"Remove": "Удалить", "Remove": "Удалить",
@ -993,11 +995,11 @@
"Share": "Поделиться", "Share": "Поделиться",
"Share Chat": "Поделиться чатом", "Share Chat": "Поделиться чатом",
"Share to Open WebUI Community": "Поделиться с сообществом OpenWebUI", "Share to Open WebUI Community": "Поделиться с сообществом OpenWebUI",
"Sharing Permissions": "", "Sharing Permissions": "Разрешения на общий доступ",
"Show": "Показать", "Show": "Показать",
"Show \"What's New\" modal on login": "Показывать окно «Что нового» при входе в систему", "Show \"What's New\" modal on login": "Показывать окно «Что нового» при входе в систему",
"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!": "Поддержите нас!", "Show your support!": "Поддержите нас!",
"Showcased creativity": "Продемонстрирован творческий подход", "Showcased creativity": "Продемонстрирован творческий подход",
@ -1024,11 +1026,11 @@
"Suggested": "Предложено", "Suggested": "Предложено",
"Support": "Поддержать", "Support": "Поддержать",
"Support this plugin:": "Поддержите этот плагин", "Support this plugin:": "Поддержите этот плагин",
"Sync directory": "", "Sync directory": "Каталог синхронизации",
"System": "Система", "System": "Система",
"System Instructions": "Системные инструкции", "System Instructions": "Системные инструкции",
"System Prompt": "Системный промпт", "System Prompt": "Системный промпт",
"Tags": "", "Tags": "Теги",
"Tags Generation": "Генерация тегов", "Tags Generation": "Генерация тегов",
"Tags Generation Prompt": "Промпт для генерации тегов", "Tags Generation Prompt": "Промпт для генерации тегов",
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "Выборка без хвостов используется для уменьшения влияния менее вероятных токенов на выходные данные. Более высокое значение (например, 2.0) еще больше уменьшит влияние, в то время как значение 1.0 отключает эту настройку.", "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "Выборка без хвостов используется для уменьшения влияния менее вероятных токенов на выходные данные. Более высокое значение (например, 2.0) еще больше уменьшит влияние, в то время как значение 1.0 отключает эту настройку.",
@ -1059,8 +1061,8 @@
"Theme": "Тема", "Theme": "Тема",
"Thinking...": "Думаю...", "Thinking...": "Думаю...",
"This action cannot be undone. Do you wish to continue?": "Это действие нельзя отменить. Вы хотите продолжить?", "This action cannot be undone. Do you wish to continue?": "Это действие нельзя отменить. Вы хотите продолжить?",
"This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Этот канал был создан {{createdAt}}. Это самое начало канала {{channelName}}.",
"This chat wont appear in history and your messages will not be saved.": "", "This chat wont appear in history and your messages will not be saved.": "Этот чат не появится в истории, и ваши сообщения не будут сохранены.",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Это обеспечивает сохранение ваших ценных разговоров в безопасной базе данных на вашем сервере. Спасибо!", "This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Это обеспечивает сохранение ваших ценных разговоров в безопасной базе данных на вашем сервере. Спасибо!",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Это экспериментальная функция, она может работать не так, как ожидалось, и может быть изменена в любое время.", "This is an experimental feature, it may not function as expected and is subject to change at any time.": "Это экспериментальная функция, она может работать не так, как ожидалось, и может быть изменена в любое время.",
"This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Этот параметр определяет, сколько токенов сохраняется при обновлении контекста. Например, если задано значение 2, будут сохранены последние 2 токена контекста беседы. Сохранение контекста может помочь сохранить непрерывность беседы, но может уменьшить возможность отвечать на новые темы.", "This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Этот параметр определяет, сколько токенов сохраняется при обновлении контекста. Например, если задано значение 2, будут сохранены последние 2 токена контекста беседы. Сохранение контекста может помочь сохранить непрерывность беседы, но может уменьшить возможность отвечать на новые темы.",
@ -1074,7 +1076,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Это сбросит базу знаний и синхронизирует все файлы. Хотите продолжить?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Это сбросит базу знаний и синхронизирует все файлы. Хотите продолжить?",
"Thorough explanation": "Подробное объяснение", "Thorough explanation": "Подробное объяснение",
"Thought for {{DURATION}}": "Рассуждаю {{DURATION}}", "Thought for {{DURATION}}": "Рассуждаю {{DURATION}}",
"Thought for {{DURATION}} seconds": "Рассуждаю {{DURATION}} секунд(ы)", "Thought for {{DURATION}} seconds": "Рассуждал {{DURATION}} секунд",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Требуется URL-адрес сервера Tika.", "Tika Server URL required.": "Требуется URL-адрес сервера Tika.",
"Tiktoken": "", "Tiktoken": "",
@ -1108,7 +1110,7 @@
"Tool ID": "ID Инструмента", "Tool ID": "ID Инструмента",
"Tool imported successfully": "Инструмент успешно импортирован", "Tool imported successfully": "Инструмент успешно импортирован",
"Tool Name": "Имя Инструмента", "Tool Name": "Имя Инструмента",
"Tool Servers": "", "Tool Servers": "Сервер Инструмента",
"Tool updated successfully": "Инструмент успешно обновлен", "Tool updated successfully": "Инструмент успешно обновлен",
"Tools": "Инструменты", "Tools": "Инструменты",
"Tools Access": "Доступ к инструментам", "Tools Access": "Доступ к инструментам",
@ -1116,7 +1118,7 @@
"Tools Function Calling Prompt": "Промпт на вызов функции Инструменты", "Tools Function Calling Prompt": "Промпт на вызов функции Инструменты",
"Tools have a function calling system that allows arbitrary code execution": "Инструменты имеют систему вызова функций, которая позволяет выполнять произвольный код", "Tools have a function calling system that allows arbitrary code execution": "Инструменты имеют систему вызова функций, которая позволяет выполнять произвольный код",
"Tools have a function calling system that allows arbitrary code execution.": "Инструменты имеют систему вызова функций, которая позволяет выполнять произвольный код.", "Tools have a function calling system that allows arbitrary code execution.": "Инструменты имеют систему вызова функций, которая позволяет выполнять произвольный код.",
"Tools Public Sharing": "", "Tools Public Sharing": "Публичный обмен инструментами",
"Top K": "Top K", "Top K": "Top K",
"Top K Reranker": "", "Top K Reranker": "",
"Top P": "Top P", "Top P": "Top P",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Использовать Gravatar", "Use Gravatar": "Использовать Gravatar",
"Use groups to group your users and assign permissions.": "Используйте группы, чтобы группировать пользователей и назначать разрешения.", "Use groups to group your users and assign permissions.": "Используйте группы, чтобы группировать пользователей и назначать разрешения.",
"Use Initials": "Использовать инициалы", "Use Initials": "Использовать инициалы",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "пользователь", "user": "пользователь",
@ -1174,11 +1178,11 @@
"Valves updated successfully": "Вентили успешно обновлены", "Valves updated successfully": "Вентили успешно обновлены",
"variable": "переменная", "variable": "переменная",
"variable to have them replaced with clipboard content.": "переменную, чтобы заменить их содержимым буфера обмена.", "variable to have them replaced with clipboard content.": "переменную, чтобы заменить их содержимым буфера обмена.",
"Verify Connection": "", "Verify Connection": "Проверить подключение",
"Version": "Версия", "Version": "Версия",
"Version {{selectedVersion}} of {{totalVersions}}": "Версия {{selectedVersion}} из {{totalVersions}}", "Version {{selectedVersion}} of {{totalVersions}}": "Версия {{selectedVersion}} из {{totalVersions}}",
"View Replies": "С ответами", "View Replies": "С ответами",
"View Result from **{{NAME}}**": "", "View Result from **{{NAME}}**": "Просмотр результата от **{{NAME}}**",
"Visibility": "Видимость", "Visibility": "Видимость",
"Voice": "Голос", "Voice": "Голос",
"Voice Input": "Ввод голоса", "Voice Input": "Ввод голоса",
@ -1196,7 +1200,7 @@
"Webhook URL": "URL-адрес веб-хука", "Webhook URL": "URL-адрес веб-хука",
"WebUI Settings": "Настройки WebUI", "WebUI Settings": "Настройки WebUI",
"WebUI URL": "", "WebUI URL": "",
"WebUI will make requests to \"{{url}}\"": "", "WebUI will make requests to \"{{url}}\"": "WebUI будет отправлять запросы к \"{{url}}\"",
"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI будет отправлять запросы к \"{{url}}/api/chat\"", "WebUI will make requests to \"{{url}}/api/chat\"": "WebUI будет отправлять запросы к \"{{url}}/api/chat\"",
"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI будет отправлять запросы к \"{{url}}/chat/completions\"", "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI будет отправлять запросы к \"{{url}}/chat/completions\"",
"What are you trying to achieve?": "Чего вы пытаетесь достичь?", "What are you trying to achieve?": "Чего вы пытаетесь достичь?",

View File

@ -878,6 +878,8 @@
"References from": "Referencie z", "References from": "Referencie z",
"Refused when it shouldn't have": "Odmietnuté, keď nemalo byť.", "Refused when it shouldn't have": "Odmietnuté, keď nemalo byť.",
"Regenerate": "Regenerovať", "Regenerate": "Regenerovať",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Záznamy o vydaní", "Release Notes": "Záznamy o vydaní",
"Relevance": "Relevancia", "Relevance": "Relevancia",
"Remove": "Odstrániť", "Remove": "Odstrániť",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Použiť Gravatar", "Use Gravatar": "Použiť Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "Použiť iniciály", "Use Initials": "Použiť iniciály",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "používateľ", "user": "používateľ",

View File

@ -878,6 +878,8 @@
"References from": "Референце од", "References from": "Референце од",
"Refused when it shouldn't have": "Одбијено када није требало", "Refused when it shouldn't have": "Одбијено када није требало",
"Regenerate": "Поново створи", "Regenerate": "Поново створи",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Напомене о издању", "Release Notes": "Напомене о издању",
"Relevance": "Примењивост", "Relevance": "Примењивост",
"Remove": "Уклони", "Remove": "Уклони",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Користи Граватар", "Use Gravatar": "Користи Граватар",
"Use groups to group your users and assign permissions.": "Користите групе да бисте разврстали ваше кориснике и доделили овлашћења.", "Use groups to group your users and assign permissions.": "Користите групе да бисте разврстали ваше кориснике и доделили овлашћења.",
"Use Initials": "Користи иницијале", "Use Initials": "Користи иницијале",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "корисник", "user": "корисник",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "Avvisades när det inte borde ha gjort det", "Refused when it shouldn't have": "Avvisades när det inte borde ha gjort det",
"Regenerate": "Regenerera", "Regenerate": "Regenerera",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Versionsinformation", "Release Notes": "Versionsinformation",
"Relevance": "", "Relevance": "",
"Remove": "Ta bort", "Remove": "Ta bort",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Använd Gravatar", "Use Gravatar": "Använd Gravatar",
"Use groups to group your users and assign permissions.": "Använd grupper för att gruppera dina användare och tilldela behörigheter.", "Use groups to group your users and assign permissions.": "Använd grupper för att gruppera dina användare och tilldela behörigheter.",
"Use Initials": "Använd initialer", "Use Initials": "Använd initialer",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "användare", "user": "användare",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "ปฏิเสธเมื่อไม่ควรทำ", "Refused when it shouldn't have": "ปฏิเสธเมื่อไม่ควรทำ",
"Regenerate": "สร้างใหม่", "Regenerate": "สร้างใหม่",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "บันทึกรุ่น", "Release Notes": "บันทึกรุ่น",
"Relevance": "", "Relevance": "",
"Remove": "ลบ", "Remove": "ลบ",
@ -1158,6 +1160,8 @@
"Use Gravatar": "ใช้ Gravatar", "Use Gravatar": "ใช้ Gravatar",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "ใช้ตัวย่อ", "Use Initials": "ใช้ตัวย่อ",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "ผู้ใช้", "user": "ผู้ใช้",

View File

@ -878,6 +878,8 @@
"References from": "", "References from": "",
"Refused when it shouldn't have": "", "Refused when it shouldn't have": "",
"Regenerate": "", "Regenerate": "",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "", "Release Notes": "",
"Relevance": "", "Relevance": "",
"Remove": "", "Remove": "",
@ -1158,6 +1160,8 @@
"Use Gravatar": "", "Use Gravatar": "",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "", "Use Initials": "",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "", "use_mlock (Ollama)": "",
"use_mmap (Ollama)": "", "use_mmap (Ollama)": "",
"user": "", "user": "",

View File

@ -878,6 +878,8 @@
"References from": "Referanslar arasından", "References from": "Referanslar arasından",
"Refused when it shouldn't have": "Reddedilmemesi gerekirken reddedildi", "Refused when it shouldn't have": "Reddedilmemesi gerekirken reddedildi",
"Regenerate": "Tekrar Oluştur", "Regenerate": "Tekrar Oluştur",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Sürüm Notları", "Release Notes": "Sürüm Notları",
"Relevance": "İlgili", "Relevance": "İlgili",
"Remove": "Kaldır", "Remove": "Kaldır",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Gravatar Kullan", "Use Gravatar": "Gravatar Kullan",
"Use groups to group your users and assign permissions.": "Kullanıcılarınızı gruplamak ve izinler atamak için grupları kullanın.", "Use groups to group your users and assign permissions.": "Kullanıcılarınızı gruplamak ve izinler atamak için grupları kullanın.",
"Use Initials": "Baş Harfleri Kullan", "Use Initials": "Baş Harfleri Kullan",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "kullanıcı", "user": "kullanıcı",

View File

@ -878,6 +878,8 @@
"References from": "Посилання з", "References from": "Посилання з",
"Refused when it shouldn't have": "Відмовив, коли не мав би", "Refused when it shouldn't have": "Відмовив, коли не мав би",
"Regenerate": "Регенерувати", "Regenerate": "Регенерувати",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Нотатки до випуску", "Release Notes": "Нотатки до випуску",
"Relevance": "Актуальність", "Relevance": "Актуальність",
"Remove": "Видалити", "Remove": "Видалити",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Змінити аватар", "Use Gravatar": "Змінити аватар",
"Use groups to group your users and assign permissions.": "Використовуйте групи, щоб об’єднувати користувачів і призначати дозволи.", "Use groups to group your users and assign permissions.": "Використовуйте групи, щоб об’єднувати користувачів і призначати дозволи.",
"Use Initials": "Використовувати ініціали", "Use Initials": "Використовувати ініціали",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "користувач", "user": "користувач",

View File

@ -878,6 +878,8 @@
"References from": "سے حوالہ جات", "References from": "سے حوالہ جات",
"Refused when it shouldn't have": "جب انکار نہیں ہونا چاہیے تھا، انکار کر دیا", "Refused when it shouldn't have": "جب انکار نہیں ہونا چاہیے تھا، انکار کر دیا",
"Regenerate": "دوبارہ تخلیق کریں", "Regenerate": "دوبارہ تخلیق کریں",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "ریلیز نوٹس", "Release Notes": "ریلیز نوٹس",
"Relevance": "موزونیت", "Relevance": "موزونیت",
"Remove": "ہٹا دیں", "Remove": "ہٹا دیں",
@ -1158,6 +1160,8 @@
"Use Gravatar": "گراویٹر استعمال کریں", "Use Gravatar": "گراویٹر استعمال کریں",
"Use groups to group your users and assign permissions.": "", "Use groups to group your users and assign permissions.": "",
"Use Initials": "ابتدائیات استعمال کریں", "Use Initials": "ابتدائیات استعمال کریں",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"use_mlock (Ollama)": "استعمال کریں_mlock (Ollama)", "use_mlock (Ollama)": "استعمال کریں_mlock (Ollama)",
"use_mmap (Ollama)": "استعمال_mmap (Ollama)", "use_mmap (Ollama)": "استعمال_mmap (Ollama)",
"user": "صارف", "user": "صارف",

View File

@ -878,6 +878,8 @@
"References from": "Tham khảo từ", "References from": "Tham khảo từ",
"Refused when it shouldn't have": "Từ chối trả lời mà nhẽ không nên làm vậy", "Refused when it shouldn't have": "Từ chối trả lời mà nhẽ không nên làm vậy",
"Regenerate": "Tạo sinh lại câu trả lời", "Regenerate": "Tạo sinh lại câu trả lời",
"Reindex": "",
"Reindex Knowledge Base Vectors": "",
"Release Notes": "Mô tả những cập nhật mới", "Release Notes": "Mô tả những cập nhật mới",
"Relevance": "Mức độ liên quan", "Relevance": "Mức độ liên quan",
"Remove": "Xóa", "Remove": "Xóa",
@ -1158,6 +1160,8 @@
"Use Gravatar": "Sử dụng Gravatar", "Use Gravatar": "Sử dụng Gravatar",
"Use groups to group your users and assign permissions.": "Sử dụng nhóm để nhóm người dùng của bạn và gán quyền.", "Use groups to group your users and assign permissions.": "Sử dụng nhóm để nhóm người dùng của bạn và gán quyền.",
"Use Initials": "Sử dụng tên viết tắt", "Use Initials": "Sử dụng tên viết tắt",
"Use no proxy to fetch page contents.": "",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "",
"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": "Người sử dụng", "user": "Người sử dụng",

View File

@ -111,11 +111,11 @@
"Auth": "授权", "Auth": "授权",
"Authenticate": "认证", "Authenticate": "认证",
"Authentication": "身份验证", "Authentication": "身份验证",
"Auto": "", "Auto": "自动",
"Auto-Copy Response to Clipboard": "自动复制回复到剪贴板", "Auto-Copy Response to Clipboard": "自动复制回复到剪贴板",
"Auto-playback response": "自动念出回复内容", "Auto-playback response": "自动念出回复内容",
"Autocomplete Generation": "输入框内容猜测补全", "Autocomplete Generation": "输入框内容自动补全",
"Autocomplete Generation Input Max Length": "输入框内容猜测补全输入最大长度", "Autocomplete Generation Input Max Length": "输入框内容自动补全输入最大长度",
"Automatic1111": "Automatic1111", "Automatic1111": "Automatic1111",
"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Api 鉴权字符串", "AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Api 鉴权字符串",
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 基础地址", "AUTOMATIC1111 Base URL": "AUTOMATIC1111 基础地址",
@ -154,7 +154,7 @@
"Channel Name": "频道名称", "Channel Name": "频道名称",
"Channels": "频道", "Channels": "频道",
"Character": "字符", "Character": "字符",
"Character limit for autocomplete generation input": "输入框内容猜测补全输入的字符限制", "Character limit for autocomplete generation input": "输入框内容自动补全输入的字符限制",
"Chart new frontiers": "开拓新领域", "Chart new frontiers": "开拓新领域",
"Chat": "对话", "Chat": "对话",
"Chat Background Image": "对话背景图片", "Chat Background Image": "对话背景图片",
@ -375,14 +375,14 @@
"Embedding Model Engine": "语义向量模型引擎", "Embedding Model Engine": "语义向量模型引擎",
"Embedding model set to \"{{embedding_model}}\"": "语义向量模型设置为 \"{{embedding_model}}\"", "Embedding model set to \"{{embedding_model}}\"": "语义向量模型设置为 \"{{embedding_model}}\"",
"Enable API Key": "启用 API 密钥", "Enable API Key": "启用 API 密钥",
"Enable autocomplete generation for chat messages": "启用聊天消息的输入框内容猜测补全", "Enable autocomplete generation for chat messages": "启用聊天消息的输入框内容自动补全",
"Enable Code Execution": "启用代码执行", "Enable Code Execution": "启用代码执行",
"Enable Code Interpreter": "启用代码解释器", "Enable Code Interpreter": "启用代码解释器",
"Enable Community Sharing": "启用分享至社区", "Enable Community Sharing": "启用分享至社区",
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "启用内存锁定mlock以防止模型数据被交换出RAM。此选项将模型的工作集页面锁定在RAM中确保它们不会被交换到磁盘。这可以通过避免页面错误和确保快速数据访问来帮助维持性能。", "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "启用内存锁定mlock以防止模型数据被交换出RAM。此选项将模型的工作集页面锁定在RAM中确保它们不会被交换到磁盘。这可以通过避免页面错误和确保快速数据访问来帮助维持性能。",
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "启用内存映射mmap以加载模型数据。此选项允许系统通过将磁盘文件视为在RAM中来使用磁盘存储作为RAM的扩展。这可以通过更快的数据访问来提高模型性能。然而它可能无法在所有系统上正常工作并且可能会消耗大量磁盘空间。", "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "启用内存映射mmap以加载模型数据。此选项允许系统通过将磁盘文件视为在RAM中来使用磁盘存储作为RAM的扩展。这可以通过更快的数据访问来提高模型性能。然而它可能无法在所有系统上正常工作并且可能会消耗大量磁盘空间。",
"Enable Message Rating": "启用回复评价", "Enable Message Rating": "启用回复评价",
"Enable Mirostat sampling for controlling perplexity.": "启用Mirostat采样以控制困惑度", "Enable Mirostat sampling for controlling perplexity.": "启用 Mirostat 采样以控制困惑度",
"Enable New Sign Ups": "允许新用户注册", "Enable New Sign Ups": "允许新用户注册",
"Enabled": "启用", "Enabled": "启用",
"Enforce Temporary Chat": "强制临时聊天", "Enforce Temporary Chat": "强制临时聊天",
@ -424,6 +424,8 @@
"Enter Mojeek Search API Key": "输入 Mojeek Search API 密钥", "Enter Mojeek Search API Key": "输入 Mojeek Search API 密钥",
"Enter Number of Steps (e.g. 50)": "输入步骤数 (Steps) (例如50)", "Enter Number of Steps (e.g. 50)": "输入步骤数 (Steps) (例如50)",
"Enter Perplexity API Key": "输入 Perplexity API 密钥", "Enter Perplexity API Key": "输入 Perplexity API 密钥",
"Enter Sougou Search API sID": "输入搜狗搜索 API 的 Secret ID",
"Enter Sougou Search API SK": "输入搜狗搜索 API 的 Secret Key",
"Enter proxy URL (e.g. https://user:password@host:port)": "输入代理 URL (例如https://用户名:密码@主机名:端口)", "Enter proxy URL (e.g. https://user:password@host:port)": "输入代理 URL (例如https://用户名:密码@主机名:端口)",
"Enter reasoning effort": "设置推理努力", "Enter reasoning effort": "设置推理努力",
"Enter Sampler (e.g. Euler a)": "输入 Sampler (例如Euler a)", "Enter Sampler (e.g. Euler a)": "输入 Sampler (例如Euler a)",
@ -655,7 +657,7 @@
"LDAP": "LDAP", "LDAP": "LDAP",
"LDAP server updated": "LDAP 服务器已更新", "LDAP server updated": "LDAP 服务器已更新",
"Leaderboard": "排行榜", "Leaderboard": "排行榜",
"Learn more about OpenAPI tool servers.": "", "Learn more about OpenAPI tool servers.": "进一步了解 OpenAPI 工具服务器。",
"Leave empty for unlimited": "留空表示无限制", "Leave empty for unlimited": "留空表示无限制",
"Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "留空以包含来自 \"{{url}}/api/tags\" 端点的所有模型", "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "留空以包含来自 \"{{url}}/api/tags\" 端点的所有模型",
"Leave empty to include all models from \"{{url}}/models\" endpoint": "留空以包含来自 \"{{url}}/models\" 端点的所有模型", "Leave empty to include all models from \"{{url}}/models\" endpoint": "留空以包含来自 \"{{url}}/models\" 端点的所有模型",
@ -687,7 +689,7 @@
"Manage Pipelines": "管理 Pipeline", "Manage Pipelines": "管理 Pipeline",
"Manage Tool Servers": "管理工具服务器", "Manage Tool Servers": "管理工具服务器",
"March": "三月", "March": "三月",
"Max Tokens (num_predict)": "最大Token数量 (num_predict)", "Max Tokens (num_predict)": "最大 Token 数量 (num_predict)",
"Max Upload Count": "最大上传数量", "Max Upload Count": "最大上传数量",
"Max Upload Size": "最大上传大小", "Max Upload Size": "最大上传大小",
"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 个模型,请稍后重试。",
@ -771,7 +773,7 @@
"Notifications": "桌面通知", "Notifications": "桌面通知",
"November": "十一月", "November": "十一月",
"num_gpu (Ollama)": "num_gpu (Ollama)", "num_gpu (Ollama)": "num_gpu (Ollama)",
"num_thread (Ollama)": "num_threadOllama", "num_thread (Ollama)": "num_thread (Ollama)",
"OAuth ID": "OAuth ID", "OAuth ID": "OAuth ID",
"October": "十月", "October": "十月",
"Off": "关闭", "Off": "关闭",
@ -794,7 +796,7 @@
"Open file": "打开文件", "Open file": "打开文件",
"Open in full screen": "全屏打开", "Open in full screen": "全屏打开",
"Open new chat": "打开新对话", "Open new chat": "打开新对话",
"Open WebUI can use tools provided by any OpenAPI server.": "", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI 可使用任何 OpenAPI 服务器提供的工具。",
"Open WebUI uses faster-whisper internally.": "Open WebUI 使用内置 faster-whisper。", "Open WebUI uses faster-whisper internally.": "Open WebUI 使用内置 faster-whisper。",
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI 使用 SpeechT5 和 CMU Arctic speaker embedding。", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI 使用 SpeechT5 和 CMU Arctic speaker embedding。",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "当前 Open WebUI 版本 (v{{OPEN_WEBUI_VERSION}}) 低于所需的版本 (v{{REQUIRED_VERSION}})", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "当前 Open WebUI 版本 (v{{OPEN_WEBUI_VERSION}}) 低于所需的版本 (v{{REQUIRED_VERSION}})",
@ -822,6 +824,8 @@
"Permission denied when accessing microphone: {{error}}": "申请麦克风权限被拒绝:{{error}}", "Permission denied when accessing microphone: {{error}}": "申请麦克风权限被拒绝:{{error}}",
"Permissions": "权限", "Permissions": "权限",
"Perplexity API Key": "Perplexity API 密钥", "Perplexity API Key": "Perplexity API 密钥",
"Sougou Search API sID": "搜狗搜索 API 的 Secret ID",
"Sougou Search API SK": "搜狗搜索 API 的 Secret Key",
"Personalization": "个性化", "Personalization": "个性化",
"Pin": "置顶", "Pin": "置顶",
"Pinned": "已置顶", "Pinned": "已置顶",
@ -846,7 +850,7 @@
"Positive attitude": "积极的态度", "Positive attitude": "积极的态度",
"Prefix ID": "Prefix ID", "Prefix ID": "Prefix ID",
"Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID 用于通过为模型 ID 添加前缀来避免与其他连接发生冲突 - 留空则禁用此功能", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID 用于通过为模型 ID 添加前缀来避免与其他连接发生冲突 - 留空则禁用此功能",
"Presence Penalty": "重复惩罚Presence Penalty", "Presence Penalty": "重复惩罚 (Presence Penalty)",
"Previous 30 days": "过去 30 天", "Previous 30 days": "过去 30 天",
"Previous 7 days": "过去 7 天", "Previous 7 days": "过去 7 天",
"Private": "私有", "Private": "私有",
@ -878,6 +882,8 @@
"References from": "来自", "References from": "来自",
"Refused when it shouldn't have": "无理拒绝", "Refused when it shouldn't have": "无理拒绝",
"Regenerate": "重新生成", "Regenerate": "重新生成",
"Reindex": "重建索引",
"Reindex Knowledge Base Vectors": "重建知识库向量",
"Release Notes": "更新日志", "Release Notes": "更新日志",
"Relevance": "相关性", "Relevance": "相关性",
"Remove": "移除", "Remove": "移除",
@ -885,7 +891,7 @@
"Rename": "重命名", "Rename": "重命名",
"Reorder Models": "重新排序模型", "Reorder Models": "重新排序模型",
"Repeat Last N": "重复最后 N 次", "Repeat Last N": "重复最后 N 次",
"Repeat Penalty (Ollama)": "重复惩罚Ollama", "Repeat Penalty (Ollama)": "重复惩罚 (Ollama)",
"Reply in Thread": "在主题中回复", "Reply in Thread": "在主题中回复",
"Request Mode": "请求模式", "Request Mode": "请求模式",
"Reranking Model": "重排模型", "Reranking Model": "重排模型",
@ -1158,6 +1164,8 @@
"Use Gravatar": "使用来自 Gravatar 的头像", "Use Gravatar": "使用来自 Gravatar 的头像",
"Use groups to group your users and assign permissions.": "使用权限组来组织用户并分配权限。", "Use groups to group your users and assign permissions.": "使用权限组来组织用户并分配权限。",
"Use Initials": "使用首个字符作为头像", "Use Initials": "使用首个字符作为头像",
"Use no proxy to fetch page contents.": "不使用代理获取页面内容。",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "使用由 http_proxy 和 https_proxy 环境变量指定的代理获取页面内容。",
"use_mlock (Ollama)": "use_mlockOllama", "use_mlock (Ollama)": "use_mlockOllama",
"use_mmap (Ollama)": "use_mmap Ollama", "use_mmap (Ollama)": "use_mmap Ollama",
"user": "用户", "user": "用户",

View File

@ -878,6 +878,8 @@
"References from": "引用來源", "References from": "引用來源",
"Refused when it shouldn't have": "不應拒絕時拒絕了", "Refused when it shouldn't have": "不應拒絕時拒絕了",
"Regenerate": "重新產生", "Regenerate": "重新產生",
"Reindex": "重新索引",
"Reindex Knowledge Base Vectors": "重新索引知識庫向量",
"Release Notes": "釋出説明", "Release Notes": "釋出説明",
"Relevance": "相關性", "Relevance": "相關性",
"Remove": "移除", "Remove": "移除",
@ -1158,6 +1160,8 @@
"Use Gravatar": "使用 Gravatar", "Use Gravatar": "使用 Gravatar",
"Use groups to group your users and assign permissions.": "使用群組來組織您的使用者並分配權限。", "Use groups to group your users and assign permissions.": "使用群組來組織您的使用者並分配權限。",
"Use Initials": "使用姓名縮寫", "Use Initials": "使用姓名縮寫",
"Use no proxy to fetch page contents.": "不使用代理擷取頁面內容。",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "使用 http_proxy 和 https_proxy 環境變數指定的代理擷取頁面內容。",
"use_mlock (Ollama)": "使用 mlock (Ollama)", "use_mlock (Ollama)": "使用 mlock (Ollama)",
"use_mmap (Ollama)": "使用 mmap (Ollama)", "use_mmap (Ollama)": "使用 mmap (Ollama)",
"user": "使用者", "user": "使用者",

View File

@ -45,6 +45,7 @@
import AccountPending from '$lib/components/layout/Overlay/AccountPending.svelte'; import AccountPending from '$lib/components/layout/Overlay/AccountPending.svelte';
import UpdateInfoToast from '$lib/components/layout/UpdateInfoToast.svelte'; import UpdateInfoToast from '$lib/components/layout/UpdateInfoToast.svelte';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import Spinner from '$lib/components/common/Spinner.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -254,65 +255,70 @@
<div <div
class=" text-gray-700 dark:text-gray-100 bg-white dark:bg-gray-900 h-screen max-h-[100dvh] overflow-auto flex flex-row justify-end" class=" text-gray-700 dark:text-gray-100 bg-white dark:bg-gray-900 h-screen max-h-[100dvh] overflow-auto flex flex-row justify-end"
> >
{#if loaded} {#if !['user', 'admin'].includes($user?.role)}
{#if !['user', 'admin'].includes($user?.role)} <AccountPending />
<AccountPending /> {:else if localDBChats.length > 0}
{:else if localDBChats.length > 0} <div class="fixed w-full h-full flex z-50">
<div class="fixed w-full h-full flex z-50"> <div
<div class="absolute w-full h-full backdrop-blur-md bg-white/20 dark:bg-gray-900/50 flex justify-center"
class="absolute w-full h-full backdrop-blur-md bg-white/20 dark:bg-gray-900/50 flex justify-center" >
> <div class="m-auto pb-44 flex flex-col justify-center">
<div class="m-auto pb-44 flex flex-col justify-center"> <div class="max-w-md">
<div class="max-w-md"> <div class="text-center dark:text-white text-2xl font-medium z-50">
<div class="text-center dark:text-white text-2xl font-medium z-50"> Important Update<br /> Action Required for Chat Log Storage
Important Update<br /> Action Required for Chat Log Storage </div>
</div>
<div class=" mt-4 text-center text-sm dark:text-gray-200 w-full"> <div class=" mt-4 text-center text-sm dark:text-gray-200 w-full">
{$i18n.t( {$i18n.t(
"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"
)} )}
<span class="font-semibold dark:text-white" <span class="font-semibold dark:text-white"
>{$i18n.t('Settings')} > {$i18n.t('Chats')} > {$i18n.t('Import Chats')}</span >{$i18n.t('Settings')} > {$i18n.t('Chats')} > {$i18n.t('Import Chats')}</span
>. {$i18n.t( >. {$i18n.t(
'This ensures that your valuable conversations are securely saved to your backend database. Thank you!' 'This ensures that your valuable conversations are securely saved to your backend database. Thank you!'
)} )}
</div> </div>
<div class=" mt-6 mx-auto relative group w-fit"> <div class=" mt-6 mx-auto relative group w-fit">
<button <button
class="relative z-20 flex px-5 py-2 rounded-full bg-white border border-gray-100 dark:border-none hover:bg-gray-100 transition font-medium text-sm" class="relative z-20 flex px-5 py-2 rounded-full bg-white border border-gray-100 dark:border-none hover:bg-gray-100 transition font-medium text-sm"
on:click={async () => { on:click={async () => {
let blob = new Blob([JSON.stringify(localDBChats)], { let blob = new Blob([JSON.stringify(localDBChats)], {
type: 'application/json' type: 'application/json'
}); });
saveAs(blob, `chat-export-${Date.now()}.json`); saveAs(blob, `chat-export-${Date.now()}.json`);
const tx = DB.transaction('chats', 'readwrite'); const tx = DB.transaction('chats', 'readwrite');
await Promise.all([tx.store.clear(), tx.done]); await Promise.all([tx.store.clear(), tx.done]);
await deleteDB('Chats'); await deleteDB('Chats');
localDBChats = []; localDBChats = [];
}} }}
> >
Download & Delete Download & Delete
</button> </button>
<button <button
class="text-xs text-center w-full mt-2 text-gray-400 underline" class="text-xs text-center w-full mt-2 text-gray-400 underline"
on:click={async () => { on:click={async () => {
localDBChats = []; localDBChats = [];
}}>{$i18n.t('Close')}</button }}>{$i18n.t('Close')}</button
> >
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{/if} </div>
{/if}
<Sidebar /> <Sidebar />
{#if loaded}
<slot /> <slot />
{:else}
<div class="w-full flex-1 h-full flex items-center justify-center">
<Spinner />
</div>
{/if} {/if}
</div> </div>
</div> </div>

View File

@ -211,8 +211,9 @@
console.log('executeTool', data, toolServer); console.log('executeTool', data, toolServer);
if (toolServer) { if (toolServer) {
console.log(toolServer);
const res = await executeToolServer( const res = await executeToolServer(
toolServer.key, (toolServer?.auth_type ?? 'bearer') === 'bearer' ? toolServer?.key : localStorage.token,
toolServer.url, toolServer.url,
data?.name, data?.name,
data?.params, data?.params,