Merge remote-tracking branch 'upstream/dev' into playwright

This commit is contained in:
Rory 2025-02-12 22:32:44 -06:00
commit 40d4db97e6
120 changed files with 3485 additions and 1184 deletions

View file

@ -683,6 +683,17 @@ Path(UPLOAD_DIR).mkdir(parents=True, exist_ok=True)
CACHE_DIR = f"{DATA_DIR}/cache" CACHE_DIR = f"{DATA_DIR}/cache"
Path(CACHE_DIR).mkdir(parents=True, exist_ok=True) Path(CACHE_DIR).mkdir(parents=True, exist_ok=True)
####################################
# DIRECT CONNECTIONS
####################################
ENABLE_DIRECT_CONNECTIONS = PersistentConfig(
"ENABLE_DIRECT_CONNECTIONS",
"direct.enable",
os.environ.get("ENABLE_DIRECT_CONNECTIONS", "True").lower() == "true",
)
#################################### ####################################
# OLLAMA_BASE_URL # OLLAMA_BASE_URL
#################################### ####################################
@ -1326,6 +1337,54 @@ Your task is to synthesize these responses into a single, high-quality response.
Responses from models: {{responses}}""" Responses from models: {{responses}}"""
####################################
# Code Interpreter
####################################
ENABLE_CODE_INTERPRETER = PersistentConfig(
"ENABLE_CODE_INTERPRETER",
"code_interpreter.enable",
os.environ.get("ENABLE_CODE_INTERPRETER", "True").lower() == "true",
)
CODE_INTERPRETER_ENGINE = PersistentConfig(
"CODE_INTERPRETER_ENGINE",
"code_interpreter.engine",
os.environ.get("CODE_INTERPRETER_ENGINE", "pyodide"),
)
CODE_INTERPRETER_PROMPT_TEMPLATE = PersistentConfig(
"CODE_INTERPRETER_PROMPT_TEMPLATE",
"code_interpreter.prompt_template",
os.environ.get("CODE_INTERPRETER_PROMPT_TEMPLATE", ""),
)
CODE_INTERPRETER_JUPYTER_URL = PersistentConfig(
"CODE_INTERPRETER_JUPYTER_URL",
"code_interpreter.jupyter.url",
os.environ.get("CODE_INTERPRETER_JUPYTER_URL", ""),
)
CODE_INTERPRETER_JUPYTER_AUTH = PersistentConfig(
"CODE_INTERPRETER_JUPYTER_AUTH",
"code_interpreter.jupyter.auth",
os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH", ""),
)
CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = PersistentConfig(
"CODE_INTERPRETER_JUPYTER_AUTH_TOKEN",
"code_interpreter.jupyter.auth_token",
os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH_TOKEN", ""),
)
CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = PersistentConfig(
"CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD",
"code_interpreter.jupyter.auth_password",
os.environ.get("CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD", ""),
)
DEFAULT_CODE_INTERPRETER_PROMPT = """ DEFAULT_CODE_INTERPRETER_PROMPT = """
#### Tools Available #### Tools Available
@ -1336,9 +1395,8 @@ DEFAULT_CODE_INTERPRETER_PROMPT = """
- When coding, **always aim to print meaningful outputs** (e.g., results, tables, summaries, or visuals) to better interpret and verify the findings. Avoid relying on implicit outputs; prioritize explicit and clear print statements so the results are effectively communicated to the user. - When coding, **always aim to print meaningful outputs** (e.g., results, tables, summaries, or visuals) to better interpret and verify the findings. Avoid relying on implicit outputs; prioritize explicit and clear print statements so the results are effectively communicated to the user.
- After obtaining the printed output, **always provide a concise analysis, interpretation, or next steps to help the user understand the findings or refine the outcome further.** - After obtaining the printed output, **always provide a concise analysis, interpretation, or next steps to help the user understand the findings or refine the outcome further.**
- If the results are unclear, unexpected, or require validation, refine the code and execute it again as needed. Always aim to deliver meaningful insights from the results, iterating if necessary. - If the results are unclear, unexpected, or require validation, refine the code and execute it again as needed. Always aim to deliver meaningful insights from the results, iterating if necessary.
- If a link is provided for an image, audio, or any file, include it in the response exactly as given to ensure the user has access to the original resource. - **If a link to an image, audio, or any file is provided in markdown format in the output, ALWAYS regurgitate word for word, explicitly display it as part of the response to ensure the user can access it easily, do NOT change the link.**
- All responses should be communicated in the chat's primary language, ensuring seamless understanding. If the chat is multilingual, default to English for clarity. - All responses should be communicated in the chat's primary language, ensuring seamless understanding. If the chat is multilingual, default to English for clarity.
- **If a link to an image, audio, or any file is provided in markdown format, ALWAYS regurgitate explicitly display it as part of the response to ensure the user can access it easily, do NOT change the link.**
Ensure that the tools are effectively utilized to achieve the highest-quality analysis for the user.""" Ensure that the tools are effectively utilized to achieve the highest-quality analysis for the user."""
@ -1691,6 +1749,12 @@ MOJEEK_SEARCH_API_KEY = PersistentConfig(
os.getenv("MOJEEK_SEARCH_API_KEY", ""), os.getenv("MOJEEK_SEARCH_API_KEY", ""),
) )
BOCHA_SEARCH_API_KEY = PersistentConfig(
"BOCHA_SEARCH_API_KEY",
"rag.web.search.bocha_search_api_key",
os.getenv("BOCHA_SEARCH_API_KEY", ""),
)
SERPSTACK_API_KEY = PersistentConfig( SERPSTACK_API_KEY = PersistentConfig(
"SERPSTACK_API_KEY", "SERPSTACK_API_KEY",
"rag.web.search.serpstack_api_key", "rag.web.search.serpstack_api_key",

View file

@ -97,6 +97,16 @@ from open_webui.config import (
OPENAI_API_BASE_URLS, OPENAI_API_BASE_URLS,
OPENAI_API_KEYS, OPENAI_API_KEYS,
OPENAI_API_CONFIGS, OPENAI_API_CONFIGS,
# Direct Connections
ENABLE_DIRECT_CONNECTIONS,
# Code Interpreter
ENABLE_CODE_INTERPRETER,
CODE_INTERPRETER_ENGINE,
CODE_INTERPRETER_PROMPT_TEMPLATE,
CODE_INTERPRETER_JUPYTER_URL,
CODE_INTERPRETER_JUPYTER_AUTH,
CODE_INTERPRETER_JUPYTER_AUTH_TOKEN,
CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD,
# Image # Image
AUTOMATIC1111_API_AUTH, AUTOMATIC1111_API_AUTH,
AUTOMATIC1111_BASE_URL, AUTOMATIC1111_BASE_URL,
@ -183,6 +193,7 @@ from open_webui.config import (
EXA_API_KEY, EXA_API_KEY,
KAGI_SEARCH_API_KEY, KAGI_SEARCH_API_KEY,
MOJEEK_SEARCH_API_KEY, MOJEEK_SEARCH_API_KEY,
BOCHA_SEARCH_API_KEY,
GOOGLE_PSE_API_KEY, GOOGLE_PSE_API_KEY,
GOOGLE_PSE_ENGINE_ID, GOOGLE_PSE_ENGINE_ID,
GOOGLE_DRIVE_CLIENT_ID, GOOGLE_DRIVE_CLIENT_ID,
@ -325,6 +336,10 @@ class SPAStaticFiles(StaticFiles):
return await super().get_response(path, scope) return await super().get_response(path, scope)
except (HTTPException, StarletteHTTPException) as ex: except (HTTPException, StarletteHTTPException) as ex:
if ex.status_code == 404: if ex.status_code == 404:
if path.endswith(".js"):
# Return 404 for javascript files
raise ex
else:
return await super().get_response("index.html", scope) return await super().get_response("index.html", scope)
else: else:
raise ex raise ex
@ -392,6 +407,14 @@ app.state.config.OPENAI_API_CONFIGS = OPENAI_API_CONFIGS
app.state.OPENAI_MODELS = {} app.state.OPENAI_MODELS = {}
########################################
#
# DIRECT CONNECTIONS
#
########################################
app.state.config.ENABLE_DIRECT_CONNECTIONS = ENABLE_DIRECT_CONNECTIONS
######################################## ########################################
# #
# WEBUI # WEBUI
@ -517,6 +540,7 @@ app.state.config.GOOGLE_PSE_ENGINE_ID = GOOGLE_PSE_ENGINE_ID
app.state.config.BRAVE_SEARCH_API_KEY = BRAVE_SEARCH_API_KEY app.state.config.BRAVE_SEARCH_API_KEY = BRAVE_SEARCH_API_KEY
app.state.config.KAGI_SEARCH_API_KEY = KAGI_SEARCH_API_KEY app.state.config.KAGI_SEARCH_API_KEY = KAGI_SEARCH_API_KEY
app.state.config.MOJEEK_SEARCH_API_KEY = MOJEEK_SEARCH_API_KEY app.state.config.MOJEEK_SEARCH_API_KEY = MOJEEK_SEARCH_API_KEY
app.state.config.BOCHA_SEARCH_API_KEY = BOCHA_SEARCH_API_KEY
app.state.config.SERPSTACK_API_KEY = SERPSTACK_API_KEY app.state.config.SERPSTACK_API_KEY = SERPSTACK_API_KEY
app.state.config.SERPSTACK_HTTPS = SERPSTACK_HTTPS app.state.config.SERPSTACK_HTTPS = SERPSTACK_HTTPS
app.state.config.SERPER_API_KEY = SERPER_API_KEY app.state.config.SERPER_API_KEY = SERPER_API_KEY
@ -574,6 +598,24 @@ app.state.EMBEDDING_FUNCTION = get_embedding_function(
app.state.config.RAG_EMBEDDING_BATCH_SIZE, app.state.config.RAG_EMBEDDING_BATCH_SIZE,
) )
########################################
#
# CODE INTERPRETER
#
########################################
app.state.config.ENABLE_CODE_INTERPRETER = ENABLE_CODE_INTERPRETER
app.state.config.CODE_INTERPRETER_ENGINE = CODE_INTERPRETER_ENGINE
app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE = CODE_INTERPRETER_PROMPT_TEMPLATE
app.state.config.CODE_INTERPRETER_JUPYTER_URL = CODE_INTERPRETER_JUPYTER_URL
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = CODE_INTERPRETER_JUPYTER_AUTH
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = (
CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
)
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = (
CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
)
######################################## ########################################
# #
@ -759,6 +801,7 @@ app.include_router(openai.router, prefix="/openai", tags=["openai"])
app.include_router(pipelines.router, prefix="/api/v1/pipelines", tags=["pipelines"]) app.include_router(pipelines.router, prefix="/api/v1/pipelines", tags=["pipelines"])
app.include_router(tasks.router, prefix="/api/v1/tasks", tags=["tasks"]) app.include_router(tasks.router, prefix="/api/v1/tasks", tags=["tasks"])
app.include_router(images.router, prefix="/api/v1/images", tags=["images"]) app.include_router(images.router, prefix="/api/v1/images", tags=["images"])
app.include_router(audio.router, prefix="/api/v1/audio", tags=["audio"]) app.include_router(audio.router, prefix="/api/v1/audio", tags=["audio"])
app.include_router(retrieval.router, prefix="/api/v1/retrieval", tags=["retrieval"]) app.include_router(retrieval.router, prefix="/api/v1/retrieval", tags=["retrieval"])
@ -1017,15 +1060,17 @@ async def get_app_config(request: Request):
"enable_websocket": ENABLE_WEBSOCKET_SUPPORT, "enable_websocket": ENABLE_WEBSOCKET_SUPPORT,
**( **(
{ {
"enable_direct_connections": app.state.config.ENABLE_DIRECT_CONNECTIONS,
"enable_channels": app.state.config.ENABLE_CHANNELS, "enable_channels": app.state.config.ENABLE_CHANNELS,
"enable_web_search": app.state.config.ENABLE_RAG_WEB_SEARCH, "enable_web_search": app.state.config.ENABLE_RAG_WEB_SEARCH,
"enable_google_drive_integration": app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, "enable_code_interpreter": app.state.config.ENABLE_CODE_INTERPRETER,
"enable_image_generation": app.state.config.ENABLE_IMAGE_GENERATION, "enable_image_generation": app.state.config.ENABLE_IMAGE_GENERATION,
"enable_autocomplete_generation": app.state.config.ENABLE_AUTOCOMPLETE_GENERATION,
"enable_community_sharing": app.state.config.ENABLE_COMMUNITY_SHARING, "enable_community_sharing": app.state.config.ENABLE_COMMUNITY_SHARING,
"enable_message_rating": app.state.config.ENABLE_MESSAGE_RATING, "enable_message_rating": app.state.config.ENABLE_MESSAGE_RATING,
"enable_autocomplete_generation": app.state.config.ENABLE_AUTOCOMPLETE_GENERATION,
"enable_admin_export": ENABLE_ADMIN_EXPORT, "enable_admin_export": ENABLE_ADMIN_EXPORT,
"enable_admin_chat_access": ENABLE_ADMIN_CHAT_ACCESS, "enable_admin_chat_access": ENABLE_ADMIN_CHAT_ACCESS,
"enable_google_drive_integration": app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
} }
if user is not None if user is not None
else {} else {}

View file

@ -271,6 +271,24 @@ class UsersTable:
except Exception: except Exception:
return None return None
def update_user_settings_by_id(self, id: str, updated: dict) -> Optional[UserModel]:
try:
with get_db() as db:
user_settings = db.query(User).filter_by(id=id).first().settings
if user_settings is None:
user_settings = {}
user_settings.update(updated)
db.query(User).filter_by(id=id).update({"settings": user_settings})
db.commit()
user = db.query(User).filter_by(id=id).first()
return UserModel.model_validate(user)
except Exception:
return None
def delete_user_by_id(self, id: str) -> bool: def delete_user_by_id(self, id: str) -> bool:
try: try:
# Remove User from Groups # Remove User from Groups

View file

@ -120,18 +120,12 @@ class OpenSearchClient:
return None return None
query_body = { query_body = {
"query": { "query": {"bool": {"filter": []}},
"bool": {
"filter": []
}
},
"_source": ["text", "metadata"], "_source": ["text", "metadata"],
} }
for field, value in filter.items(): for field, value in filter.items():
query_body["query"]["bool"]["filter"].append({ query_body["query"]["bool"]["filter"].append({"term": {field: value}})
"term": {field: value}
})
size = limit if limit else 10 size = limit if limit else 10
@ -139,7 +133,7 @@ class OpenSearchClient:
result = self.client.search( result = self.client.search(
index=f"{self.index_prefix}_{collection_name}", index=f"{self.index_prefix}_{collection_name}",
body=query_body, body=query_body,
size=size size=size,
) )
return self._result_to_get_result(result) return self._result_to_get_result(result)

View file

@ -0,0 +1,72 @@
import logging
from typing import Optional
import requests
import json
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 _parse_response(response):
result = {}
if "data" in response:
data = response["data"]
if "webPages" in data:
webPages = data["webPages"]
if "value" in webPages:
result["webpage"] = [
{
"id": item.get("id", ""),
"name": item.get("name", ""),
"url": item.get("url", ""),
"snippet": item.get("snippet", ""),
"summary": item.get("summary", ""),
"siteName": item.get("siteName", ""),
"siteIcon": item.get("siteIcon", ""),
"datePublished": item.get("datePublished", "") or item.get("dateLastCrawled", ""),
}
for item in webPages["value"]
]
return result
def search_bocha(
api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None
) -> list[SearchResult]:
"""Search using Bocha's Search API and return the results as a list of SearchResult objects.
Args:
api_key (str): A Bocha Search API key
query (str): The query to search for
"""
url = "https://api.bochaai.com/v1/web-search?utm_source=ollama"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = json.dumps({
"query": query,
"summary": True,
"freshness": "noLimit",
"count": count
})
response = requests.post(url, headers=headers, data=payload, timeout=5)
response.raise_for_status()
results = _parse_response(response.json())
print(results)
if filter_list:
results = get_filtered_results(results, filter_list)
return [
SearchResult(
link=result["url"],
title=result.get("name"),
snippet=result.get("summary")
)
for result in results.get("webpage", [])[:count]
]

View file

@ -8,7 +8,6 @@ from open_webui.env import SRC_LOG_LEVELS
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["RAG"]) log.setLevel(SRC_LOG_LEVELS["RAG"])
def search_google_pse( def search_google_pse(
api_key: str, api_key: str,
search_engine_id: str, search_engine_id: str,
@ -17,34 +16,51 @@ def search_google_pse(
filter_list: Optional[list[str]] = None, filter_list: Optional[list[str]] = None,
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using Google's Programmable Search Engine API and return the results as a list of SearchResult objects. """Search using Google's Programmable Search Engine API and return the results as a list of SearchResult objects.
Handles pagination for counts greater than 10.
Args: Args:
api_key (str): A Programmable Search Engine API key api_key (str): A Programmable Search Engine API key
search_engine_id (str): A Programmable Search Engine ID search_engine_id (str): A Programmable Search Engine ID
query (str): The query to search for query (str): The query to search for
count (int): The number of results to return (max 100, as PSE max results per query is 10 and max page is 10)
filter_list (Optional[list[str]], optional): A list of keywords to filter out from results. Defaults to None.
Returns:
list[SearchResult]: A list of SearchResult objects.
""" """
url = "https://www.googleapis.com/customsearch/v1" url = "https://www.googleapis.com/customsearch/v1"
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
all_results = []
start_index = 1 # Google PSE start parameter is 1-based
while count > 0:
num_results_this_page = min(count, 10) # Google PSE max results per page is 10
params = { params = {
"cx": search_engine_id, "cx": search_engine_id,
"q": query, "q": query,
"key": api_key, "key": api_key,
"num": count, "num": num_results_this_page,
"start": start_index,
} }
response = requests.request("GET", url, headers=headers, params=params) response = requests.request("GET", url, headers=headers, params=params)
response.raise_for_status() response.raise_for_status()
json_response = response.json() json_response = response.json()
results = json_response.get("items", []) results = json_response.get("items", [])
if results: # check if results are returned. If not, no more pages to fetch.
all_results.extend(results)
count -= len(results) # Decrement count by the number of results fetched in this page.
start_index += 10 # Increment start index for the next page
else:
break # No more results from Google PSE, break the loop
if filter_list: if filter_list:
results = get_filtered_results(results, filter_list) all_results = get_filtered_results(all_results, filter_list)
return [ return [
SearchResult( SearchResult(
link=result["link"], link=result["link"],
title=result.get("title"), title=result.get("title"),
snippet=result.get("snippet"), snippet=result.get("snippet"),
) )
for result in results for result in all_results
] ]

View file

@ -25,13 +25,10 @@ def search_jina(api_key: str, query: str, count: int) -> list[SearchResult]:
"Accept": "application/json", "Accept": "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": api_key, "Authorization": api_key,
"X-Retain-Images": "none" "X-Retain-Images": "none",
} }
payload = { payload = {"q": query, "count": count if count <= 10 else 10}
"q": query,
"count": count if count <= 10 else 10
}
url = str(URL(jina_search_endpoint)) url = str(URL(jina_search_endpoint))
response = requests.post(url, headers=headers, json=payload) response = requests.post(url, headers=headers, json=payload)

View file

@ -560,10 +560,14 @@ def transcribe(request: Request, file_path):
# Extract transcript from Deepgram response # Extract transcript from Deepgram response
try: try:
transcript = response_data["results"]["channels"][0]["alternatives"][0].get("transcript", "") transcript = response_data["results"]["channels"][0]["alternatives"][
0
].get("transcript", "")
except (KeyError, IndexError) as e: except (KeyError, IndexError) as e:
log.error(f"Malformed response from Deepgram: {str(e)}") log.error(f"Malformed response from Deepgram: {str(e)}")
raise Exception("Failed to parse Deepgram response - unexpected response format") raise Exception(
"Failed to parse Deepgram response - unexpected response format"
)
data = {"text": transcript.strip()} data = {"text": transcript.strip()}
# Save transcript # Save transcript

View file

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

View file

@ -3,30 +3,22 @@ import os
import uuid import uuid
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from pydantic import BaseModel
import mimetypes
from urllib.parse import quote from urllib.parse import quote
from open_webui.storage.provider import Storage from fastapi import APIRouter, Depends, File, HTTPException, Request, UploadFile, status
from fastapi.responses import FileResponse, StreamingResponse
from open_webui.constants import ERROR_MESSAGES
from open_webui.env import SRC_LOG_LEVELS
from open_webui.models.files import ( from open_webui.models.files import (
FileForm, FileForm,
FileModel, FileModel,
FileModelResponse, FileModelResponse,
Files, Files,
) )
from open_webui.routers.retrieval import process_file, ProcessFileForm from open_webui.routers.retrieval import ProcessFileForm, process_file
from open_webui.storage.provider import Storage
from open_webui.config import UPLOAD_DIR
from open_webui.env import SRC_LOG_LEVELS
from open_webui.constants import ERROR_MESSAGES
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status, Request
from fastapi.responses import FileResponse, StreamingResponse
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 pydantic import BaseModel
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"]) log.setLevel(SRC_LOG_LEVELS["MODELS"])
@ -41,7 +33,10 @@ router = APIRouter()
@router.post("/", response_model=FileModelResponse) @router.post("/", response_model=FileModelResponse)
def upload_file( def upload_file(
request: Request, file: UploadFile = File(...), user=Depends(get_verified_user) request: Request,
file: UploadFile = File(...),
user=Depends(get_verified_user),
file_metadata: dict = {},
): ):
log.info(f"file.content_type: {file.content_type}") log.info(f"file.content_type: {file.content_type}")
try: try:
@ -65,6 +60,7 @@ def upload_file(
"name": name, "name": name,
"content_type": file.content_type, "content_type": file.content_type,
"size": len(contents), "size": len(contents),
"data": file_metadata,
}, },
} }
), ),
@ -126,7 +122,7 @@ async def delete_all_files(user=Depends(get_admin_user)):
Storage.delete_all_files() Storage.delete_all_files()
except Exception as e: except Exception as e:
log.exception(e) log.exception(e)
log.error(f"Error deleting files") log.error("Error deleting files")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.DEFAULT("Error deleting files"), detail=ERROR_MESSAGES.DEFAULT("Error deleting files"),
@ -248,7 +244,7 @@ async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
) )
except Exception as e: except Exception as e:
log.exception(e) log.exception(e)
log.error(f"Error getting file content") log.error("Error getting file content")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.DEFAULT("Error getting file content"), detail=ERROR_MESSAGES.DEFAULT("Error getting file content"),
@ -279,7 +275,7 @@ async def get_html_file_content_by_id(id: str, user=Depends(get_verified_user)):
) )
except Exception as e: except Exception as e:
log.exception(e) log.exception(e)
log.error(f"Error getting file content") log.error("Error getting file content")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.DEFAULT("Error getting file content"), detail=ERROR_MESSAGES.DEFAULT("Error getting file content"),
@ -355,7 +351,7 @@ async def delete_file_by_id(id: str, user=Depends(get_verified_user)):
Storage.delete_file(file.path) Storage.delete_file(file.path)
except Exception as e: except Exception as e:
log.exception(e) log.exception(e)
log.error(f"Error deleting files") log.error("Error deleting files")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.DEFAULT("Error deleting files"), detail=ERROR_MESSAGES.DEFAULT("Error deleting files"),

View file

@ -1,32 +1,26 @@
import asyncio import asyncio
import base64 import base64
import io
import json import json
import logging import logging
import mimetypes import mimetypes
import re import re
import uuid
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
import requests import requests
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile
from fastapi import Depends, FastAPI, HTTPException, Request, APIRouter
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
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 open_webui.env import ENV, SRC_LOG_LEVELS, ENABLE_FORWARD_USER_INFO_HEADERS from open_webui.env import ENABLE_FORWARD_USER_INFO_HEADERS, SRC_LOG_LEVELS
from open_webui.routers.files import upload_file
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.images.comfyui import ( from open_webui.utils.images.comfyui import (
ComfyUIGenerateImageForm, ComfyUIGenerateImageForm,
ComfyUIWorkflow, ComfyUIWorkflow,
comfyui_generate_image, comfyui_generate_image,
) )
from pydantic import BaseModel
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["IMAGES"]) log.setLevel(SRC_LOG_LEVELS["IMAGES"])
@ -271,7 +265,6 @@ async def get_image_config(request: Request, user=Depends(get_admin_user)):
async def update_image_config( async def update_image_config(
request: Request, form_data: ImageConfigForm, user=Depends(get_admin_user) request: Request, form_data: ImageConfigForm, user=Depends(get_admin_user)
): ):
set_image_model(request, form_data.MODEL) set_image_model(request, form_data.MODEL)
pattern = r"^\d+x\d+$" pattern = r"^\d+x\d+$"
@ -383,40 +376,22 @@ class GenerateImageForm(BaseModel):
negative_prompt: Optional[str] = None negative_prompt: Optional[str] = None
def save_b64_image(b64_str): def load_b64_image_data(b64_str):
try: try:
image_id = str(uuid.uuid4())
if "," in b64_str: if "," in b64_str:
header, encoded = b64_str.split(",", 1) header, encoded = b64_str.split(",", 1)
mime_type = header.split(";")[0] mime_type = header.split(";")[0]
img_data = base64.b64decode(encoded) img_data = base64.b64decode(encoded)
image_format = mimetypes.guess_extension(mime_type)
image_filename = f"{image_id}{image_format}"
file_path = IMAGE_CACHE_DIR / f"{image_filename}"
with open(file_path, "wb") as f:
f.write(img_data)
return image_filename
else: else:
image_filename = f"{image_id}.png" mime_type = "image/png"
file_path = IMAGE_CACHE_DIR.joinpath(image_filename)
img_data = base64.b64decode(b64_str) img_data = base64.b64decode(b64_str)
return img_data, mime_type
# Write the image data to a file
with open(file_path, "wb") as f:
f.write(img_data)
return image_filename
except Exception as e: except Exception as e:
log.exception(f"Error saving image: {e}") log.exception(f"Error loading image data: {e}")
return None return None
def save_url_image(url, headers=None): def load_url_image_data(url, headers=None):
image_id = str(uuid.uuid4())
try: try:
if headers: if headers:
r = requests.get(url, headers=headers) r = requests.get(url, headers=headers)
@ -426,18 +401,7 @@ def save_url_image(url, headers=None):
r.raise_for_status() r.raise_for_status()
if r.headers["content-type"].split("/")[0] == "image": if r.headers["content-type"].split("/")[0] == "image":
mime_type = r.headers["content-type"] mime_type = r.headers["content-type"]
image_format = mimetypes.guess_extension(mime_type) return r.content, mime_type
if not image_format:
raise ValueError("Could not determine image type from MIME type")
image_filename = f"{image_id}{image_format}"
file_path = IMAGE_CACHE_DIR.joinpath(f"{image_filename}")
with open(file_path, "wb") as image_file:
for chunk in r.iter_content(chunk_size=8192):
image_file.write(chunk)
return image_filename
else: else:
log.error("Url does not point to an image.") log.error("Url does not point to an image.")
return None return None
@ -447,6 +411,20 @@ def save_url_image(url, headers=None):
return None return None
def upload_image(request, image_metadata, image_data, content_type, user):
image_format = mimetypes.guess_extension(content_type)
file = UploadFile(
file=io.BytesIO(image_data),
filename=f"generated-image{image_format}", # will be converted to a unique ID on upload_file
headers={
"content-type": content_type,
},
)
file_item = upload_file(request, file, user, file_metadata=image_metadata)
url = request.app.url_path_for("get_file_content_by_id", id=file_item.id)
return url
@router.post("/generations") @router.post("/generations")
async def image_generations( async def image_generations(
request: Request, request: Request,
@ -500,13 +478,9 @@ async def image_generations(
images = [] images = []
for image in res["data"]: for image in res["data"]:
image_filename = save_b64_image(image["b64_json"]) image_data, content_type = load_b64_image_data(image["b64_json"])
images.append({"url": f"/cache/image/generations/{image_filename}"}) url = upload_image(request, data, image_data, content_type, user)
file_body_path = IMAGE_CACHE_DIR.joinpath(f"{image_filename}.json") images.append({"url": url})
with open(file_body_path, "w") as f:
json.dump(data, f)
return images return images
elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui": elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui":
@ -552,14 +526,15 @@ async def image_generations(
"Authorization": f"Bearer {request.app.state.config.COMFYUI_API_KEY}" "Authorization": f"Bearer {request.app.state.config.COMFYUI_API_KEY}"
} }
image_filename = save_url_image(image["url"], headers) image_data, content_type = load_url_image_data(image["url"], headers)
images.append({"url": f"/cache/image/generations/{image_filename}"}) url = upload_image(
file_body_path = IMAGE_CACHE_DIR.joinpath(f"{image_filename}.json") request,
form_data.model_dump(exclude_none=True),
with open(file_body_path, "w") as f: image_data,
json.dump(form_data.model_dump(exclude_none=True), f) content_type,
user,
log.debug(f"images: {images}") )
images.append({"url": url})
return images return images
elif ( elif (
request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111" request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111"
@ -604,13 +579,15 @@ async def image_generations(
images = [] images = []
for image in res["images"]: for image in res["images"]:
image_filename = save_b64_image(image) image_data, content_type = load_b64_image_data(image)
images.append({"url": f"/cache/image/generations/{image_filename}"}) url = upload_image(
file_body_path = IMAGE_CACHE_DIR.joinpath(f"{image_filename}.json") request,
{**data, "info": res["info"]},
with open(file_body_path, "w") as f: image_data,
json.dump({**data, "info": res["info"]}, f) content_type,
user,
)
images.append({"url": url})
return images return images
except Exception as e: except Exception as e:
error = e error = e

View file

@ -1471,9 +1471,7 @@ async def upload_model(
create_payload = { create_payload = {
"model": model_name, "model": model_name,
# Reference the file by its original name => the uploaded blob's digest # Reference the file by its original name => the uploaded blob's digest
"files": { "files": {file.filename: f"sha256:{file_hash}"},
file.filename: f"sha256:{file_hash}"
},
} }
log.info(f"Model Payload: {create_payload}") # DEBUG log.info(f"Model Payload: {create_payload}") # DEBUG

View file

@ -45,6 +45,7 @@ from open_webui.retrieval.web.utils import get_web_loader
from open_webui.retrieval.web.brave import search_brave from open_webui.retrieval.web.brave import search_brave
from open_webui.retrieval.web.kagi import search_kagi from open_webui.retrieval.web.kagi import search_kagi
from open_webui.retrieval.web.mojeek import search_mojeek from open_webui.retrieval.web.mojeek import search_mojeek
from open_webui.retrieval.web.bocha import search_bocha
from open_webui.retrieval.web.duckduckgo import search_duckduckgo from open_webui.retrieval.web.duckduckgo import search_duckduckgo
from open_webui.retrieval.web.google_pse import search_google_pse from open_webui.retrieval.web.google_pse import search_google_pse
from open_webui.retrieval.web.jina_search import search_jina from open_webui.retrieval.web.jina_search import search_jina
@ -379,6 +380,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
"brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY, "brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY,
"kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY, "kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY,
"mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY, "mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY,
"bocha_search_api_key": request.app.state.config.BOCHA_SEARCH_API_KEY,
"serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY, "serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY,
"serpstack_https": request.app.state.config.SERPSTACK_HTTPS, "serpstack_https": request.app.state.config.SERPSTACK_HTTPS,
"serper_api_key": request.app.state.config.SERPER_API_KEY, "serper_api_key": request.app.state.config.SERPER_API_KEY,
@ -429,6 +431,7 @@ class WebSearchConfig(BaseModel):
brave_search_api_key: Optional[str] = None brave_search_api_key: Optional[str] = None
kagi_search_api_key: Optional[str] = None kagi_search_api_key: Optional[str] = None
mojeek_search_api_key: Optional[str] = None mojeek_search_api_key: Optional[str] = None
bocha_search_api_key: Optional[str] = None
serpstack_api_key: Optional[str] = None serpstack_api_key: Optional[str] = None
serpstack_https: Optional[bool] = None serpstack_https: Optional[bool] = None
serper_api_key: Optional[str] = None serper_api_key: Optional[str] = None
@ -525,6 +528,9 @@ async def update_rag_config(
request.app.state.config.MOJEEK_SEARCH_API_KEY = ( request.app.state.config.MOJEEK_SEARCH_API_KEY = (
form_data.web.search.mojeek_search_api_key form_data.web.search.mojeek_search_api_key
) )
request.app.state.config.BOCHA_SEARCH_API_KEY = (
form_data.web.search.bocha_search_api_key
)
request.app.state.config.SERPSTACK_API_KEY = ( request.app.state.config.SERPSTACK_API_KEY = (
form_data.web.search.serpstack_api_key form_data.web.search.serpstack_api_key
) )
@ -591,6 +597,7 @@ async def update_rag_config(
"brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY, "brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY,
"kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY, "kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY,
"mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY, "mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY,
"bocha_search_api_key": request.app.state.config.BOCHA_SEARCH_API_KEY,
"serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY, "serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY,
"serpstack_https": request.app.state.config.SERPSTACK_HTTPS, "serpstack_https": request.app.state.config.SERPSTACK_HTTPS,
"serper_api_key": request.app.state.config.SERPER_API_KEY, "serper_api_key": request.app.state.config.SERPER_API_KEY,
@ -1113,6 +1120,7 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]:
- BRAVE_SEARCH_API_KEY - BRAVE_SEARCH_API_KEY
- KAGI_SEARCH_API_KEY - KAGI_SEARCH_API_KEY
- MOJEEK_SEARCH_API_KEY - MOJEEK_SEARCH_API_KEY
- BOCHA_SEARCH_API_KEY
- SERPSTACK_API_KEY - SERPSTACK_API_KEY
- SERPER_API_KEY - SERPER_API_KEY
- SERPLY_API_KEY - SERPLY_API_KEY
@ -1180,6 +1188,16 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]:
) )
else: else:
raise Exception("No MOJEEK_SEARCH_API_KEY found in environment variables") raise Exception("No MOJEEK_SEARCH_API_KEY found in environment variables")
elif engine == "bocha":
if request.app.state.config.BOCHA_SEARCH_API_KEY:
return search_bocha(
request.app.state.config.BOCHA_SEARCH_API_KEY,
query,
request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
)
else:
raise Exception("No BOCHA_SEARCH_API_KEY found in environment variables")
elif engine == "serpstack": elif engine == "serpstack":
if request.app.state.config.SERPSTACK_API_KEY: if request.app.state.config.SERPSTACK_API_KEY:
return search_serpstack( return search_serpstack(

View file

@ -153,7 +153,7 @@ async def get_user_settings_by_session_user(user=Depends(get_verified_user)):
async def update_user_settings_by_session_user( async def update_user_settings_by_session_user(
form_data: UserSettings, user=Depends(get_verified_user) form_data: UserSettings, user=Depends(get_verified_user)
): ):
user = Users.update_user_by_id(user.id, {"settings": form_data.model_dump()}) user = Users.update_user_settings_by_id(user.id, form_data.model_dump())
if user: if user:
return user.settings return user.settings
else: else:

View file

@ -137,7 +137,8 @@ class S3StorageProvider(StorageProvider):
if "Contents" in response: if "Contents" in response:
for content in response["Contents"]: for content in response["Contents"]:
# Skip objects that were not uploaded from open-webui in the first place # Skip objects that were not uploaded from open-webui in the first place
if not content["Key"].startswith(self.key_prefix): continue if not content["Key"].startswith(self.key_prefix):
continue
self.s3_client.delete_object( self.s3_client.delete_object(
Bucket=self.bucket_name, Key=content["Key"] Bucket=self.bucket_name, Key=content["Key"]
@ -150,11 +151,12 @@ class S3StorageProvider(StorageProvider):
# The s3 key is the name assigned to an object. It excludes the bucket name, but includes the internal path and the file name. # The s3 key is the name assigned to an object. It excludes the bucket name, but includes the internal path and the file name.
def _extract_s3_key(self, full_file_path: str) -> str: def _extract_s3_key(self, full_file_path: str) -> str:
return '/'.join(full_file_path.split("//")[1].split("/")[1:]) return "/".join(full_file_path.split("//")[1].split("/")[1:])
def _get_local_file_path(self, s3_key: str) -> str: def _get_local_file_path(self, s3_key: str) -> str:
return f"{UPLOAD_DIR}/{s3_key.split('/')[-1]}" return f"{UPLOAD_DIR}/{s3_key.split('/')[-1]}"
class GCSStorageProvider(StorageProvider): class GCSStorageProvider(StorageProvider):
def __init__(self): def __init__(self):
self.bucket_name = GCS_BUCKET_NAME self.bucket_name = GCS_BUCKET_NAME

View file

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

View file

@ -72,7 +72,7 @@ from open_webui.utils.filter import (
get_sorted_filter_ids, get_sorted_filter_ids,
process_filter_functions, process_filter_functions,
) )
from open_webui.utils.code_interpreter import execute_code_jupyter
from open_webui.tasks import create_task from open_webui.tasks import create_task
@ -684,7 +684,12 @@ async def process_chat_payload(request, form_data, metadata, user, model):
if "code_interpreter" in features and features["code_interpreter"]: if "code_interpreter" in features and features["code_interpreter"]:
form_data["messages"] = add_or_update_user_message( form_data["messages"] = add_or_update_user_message(
DEFAULT_CODE_INTERPRETER_PROMPT, form_data["messages"] (
request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE
if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE != ""
else DEFAULT_CODE_INTERPRETER_PROMPT
),
form_data["messages"],
) )
try: try:
@ -1639,21 +1644,60 @@ async def process_chat_response(
content_blocks[-1]["type"] == "code_interpreter" content_blocks[-1]["type"] == "code_interpreter"
and retries < MAX_RETRIES and retries < MAX_RETRIES
): ):
await event_emitter(
{
"type": "chat:completion",
"data": {
"content": serialize_content_blocks(content_blocks),
},
}
)
retries += 1 retries += 1
log.debug(f"Attempt count: {retries}") log.debug(f"Attempt count: {retries}")
output = "" output = ""
try: try:
if content_blocks[-1]["attributes"].get("type") == "code": if content_blocks[-1]["attributes"].get("type") == "code":
code = content_blocks[-1]["content"]
if (
request.app.state.config.CODE_INTERPRETER_ENGINE
== "pyodide"
):
output = await event_caller( output = await event_caller(
{ {
"type": "execute:python", "type": "execute:python",
"data": { "data": {
"id": str(uuid4()), "id": str(uuid4()),
"code": content_blocks[-1]["content"], "code": code,
}, },
} }
) )
elif (
request.app.state.config.CODE_INTERPRETER_ENGINE
== "jupyter"
):
output = await execute_code_jupyter(
request.app.state.config.CODE_INTERPRETER_JUPYTER_URL,
code,
(
request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN
if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH
== "token"
else None
),
(
request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD
if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH
== "password"
else None
),
)
else:
output = {
"stdout": "Code interpreter engine not configured."
}
if isinstance(output, dict): if isinstance(output, dict):
stdout = output.get("stdout", "") stdout = output.get("stdout", "")
@ -1687,6 +1731,38 @@ async def process_chat_response(
) )
output["stdout"] = "\n".join(stdoutLines) output["stdout"] = "\n".join(stdoutLines)
result = output.get("result", "")
if result:
resultLines = result.split("\n")
for idx, line in enumerate(resultLines):
if "data:image/png;base64" in line:
id = str(uuid4())
# ensure the path exists
os.makedirs(
os.path.join(CACHE_DIR, "images"),
exist_ok=True,
)
image_path = os.path.join(
CACHE_DIR,
f"images/{id}.png",
)
with open(image_path, "wb") as f:
f.write(
base64.b64decode(
line.split(",")[1]
)
)
resultLines[idx] = (
f"![Output Image {idx}](/cache/images/{id}.png)"
)
output["result"] = "\n".join(resultLines)
except Exception as e: except Exception as e:
output = str(e) output = str(e)

View file

@ -142,13 +142,17 @@ class OAuthManager:
log.debug(f"Oauth Groups claim: {oauth_claim}") log.debug(f"Oauth Groups claim: {oauth_claim}")
log.debug(f"User oauth groups: {user_oauth_groups}") log.debug(f"User oauth groups: {user_oauth_groups}")
log.debug(f"User's current groups: {[g.name for g in user_current_groups]}") log.debug(f"User's current groups: {[g.name for g in user_current_groups]}")
log.debug(f"All groups available in OpenWebUI: {[g.name for g in all_available_groups]}") log.debug(
f"All groups available in OpenWebUI: {[g.name for g in all_available_groups]}"
)
# Remove groups that user is no longer a part of # Remove groups that user is no longer a part of
for group_model in user_current_groups: for group_model in user_current_groups:
if group_model.name not in user_oauth_groups: if group_model.name not in user_oauth_groups:
# Remove group from user # Remove group from user
log.debug(f"Removing user from group {group_model.name} as it is no longer in their oauth groups") log.debug(
f"Removing user from group {group_model.name} as it is no longer in their oauth groups"
)
user_ids = group_model.user_ids user_ids = group_model.user_ids
user_ids = [i for i in user_ids if i != user.id] user_ids = [i for i in user_ids if i != user.id]
@ -174,7 +178,9 @@ class OAuthManager:
gm.name == group_model.name for gm in user_current_groups gm.name == group_model.name for gm in user_current_groups
): ):
# Add user to group # Add user to group
log.debug(f"Adding user to group {group_model.name} as it was found in their oauth groups") log.debug(
f"Adding user to group {group_model.name} as it was found in their oauth groups"
)
user_ids = group_model.user_ids user_ids = group_model.user_ids
user_ids.append(user.id) user_ids.append(user.id)
@ -289,7 +295,9 @@ class OAuthManager:
base64_encoded_picture = base64.b64encode( base64_encoded_picture = base64.b64encode(
picture picture
).decode("utf-8") ).decode("utf-8")
guessed_mime_type = mimetypes.guess_type(picture_url)[0] guessed_mime_type = mimetypes.guess_type(
picture_url
)[0]
if guessed_mime_type is None: if guessed_mime_type is None:
# assume JPG, browsers are tolerant enough of image formats # assume JPG, browsers are tolerant enough of image formats
guessed_mime_type = "image/jpeg" guessed_mime_type = "image/jpeg"
@ -307,7 +315,8 @@ class OAuthManager:
username_claim = auth_manager_config.OAUTH_USERNAME_CLAIM username_claim = auth_manager_config.OAUTH_USERNAME_CLAIM
name = user_data.get(username_claim) name = user_data.get(username_claim)
if not isinstance(name, str): if not name:
log.warning("Username claim is missing, using email as name")
name = email name = email
role = self.get_user_role(None, user_data) role = self.get_user_role(None, user_data)

View file

@ -14,6 +14,12 @@ def apply_model_system_prompt_to_body(
if not system: if not system:
return form_data return form_data
# Metadata (WebUI Usage)
if metadata:
variables = metadata.get("variables", {})
if variables:
system = prompt_variables_template(system, variables)
# Legacy (API Usage) # Legacy (API Usage)
if user: if user:
template_params = { template_params = {
@ -25,12 +31,6 @@ def apply_model_system_prompt_to_body(
system = prompt_template(system, **template_params) system = prompt_template(system, **template_params)
# Metadata (WebUI Usage)
if metadata:
variables = metadata.get("variables", {})
if variables:
system = prompt_variables_template(system, variables)
form_data["messages"] = add_or_update_system_message( form_data["messages"] = add_or_update_system_message(
system, form_data.get("messages", []) system, form_data.get("messages", [])
) )

View file

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

View file

@ -73,7 +73,9 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
"type": "function", "type": "function",
"function": { "function": {
"name": tool_call.get("function", {}).get("name", ""), "name": tool_call.get("function", {}).get("name", ""),
"arguments": f"{tool_call.get('function', {}).get('arguments', {})}", "arguments": json.dumps(
tool_call.get("function", {}).get("arguments", {})
),
}, },
} }
openai_tool_calls.append(openai_tool_call) openai_tool_calls.append(openai_tool_call)

View file

@ -91,7 +91,7 @@ pytube==15.0.0
extract_msg extract_msg
pydub pydub
duckduckgo-search~=7.3.0 duckduckgo-search~=7.3.2
## Google Drive ## Google Drive
google-api-python-client google-api-python-client

View file

@ -98,7 +98,7 @@ dependencies = [
"extract_msg", "extract_msg",
"pydub", "pydub",
"duckduckgo-search~=7.3.0", "duckduckgo-search~=7.3.2",
"google-api-python-client", "google-api-python-client",
"google-auth-httplib2", "google-auth-httplib2",

View file

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

View file

@ -1,6 +1,11 @@
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { getOpenAIModelsDirect } from './openai';
export const getModels = async (token: string = '', base: boolean = false) => { export const getModels = async (
token: string = '',
connections: object | null = null,
base: boolean = false
) => {
let error = null; let error = null;
const res = await fetch(`${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}`, { const res = await fetch(`${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}`, {
method: 'GET', method: 'GET',
@ -25,6 +30,97 @@ export const getModels = async (token: string = '', base: boolean = false) => {
} }
let models = res?.data ?? []; let models = res?.data ?? [];
if (connections && !base) {
let localModels = [];
if (connections) {
const OPENAI_API_BASE_URLS = connections.OPENAI_API_BASE_URLS;
const OPENAI_API_KEYS = connections.OPENAI_API_KEYS;
const OPENAI_API_CONFIGS = connections.OPENAI_API_CONFIGS;
const requests = [];
for (const idx in OPENAI_API_BASE_URLS) {
const url = OPENAI_API_BASE_URLS[idx];
if (idx.toString() in OPENAI_API_CONFIGS) {
const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {};
const enable = apiConfig?.enable ?? true;
const modelIds = apiConfig?.model_ids ?? [];
if (enable) {
if (modelIds.length > 0) {
const modelList = {
object: 'list',
data: modelIds.map((modelId) => ({
id: modelId,
name: modelId,
owned_by: 'openai',
openai: { id: modelId },
urlIdx: idx
}))
};
requests.push(
(async () => {
return modelList;
})()
);
} else {
requests.push(getOpenAIModelsDirect(url, OPENAI_API_KEYS[idx]));
}
} else {
requests.push(
(async () => {
return {
object: 'list',
data: [],
urlIdx: idx
};
})()
);
}
}
}
const responses = await Promise.all(requests);
for (const idx in responses) {
const response = responses[idx];
const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {};
let models = Array.isArray(response) ? response : (response?.data ?? []);
models = models.map((model) => ({ ...model, openai: { id: model.id }, urlIdx: idx }));
const prefixId = apiConfig.prefix_id;
if (prefixId) {
for (const model of models) {
model.id = `${prefixId}.${model.id}`;
}
}
localModels = localModels.concat(models);
}
}
models = models.concat(
localModels.map((model) => ({
...model,
name: model?.name ?? model?.id,
direct: true
}))
);
// Remove duplicates
const modelsMap = {};
for (const model of models) {
modelsMap[model.id] = model;
}
models = Object.values(modelsMap);
}
return models; return models;
}; };

View file

@ -208,6 +208,33 @@ export const updateOpenAIKeys = async (token: string = '', keys: string[]) => {
return res.OPENAI_API_KEYS; return res.OPENAI_API_KEYS;
}; };
export const getOpenAIModelsDirect = async (url: string, key: string) => {
let error = null;
const res = await fetch(`${url}/models`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(key && { authorization: `Bearer ${key}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`;
return [];
});
if (error) {
throw error;
}
return res;
};
export const getOpenAIModels = async (token: string, urlIdx?: number) => { export const getOpenAIModels = async (token: string, urlIdx?: number) => {
let error = null; let error = null;
@ -241,11 +268,39 @@ export const getOpenAIModels = async (token: string, urlIdx?: number) => {
export const verifyOpenAIConnection = async ( export const verifyOpenAIConnection = async (
token: string = '', token: string = '',
url: string = 'https://api.openai.com/v1', url: string = 'https://api.openai.com/v1',
key: string = '' key: string = '',
direct: boolean = false
) => { ) => {
let error = null; if (!url) {
throw 'OpenAI: URL is required';
}
const res = await fetch(`${OPENAI_API_BASE_URL}/verify`, { let error = null;
let res = null;
if (direct) {
res = await fetch(`${url}/models`, {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${key}`,
'Content-Type': 'application/json'
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`;
return [];
});
if (error) {
throw error;
}
} else {
res = await fetch(`${OPENAI_API_BASE_URL}/verify`, {
method: 'POST', method: 'POST',
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
@ -269,6 +324,7 @@ export const verifyOpenAIConnection = async (
if (error) { if (error) {
throw error; throw error;
} }
}
return res; return res;
}; };

View file

@ -20,7 +20,9 @@
export let show = false; export let show = false;
export let edit = false; export let edit = false;
export let ollama = false; export let ollama = false;
export let direct = false;
export let connection = null; export let connection = null;
@ -46,9 +48,11 @@
}; };
const verifyOpenAIHandler = async () => { const verifyOpenAIHandler = async () => {
const res = await verifyOpenAIConnection(localStorage.token, url, key).catch((error) => { const res = await verifyOpenAIConnection(localStorage.token, url, key, direct).catch(
(error) => {
toast.error(`${error}`); toast.error(`${error}`);
}); }
);
if (res) { if (res) {
toast.success($i18n.t('Server connection verified')); toast.success($i18n.t('Server connection verified'));

View file

@ -3,7 +3,7 @@
import fileSaver from 'file-saver'; import fileSaver from 'file-saver';
const { saveAs } = fileSaver; const { saveAs } = fileSaver;
import { WEBUI_NAME, config, functions, models } from '$lib/stores'; import { WEBUI_NAME, config, functions, models, settings } from '$lib/stores';
import { onMount, getContext, tick } from 'svelte'; import { onMount, getContext, tick } from 'svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
@ -126,7 +126,12 @@
toast.success($i18n.t('Function deleted successfully')); toast.success($i18n.t('Function deleted successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
}; };
@ -147,7 +152,12 @@
} }
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
}; };
@ -359,7 +369,13 @@
bind:state={func.is_active} bind:state={func.is_active}
on:change={async (e) => { on:change={async (e) => {
toggleFunctionById(localStorage.token, func.id); toggleFunctionById(localStorage.token, func.id);
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections &&
($settings?.directConnections ?? null)
)
);
}} }}
/> />
</Tooltip> </Tooltip>
@ -496,7 +512,12 @@
id={selectedFunction?.id ?? null} id={selectedFunction?.id ?? null}
on:save={async () => { on:save={async () => {
await tick(); await tick();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}} }}
/> />
@ -517,7 +538,12 @@
toast.success($i18n.t('Functions imported successfully')); toast.success($i18n.t('Functions imported successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
reader.readAsText(importFiles[0]); reader.readAsText(importFiles[0]);

View file

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

View file

@ -10,7 +10,7 @@
getModels as _getModels, getModels as _getModels,
getVoices as _getVoices getVoices as _getVoices
} from '$lib/apis/audio'; } from '$lib/apis/audio';
import { config } from '$lib/stores'; import { config, settings } from '$lib/stores';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
@ -51,7 +51,10 @@
if (TTS_ENGINE === '') { if (TTS_ENGINE === '') {
models = []; models = [];
} else { } else {
const res = await _getModels(localStorage.token).catch((e) => { const res = await _getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
).catch((e) => {
toast.error(`${e}`); toast.error(`${e}`);
}); });

View file

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

View file

@ -7,8 +7,9 @@
import { getOllamaConfig, updateOllamaConfig } from '$lib/apis/ollama'; import { getOllamaConfig, updateOllamaConfig } from '$lib/apis/ollama';
import { getOpenAIConfig, updateOpenAIConfig, getOpenAIModels } from '$lib/apis/openai'; import { getOpenAIConfig, updateOpenAIConfig, getOpenAIModels } from '$lib/apis/openai';
import { getModels as _getModels } from '$lib/apis'; import { getModels as _getModels } from '$lib/apis';
import { getDirectConnectionsConfig, setDirectConnectionsConfig } from '$lib/apis/configs';
import { models, user } from '$lib/stores'; import { config, models, settings, user } from '$lib/stores';
import Switch from '$lib/components/common/Switch.svelte'; import Switch from '$lib/components/common/Switch.svelte';
import Spinner from '$lib/components/common/Spinner.svelte'; import Spinner from '$lib/components/common/Spinner.svelte';
@ -16,13 +17,16 @@
import Plus from '$lib/components/icons/Plus.svelte'; import Plus from '$lib/components/icons/Plus.svelte';
import OpenAIConnection from './Connections/OpenAIConnection.svelte'; import OpenAIConnection from './Connections/OpenAIConnection.svelte';
import AddConnectionModal from './Connections/AddConnectionModal.svelte'; import AddConnectionModal from '$lib/components/AddConnectionModal.svelte';
import OllamaConnection from './Connections/OllamaConnection.svelte'; import OllamaConnection from './Connections/OllamaConnection.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
const getModels = async () => { const getModels = async () => {
const models = await _getModels(localStorage.token); const models = await _getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
);
return models; return models;
}; };
@ -37,6 +41,8 @@
let ENABLE_OPENAI_API: null | boolean = null; let ENABLE_OPENAI_API: null | boolean = null;
let ENABLE_OLLAMA_API: null | boolean = null; let ENABLE_OLLAMA_API: null | boolean = null;
let directConnectionsConfig = null;
let pipelineUrls = {}; let pipelineUrls = {};
let showAddOpenAIConnectionModal = false; let showAddOpenAIConnectionModal = false;
let showAddOllamaConnectionModal = false; let showAddOllamaConnectionModal = false;
@ -98,6 +104,19 @@
} }
}; };
const updateDirectConnectionsHandler = async () => {
const res = await setDirectConnectionsConfig(localStorage.token, directConnectionsConfig).catch(
(error) => {
toast.error(`${error}`);
}
);
if (res) {
toast.success($i18n.t('Direct Connections settings updated'));
await models.set(await getModels());
}
};
const addOpenAIConnectionHandler = async (connection) => { const addOpenAIConnectionHandler = async (connection) => {
OPENAI_API_BASE_URLS = [...OPENAI_API_BASE_URLS, connection.url]; OPENAI_API_BASE_URLS = [...OPENAI_API_BASE_URLS, connection.url];
OPENAI_API_KEYS = [...OPENAI_API_KEYS, connection.key]; OPENAI_API_KEYS = [...OPENAI_API_KEYS, connection.key];
@ -127,6 +146,9 @@
})(), })(),
(async () => { (async () => {
openaiConfig = await getOpenAIConfig(localStorage.token); openaiConfig = await getOpenAIConfig(localStorage.token);
})(),
(async () => {
directConnectionsConfig = await getDirectConnectionsConfig(localStorage.token);
})() })()
]); ]);
@ -170,6 +192,14 @@
} }
} }
}); });
const submitHandler = async () => {
updateOpenAIHandler();
updateOllamaHandler();
updateDirectConnectionsHandler();
dispatch('save');
};
</script> </script>
<AddConnectionModal <AddConnectionModal
@ -183,17 +213,9 @@
onSubmit={addOllamaConnectionHandler} onSubmit={addOllamaConnectionHandler}
/> />
<form <form class="flex flex-col h-full justify-between text-sm" on:submit|preventDefault={submitHandler}>
class="flex flex-col h-full justify-between text-sm"
on:submit|preventDefault={() => {
updateOpenAIHandler();
updateOllamaHandler();
dispatch('save');
}}
>
<div class=" overflow-y-scroll scrollbar-hidden h-full"> <div class=" overflow-y-scroll scrollbar-hidden h-full">
{#if ENABLE_OPENAI_API !== null && ENABLE_OLLAMA_API !== null} {#if ENABLE_OPENAI_API !== null && ENABLE_OLLAMA_API !== null && directConnectionsConfig !== null}
<div class="my-2"> <div class="my-2">
<div class="mt-2 space-y-2 pr-1.5"> <div class="mt-2 space-y-2 pr-1.5">
<div class="flex justify-between items-center text-sm"> <div class="flex justify-between items-center text-sm">
@ -334,6 +356,33 @@
</div> </div>
{/if} {/if}
</div> </div>
<hr class=" border-gray-50 dark:border-gray-850" />
<div class="pr-1.5 my-2">
<div class="flex justify-between items-center text-sm">
<div class=" font-medium">{$i18n.t('Direct Connections')}</div>
<div class="flex items-center">
<div class="">
<Switch
bind:state={directConnectionsConfig.ENABLE_DIRECT_CONNECTIONS}
on:change={async () => {
updateDirectConnectionsHandler();
}}
/>
</div>
</div>
</div>
<div class="mt-1.5">
<div class="text-xs text-gray-500">
{$i18n.t(
'Direct Connections allow users to connect to their own OpenAI compatible API endpoints.'
)}
</div>
</div>
</div>
{:else} {:else}
<div class="flex h-full justify-center"> <div class="flex h-full justify-center">
<div class="my-auto"> <div class="my-auto">

View file

@ -4,7 +4,7 @@
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
import AddConnectionModal from './AddConnectionModal.svelte'; import AddConnectionModal from '$lib/components/AddConnectionModal.svelte';
import Cog6 from '$lib/components/icons/Cog6.svelte'; import Cog6 from '$lib/components/icons/Cog6.svelte';
import Wrench from '$lib/components/icons/Wrench.svelte'; import Wrench from '$lib/components/icons/Wrench.svelte';

View file

@ -5,7 +5,8 @@
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
import Cog6 from '$lib/components/icons/Cog6.svelte'; import Cog6 from '$lib/components/icons/Cog6.svelte';
import AddConnectionModal from './AddConnectionModal.svelte'; import AddConnectionModal from '$lib/components/AddConnectionModal.svelte';
import { connect } from 'socket.io-client'; import { connect } from 'socket.io-client';
export let onDelete = () => {}; export let onDelete = () => {};

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { models, user } from '$lib/stores'; import { models, settings, user, config } from '$lib/stores';
import { createEventDispatcher, onMount, getContext, tick } from 'svelte'; import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -16,49 +16,69 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
let config = null; let evaluationConfig = null;
let showAddModel = false; let showAddModel = false;
const submitHandler = async () => { const submitHandler = async () => {
config = await updateConfig(localStorage.token, config).catch((err) => { evaluationConfig = await updateConfig(localStorage.token, evaluationConfig).catch((err) => {
toast.error(err); toast.error(err);
return null; return null;
}); });
if (config) { if (evaluationConfig) {
toast.success('Settings saved successfully'); toast.success('Settings saved successfully');
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
}; };
const addModelHandler = async (model) => { const addModelHandler = async (model) => {
config.EVALUATION_ARENA_MODELS.push(model); evaluationConfig.EVALUATION_ARENA_MODELS.push(model);
config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS]; evaluationConfig.EVALUATION_ARENA_MODELS = [...evaluationConfig.EVALUATION_ARENA_MODELS];
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
const editModelHandler = async (model, modelIdx) => { const editModelHandler = async (model, modelIdx) => {
config.EVALUATION_ARENA_MODELS[modelIdx] = model; evaluationConfig.EVALUATION_ARENA_MODELS[modelIdx] = model;
config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS]; evaluationConfig.EVALUATION_ARENA_MODELS = [...evaluationConfig.EVALUATION_ARENA_MODELS];
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
const deleteModelHandler = async (modelIdx) => { const deleteModelHandler = async (modelIdx) => {
config.EVALUATION_ARENA_MODELS = config.EVALUATION_ARENA_MODELS.filter( evaluationConfig.EVALUATION_ARENA_MODELS = evaluationConfig.EVALUATION_ARENA_MODELS.filter(
(m, mIdx) => mIdx !== modelIdx (m, mIdx) => mIdx !== modelIdx
); );
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
onMount(async () => { onMount(async () => {
if ($user.role === 'admin') { if ($user.role === 'admin') {
config = await getConfig(localStorage.token).catch((err) => { evaluationConfig = await getConfig(localStorage.token).catch((err) => {
toast.error(err); toast.error(err);
return null; return null;
}); });
@ -81,7 +101,7 @@
}} }}
> >
<div class="overflow-y-scroll scrollbar-hidden h-full"> <div class="overflow-y-scroll scrollbar-hidden h-full">
{#if config !== null} {#if evaluationConfig !== null}
<div class=""> <div class="">
<div class="text-sm font-medium mb-2">{$i18n.t('General Settings')}</div> <div class="text-sm font-medium mb-2">{$i18n.t('General Settings')}</div>
@ -90,12 +110,12 @@
<div class=" text-xs font-medium">{$i18n.t('Arena Models')}</div> <div class=" text-xs font-medium">{$i18n.t('Arena Models')}</div>
<Tooltip content={$i18n.t(`Message rating should be enabled to use this feature`)}> <Tooltip content={$i18n.t(`Message rating should be enabled to use this feature`)}>
<Switch bind:state={config.ENABLE_EVALUATION_ARENA_MODELS} /> <Switch bind:state={evaluationConfig.ENABLE_EVALUATION_ARENA_MODELS} />
</Tooltip> </Tooltip>
</div> </div>
</div> </div>
{#if config.ENABLE_EVALUATION_ARENA_MODELS} {#if evaluationConfig.ENABLE_EVALUATION_ARENA_MODELS}
<hr class=" border-gray-50 dark:border-gray-700/10 my-2" /> <hr class=" border-gray-50 dark:border-gray-700/10 my-2" />
<div class="flex justify-between items-center mb-2"> <div class="flex justify-between items-center mb-2">
@ -117,8 +137,8 @@
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
{#if (config?.EVALUATION_ARENA_MODELS ?? []).length > 0} {#if (evaluationConfig?.EVALUATION_ARENA_MODELS ?? []).length > 0}
{#each config.EVALUATION_ARENA_MODELS as model, index} {#each evaluationConfig.EVALUATION_ARENA_MODELS as model, index}
<Model <Model
{model} {model}
on:edit={(e) => { on:edit={(e) => {

View file

@ -144,7 +144,7 @@
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500"> <div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
<!-- https://docs.openwebui.com/getting-started/advanced-topics/api-endpoints --> <!-- https://docs.openwebui.com/getting-started/advanced-topics/api-endpoints -->
<a <a
href="https://docs.openwebui.com/getting-started/advanced-topics/api-endpoints" href="https://docs.openwebui.com/getting-started/api-endpoints"
target="_blank" target="_blank"
class=" text-gray-300 font-medium underline" class=" text-gray-300 font-medium underline"
> >

View file

@ -68,7 +68,7 @@
const init = async () => { const init = async () => {
workspaceModels = await getBaseModels(localStorage.token); workspaceModels = await getBaseModels(localStorage.token);
baseModels = await getModels(localStorage.token, true); baseModels = await getModels(localStorage.token, null, true);
models = baseModels.map((m) => { models = baseModels.map((m) => {
const workspaceModel = workspaceModels.find((wm) => wm.id === m.id); const workspaceModel = workspaceModels.find((wm) => wm.id === m.id);
@ -111,7 +111,12 @@
} }
} }
_models.set(await getModels(localStorage.token)); _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
await init(); await init();
}; };
@ -133,7 +138,12 @@
} }
// await init(); // await init();
_models.set(await getModels(localStorage.token)); _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
onMount(async () => { onMount(async () => {
@ -330,7 +340,13 @@
} }
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections &&
($settings?.directConnections ?? null)
)
);
init(); init();
}; };

View file

@ -3,7 +3,7 @@
import { getContext, onMount } from 'svelte'; import { getContext, onMount } from 'svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import { WEBUI_NAME, models, MODEL_DOWNLOAD_POOL, user, config } from '$lib/stores'; import { WEBUI_NAME, models, MODEL_DOWNLOAD_POOL, user, config, settings } from '$lib/stores';
import { splitStream } from '$lib/utils'; import { splitStream } from '$lib/utils';
import { import {
@ -235,7 +235,12 @@
}) })
); );
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} else { } else {
toast.error($i18n.t('Download canceled')); toast.error($i18n.t('Download canceled'));
} }
@ -394,7 +399,12 @@
modelTransferring = false; modelTransferring = false;
uploadProgress = null; uploadProgress = null;
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
const deleteModelHandler = async () => { const deleteModelHandler = async () => {
@ -407,7 +417,12 @@
} }
deleteModelTag = ''; deleteModelTag = '';
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
}; };
const cancelModelPullHandler = async (model: string) => { const cancelModelPullHandler = async (model: string) => {
@ -506,7 +521,12 @@
} }
} }
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
createModelLoading = false; createModelLoading = false;

View file

@ -2,7 +2,7 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { models } from '$lib/stores'; import { config, models, settings } from '$lib/stores';
import { getContext, onMount, tick } from 'svelte'; import { getContext, onMount, tick } from 'svelte';
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
import type { i18n as i18nType } from 'i18next'; import type { i18n as i18nType } from 'i18next';
@ -63,7 +63,12 @@
if (res) { if (res) {
toast.success($i18n.t('Valves updated successfully')); toast.success($i18n.t('Valves updated successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
saveHandler(); saveHandler();
} }
} else { } else {
@ -125,7 +130,12 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline downloaded successfully')); toast.success($i18n.t('Pipeline downloaded successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
downloading = false; downloading = false;
@ -150,7 +160,12 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline downloaded successfully')); toast.success($i18n.t('Pipeline downloaded successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
} else { } else {
toast.error($i18n.t('No file selected')); toast.error($i18n.t('No file selected'));
@ -179,7 +194,12 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline deleted successfully')); toast.success($i18n.t('Pipeline deleted successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} }
}; };

View file

@ -18,6 +18,7 @@
'brave', 'brave',
'kagi', 'kagi',
'mojeek', 'mojeek',
'bocha',
'serpstack', 'serpstack',
'serper', 'serper',
'serply', 'serply',
@ -52,6 +53,8 @@
proxy_url: youtubeProxyUrl proxy_url: youtubeProxyUrl
} }
}); });
webConfig.search.domain_filter_list = webConfig.search.domain_filter_list.join(', ');
}; };
onMount(async () => { onMount(async () => {
@ -193,6 +196,17 @@
bind:value={webConfig.search.mojeek_search_api_key} bind:value={webConfig.search.mojeek_search_api_key}
/> />
</div> </div>
{:else if webConfig.search.engine === 'bocha'}
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Bocha Search API Key')}
</div>
<SensitiveInput
placeholder={$i18n.t('Enter Bocha Search API Key')}
bind:value={webConfig.search.bocha_search_api_key}
/>
</div>
{:else if webConfig.search.engine === 'serpstack'} {:else if webConfig.search.engine === 'serpstack'}
<div> <div>
<div class=" self-center text-xs font-medium mb-1"> <div class=" self-center text-xs font-medium mb-1">

View file

@ -1226,7 +1226,7 @@
selectedModels = _selectedModels; selectedModels = _selectedModels;
} }
if (userPrompt === '') { if (userPrompt === '' && files.length === 0) {
toast.error($i18n.t('Please enter a prompt')); toast.error($i18n.t('Please enter a prompt'));
return; return;
} }
@ -1478,7 +1478,7 @@
params?.stream_response ?? params?.stream_response ??
true; true;
const messages = [ let messages = [
params?.system || $settings.system || (responseMessage?.userContext ?? null) params?.system || $settings.system || (responseMessage?.userContext ?? null)
? { ? {
role: 'system', role: 'system',
@ -1499,8 +1499,9 @@
...message, ...message,
content: removeDetails(message.content, ['reasoning', 'code_interpreter']) content: removeDetails(message.content, ['reasoning', 'code_interpreter'])
})) }))
] ].filter((message) => message);
.filter((message) => message?.content?.trim())
messages = messages
.map((message, idx, arr) => ({ .map((message, idx, arr) => ({
role: message.role, role: message.role,
...((message.files?.filter((file) => file.type === 'image').length > 0 ?? false) && ...((message.files?.filter((file) => file.type === 'image').length > 0 ?? false) &&
@ -1524,7 +1525,8 @@
: { : {
content: message?.merged?.content ?? message.content content: message?.merged?.content ?? message.content
}) })
})); }))
.filter((message) => message?.role === 'user' || message?.content?.trim());
const res = await generateOpenAIChatCompletion( const res = await generateOpenAIChatCompletion(
localStorage.token, localStorage.token,
@ -1556,7 +1558,8 @@
? imageGenerationEnabled ? imageGenerationEnabled
: false, : false,
code_interpreter: code_interpreter:
$user.role === 'admin' || $user?.permissions?.features?.code_interpreter $config?.features?.enable_code_interpreter &&
($user.role === 'admin' || $user?.permissions?.features?.code_interpreter)
? codeInterpreterEnabled ? codeInterpreterEnabled
: false, : false,
web_search: web_search:
@ -1581,7 +1584,7 @@
(messages.length == 2 && (messages.length == 2 &&
messages.at(0)?.role === 'system' && messages.at(0)?.role === 'system' &&
messages.at(1)?.role === 'user')) && messages.at(1)?.role === 'user')) &&
selectedModels[0] === model.id (selectedModels[0] === model.id || atSelectedModel !== undefined)
? { ? {
background_tasks: { background_tasks: {
title_generation: $settings?.title?.auto ?? true, title_generation: $settings?.title?.auto ?? true,
@ -2006,7 +2009,7 @@
} }
}} }}
on:submit={async (e) => { on:submit={async (e) => {
if (e.detail) { if (e.detail || files.length > 0) {
await tick(); await tick();
submitPrompt( submitPrompt(
($settings?.richTextInput ?? true) ($settings?.richTextInput ?? true)
@ -2049,7 +2052,7 @@
} }
}} }}
on:submit={async (e) => { on:submit={async (e) => {
if (e.detail) { if (e.detail || files.length > 0) {
await tick(); await tick();
submitPrompt( submitPrompt(
($settings?.richTextInput ?? true) ($settings?.richTextInput ?? true)

View file

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

View file

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

View file

@ -122,6 +122,7 @@
</div> </div>
{:else} {:else}
<Collapsible <Collapsible
id="collapsible-sources"
bind:open={isCollapsibleOpen} bind:open={isCollapsibleOpen}
className="w-full max-w-full " className="w-full max-w-full "
buttonClassName="w-fit max-w-full" buttonClassName="w-fit max-w-full"
@ -178,6 +179,7 @@
<div class="flex text-xs font-medium flex-wrap"> <div class="flex text-xs font-medium flex-wrap">
{#each citations as citation, idx} {#each citations as citation, idx}
<button <button
id={`source-${citation.source.name}`}
class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96" class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96"
on:click={() => { on:click={() => {
showCitationModal = true; showCitationModal = true;

View file

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

View file

@ -4,12 +4,18 @@
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import { onMount, tick, getContext } from 'svelte'; import { onMount, tick, getContext } from 'svelte';
import type { Writable } from 'svelte/store';
import type { i18n as i18nType } from 'i18next';
const i18n = getContext<Writable<i18nType>>('i18n'); const i18n = getContext<Writable<i18nType>>('i18n');
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
import { config, models, settings, user } from '$lib/stores'; import { createNewFeedback, getFeedbackById, updateFeedbackById } from '$lib/apis/evaluations';
import { getChatById } from '$lib/apis/chats';
import { generateTags } from '$lib/apis';
import { config, models, settings, TTSWorker, user } from '$lib/stores';
import { synthesizeOpenAISpeech } from '$lib/apis/audio'; import { synthesizeOpenAISpeech } from '$lib/apis/audio';
import { imageGenerations } from '$lib/apis/images'; import { imageGenerations } from '$lib/apis/images';
import { import {
@ -34,13 +40,8 @@
import Error from './Error.svelte'; import Error from './Error.svelte';
import Citations from './Citations.svelte'; import Citations from './Citations.svelte';
import CodeExecutions from './CodeExecutions.svelte'; import CodeExecutions from './CodeExecutions.svelte';
import type { Writable } from 'svelte/store';
import type { i18n as i18nType } from 'i18next';
import ContentRenderer from './ContentRenderer.svelte'; import ContentRenderer from './ContentRenderer.svelte';
import { createNewFeedback, getFeedbackById, updateFeedbackById } from '$lib/apis/evaluations'; import { KokoroWorker } from '$lib/workers/KokoroWorker';
import { getChatById } from '$lib/apis/chats';
import { generateTags } from '$lib/apis';
interface MessageType { interface MessageType {
id: string; id: string;
@ -193,62 +194,7 @@
speaking = true; speaking = true;
if ($config.audio.tts.engine !== '') { if ($config.audio.tts.engine === '') {
loadingSpeech = true;
const messageContentParts: string[] = getMessageContentParts(
message.content,
$config?.audio?.tts?.split_on ?? 'punctuation'
);
if (!messageContentParts.length) {
console.log('No content to speak');
toast.info($i18n.t('No content to speak'));
speaking = false;
loadingSpeech = false;
return;
}
console.debug('Prepared message content for TTS', messageContentParts);
audioParts = messageContentParts.reduce(
(acc, _sentence, idx) => {
acc[idx] = null;
return acc;
},
{} as typeof audioParts
);
let lastPlayedAudioPromise = Promise.resolve(); // Initialize a promise that resolves immediately
for (const [idx, sentence] of messageContentParts.entries()) {
const res = await synthesizeOpenAISpeech(
localStorage.token,
$settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice
? ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
: $config?.audio?.tts?.voice,
sentence
).catch((error) => {
console.error(error);
toast.error(`${error}`);
speaking = false;
loadingSpeech = false;
});
if (res) {
const blob = await res.blob();
const blobUrl = URL.createObjectURL(blob);
const audio = new Audio(blobUrl);
audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
audioParts[idx] = audio;
loadingSpeech = false;
lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
}
}
} else {
let voices = []; let voices = [];
const getVoicesLoop = setInterval(() => { const getVoicesLoop = setInterval(() => {
voices = speechSynthesis.getVoices(); voices = speechSynthesis.getVoices();
@ -283,6 +229,97 @@
speechSynthesis.speak(speak); speechSynthesis.speak(speak);
} }
}, 100); }, 100);
} else {
loadingSpeech = true;
const messageContentParts: string[] = getMessageContentParts(
message.content,
$config?.audio?.tts?.split_on ?? 'punctuation'
);
if (!messageContentParts.length) {
console.log('No content to speak');
toast.info($i18n.t('No content to speak'));
speaking = false;
loadingSpeech = false;
return;
}
console.debug('Prepared message content for TTS', messageContentParts);
audioParts = messageContentParts.reduce(
(acc, _sentence, idx) => {
acc[idx] = null;
return acc;
},
{} as typeof audioParts
);
let lastPlayedAudioPromise = Promise.resolve(); // Initialize a promise that resolves immediately
if ($settings.audio?.tts?.engine === 'browser-kokoro') {
if (!$TTSWorker) {
await TTSWorker.set(
new KokoroWorker({
dtype: $settings.audio?.tts?.engineConfig?.dtype ?? 'fp32'
})
);
await $TTSWorker.init();
}
for (const [idx, sentence] of messageContentParts.entries()) {
const blob = await $TTSWorker
.generate({
text: sentence,
voice: $settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice
})
.catch((error) => {
console.error(error);
toast.error(`${error}`);
speaking = false;
loadingSpeech = false;
});
if (blob) {
const audio = new Audio(blob);
audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
audioParts[idx] = audio;
loadingSpeech = false;
lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
}
}
} else {
for (const [idx, sentence] of messageContentParts.entries()) {
const res = await synthesizeOpenAISpeech(
localStorage.token,
$settings?.audio?.tts?.defaultVoice === $config.audio.tts.voice
? ($settings?.audio?.tts?.voice ?? $config?.audio?.tts?.voice)
: $config?.audio?.tts?.voice,
sentence
).catch((error) => {
console.error(error);
toast.error(`${error}`);
speaking = false;
loadingSpeech = false;
});
if (res) {
const blob = await res.blob();
const blobUrl = URL.createObjectURL(blob);
const audio = new Audio(blobUrl);
audio.playbackRate = $settings.audio?.tts?.playbackRate ?? 1;
audioParts[idx] = audio;
loadingSpeech = false;
lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
}
}
}
} }
}; };
@ -679,12 +716,27 @@
floatingButtons={message?.done} floatingButtons={message?.done}
save={!readOnly} save={!readOnly}
{model} {model}
onSourceClick={(e) => { onSourceClick={async (e) => {
console.log(e); console.log(e);
const sourceButton = document.getElementById(`source-${e}`); let sourceButton = document.getElementById(`source-${e}`);
const sourcesCollapsible = document.getElementById(`collapsible-sources`);
if (sourceButton) { if (sourceButton) {
sourceButton.click(); sourceButton.click();
} else if (sourcesCollapsible) {
// Open sources collapsible so we can click the source button
sourcesCollapsible.querySelector("div:first-child").dispatchEvent(new PointerEvent('pointerup', {}))
// Wait for next frame to ensure DOM updates
await new Promise(resolve => {
requestAnimationFrame(() => {
requestAnimationFrame(resolve);
});
});
// Try clicking the source button again
sourceButton = document.getElementById(`source-${e}`);
sourceButton && sourceButton.click();
} }
}} }}
onAddMessages={({ modelId, parentId, messages }) => { onAddMessages={({ modelId, parentId, messages }) => {

View file

@ -145,6 +145,7 @@
</div> </div>
{/if} {/if}
{#if message.content !== ''}
{#if edit === true} {#if edit === true}
<div class=" w-full bg-gray-50 dark:bg-gray-800 rounded-3xl px-5 py-3 mb-2"> <div class=" w-full bg-gray-50 dark:bg-gray-800 rounded-3xl px-5 py-3 mb-2">
<div class="max-h-96 overflow-auto"> <div class="max-h-96 overflow-auto">
@ -254,7 +255,9 @@
</svg> </svg>
</button> </button>
<div class="text-sm tracking-widest font-semibold self-center dark:text-gray-100"> <div
class="text-sm tracking-widest font-semibold self-center dark:text-gray-100"
>
{siblings.indexOf(message.id) + 1}/{siblings.length} {siblings.indexOf(message.id) + 1}/{siblings.length}
</div> </div>
@ -383,7 +386,9 @@
</svg> </svg>
</button> </button>
<div class="text-sm tracking-widest font-semibold self-center dark:text-gray-100"> <div
class="text-sm tracking-widest font-semibold self-center dark:text-gray-100"
>
{siblings.indexOf(message.id) + 1}/{siblings.length} {siblings.indexOf(message.id) + 1}/{siblings.length}
</div> </div>
@ -414,6 +419,7 @@
</div> </div>
</div> </div>
{/if} {/if}
{/if}
</div> </div>
</div> </div>
</div> </div>

View file

@ -12,7 +12,15 @@
import { deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama'; import { deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama';
import { user, MODEL_DOWNLOAD_POOL, models, mobile, temporaryChatEnabled } from '$lib/stores'; import {
user,
MODEL_DOWNLOAD_POOL,
models,
mobile,
temporaryChatEnabled,
settings,
config
} from '$lib/stores';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { capitalizeFirstLetter, sanitizeResponseContent, splitStream } from '$lib/utils'; import { capitalizeFirstLetter, sanitizeResponseContent, splitStream } from '$lib/utils';
import { getModels } from '$lib/apis'; import { getModels } from '$lib/apis';
@ -186,7 +194,12 @@
}) })
); );
models.set(await getModels(localStorage.token)); models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
} else { } else {
toast.error($i18n.t('Download canceled')); toast.error($i18n.t('Download canceled'));
} }
@ -358,7 +371,24 @@
<!-- {JSON.stringify(item.info)} --> <!-- {JSON.stringify(item.info)} -->
{#if item.model.owned_by === 'openai'} {#if item.model?.direct}
<Tooltip content={`${'Direct'}`}>
<div class="translate-y-[1px]">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-3"
>
<path
fill-rule="evenodd"
d="M2 2.75A.75.75 0 0 1 2.75 2C8.963 2 14 7.037 14 13.25a.75.75 0 0 1-1.5 0c0-5.385-4.365-9.75-9.75-9.75A.75.75 0 0 1 2 2.75Zm0 4.5a.75.75 0 0 1 .75-.75 6.75 6.75 0 0 1 6.75 6.75.75.75 0 0 1-1.5 0C8 10.35 5.65 8 2.75 8A.75.75 0 0 1 2 7.25ZM3.5 11a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z"
clip-rule="evenodd"
/>
</svg>
</div>
</Tooltip>
{:else if item.model.owned_by === 'openai'}
<Tooltip content={`${'External'}`}> <Tooltip content={`${'External'}`}>
<div class="translate-y-[1px]"> <div class="translate-y-[1px]">
<svg <svg

View file

@ -114,7 +114,7 @@
</div> </div>
</button> </button>
</Menu> </Menu>
{:else if $mobile && ($user.role === 'admin' || $user?.permissions.chat?.controls)} {:else if $mobile && ($user.role === 'admin' || $user?.permissions?.chat?.controls)}
<Tooltip content={$i18n.t('Controls')}> <Tooltip content={$i18n.t('Controls')}>
<button <button
class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition" class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"
@ -130,7 +130,7 @@
</Tooltip> </Tooltip>
{/if} {/if}
{#if !$mobile && ($user.role === 'admin' || $user?.permissions.chat?.controls)} {#if !$mobile && ($user.role === 'admin' || $user?.permissions?.chat?.controls)}
<Tooltip content={$i18n.t('Controls')}> <Tooltip content={$i18n.t('Controls')}>
<button <button
class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition" class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"

View file

@ -3,7 +3,7 @@
import { onMount, getContext } from 'svelte'; import { onMount, getContext } from 'svelte';
import { user, config, settings } from '$lib/stores'; import { user, config, settings } from '$lib/stores';
import { updateUserProfile, createAPIKey, getAPIKey } from '$lib/apis/auths'; import { updateUserProfile, createAPIKey, getAPIKey, getSessionUser } from '$lib/apis/auths';
import UpdatePassword from './Account/UpdatePassword.svelte'; import UpdatePassword from './Account/UpdatePassword.svelte';
import { getGravatarUrl } from '$lib/apis/utils'; import { getGravatarUrl } from '$lib/apis/utils';
@ -53,7 +53,13 @@
); );
if (updatedUser) { if (updatedUser) {
await user.set(updatedUser); // Get Session User Info
const sessionUser = await getSessionUser(localStorage.token).catch((error) => {
toast.error(`${error}`);
return null;
});
await user.set(sessionUser);
return true; return true;
} }
return false; return false;

View file

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

View file

@ -0,0 +1,152 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
import { getModels as _getModels } from '$lib/apis';
const dispatch = createEventDispatcher();
const i18n = getContext('i18n');
import { models, settings, user } from '$lib/stores';
import Switch from '$lib/components/common/Switch.svelte';
import Spinner from '$lib/components/common/Spinner.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte';
import Plus from '$lib/components/icons/Plus.svelte';
import Connection from './Connections/Connection.svelte';
import AddConnectionModal from '$lib/components/AddConnectionModal.svelte';
export let saveSettings: Function;
let config = null;
let showConnectionModal = false;
const addConnectionHandler = async (connection) => {
config.OPENAI_API_BASE_URLS.push(connection.url);
config.OPENAI_API_KEYS.push(connection.key);
config.OPENAI_API_CONFIGS[config.OPENAI_API_BASE_URLS.length - 1] = connection.config;
await updateHandler();
};
const updateHandler = async () => {
// Remove trailing slashes
config.OPENAI_API_BASE_URLS = config.OPENAI_API_BASE_URLS.map((url) => url.replace(/\/$/, ''));
// Check if API KEYS length is same than API URLS length
if (config.OPENAI_API_KEYS.length !== config.OPENAI_API_BASE_URLS.length) {
// if there are more keys than urls, remove the extra keys
if (config.OPENAI_API_KEYS.length > config.OPENAI_API_BASE_URLS.length) {
config.OPENAI_API_KEYS = config.OPENAI_API_KEYS.slice(
0,
config.OPENAI_API_BASE_URLS.length
);
}
// if there are more urls than keys, add empty keys
if (config.OPENAI_API_KEYS.length < config.OPENAI_API_BASE_URLS.length) {
const diff = config.OPENAI_API_BASE_URLS.length - config.OPENAI_API_KEYS.length;
for (let i = 0; i < diff; i++) {
config.OPENAI_API_KEYS.push('');
}
}
}
await saveSettings({
directConnections: config
});
};
onMount(async () => {
config = $settings?.directConnections ?? {
OPENAI_API_BASE_URLS: [],
OPENAI_API_KEYS: [],
OPENAI_API_CONFIGS: {}
};
});
</script>
<AddConnectionModal direct bind:show={showConnectionModal} onSubmit={addConnectionHandler} />
<form
class="flex flex-col h-full justify-between text-sm"
on:submit|preventDefault={() => {
updateHandler();
}}
>
<div class=" overflow-y-scroll scrollbar-hidden h-full">
{#if config !== null}
<div class="">
<div class="pr-1.5">
<div class="">
<div class="flex justify-between items-center mb-0.5">
<div class="font-medium">{$i18n.t('Manage Direct Connections')}</div>
<Tooltip content={$i18n.t(`Add Connection`)}>
<button
class="px-1"
on:click={() => {
showConnectionModal = true;
}}
type="button"
>
<Plus />
</button>
</Tooltip>
</div>
<div class="flex flex-col gap-1.5">
{#each config?.OPENAI_API_BASE_URLS ?? [] as url, idx}
<Connection
bind:url
bind:key={config.OPENAI_API_KEYS[idx]}
bind:config={config.OPENAI_API_CONFIGS[idx]}
onSubmit={() => {
updateHandler();
}}
onDelete={() => {
config.OPENAI_API_BASE_URLS = config.OPENAI_API_BASE_URLS.filter(
(url, urlIdx) => idx !== urlIdx
);
config.OPENAI_API_KEYS = config.OPENAI_API_KEYS.filter(
(key, keyIdx) => idx !== keyIdx
);
let newConfig = {};
config.OPENAI_API_BASE_URLS.forEach((url, newIdx) => {
newConfig[newIdx] =
config.OPENAI_API_CONFIGS[newIdx < idx ? newIdx : newIdx + 1];
});
config.OPENAI_API_CONFIGS = newConfig;
}}
/>
{/each}
</div>
</div>
<div class="my-1.5">
<div class="text-xs text-gray-500">
{$i18n.t('Connect to your own OpenAI compatible API endpoints.')}
</div>
</div>
</div>
</div>
{:else}
<div class="flex h-full justify-center">
<div class="my-auto">
<Spinner className="size-6" />
</div>
</div>
{/if}
</div>
<div class="flex justify-end pt-3 text-sm font-medium">
<button
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
type="submit"
>
{$i18n.t('Save')}
</button>
</div>
</form>

View file

@ -0,0 +1,83 @@
<script lang="ts">
import { getContext, tick } from 'svelte';
const i18n = getContext('i18n');
import Tooltip from '$lib/components/common/Tooltip.svelte';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
import Cog6 from '$lib/components/icons/Cog6.svelte';
import AddConnectionModal from '$lib/components/AddConnectionModal.svelte';
export let onDelete = () => {};
export let onSubmit = () => {};
export let pipeline = false;
export let url = '';
export let key = '';
export let config = {};
let showConfigModal = false;
</script>
<AddConnectionModal
edit
bind:show={showConfigModal}
connection={{
url,
key,
config
}}
{onDelete}
onSubmit={(connection) => {
url = connection.url;
key = connection.key;
config = connection.config;
onSubmit(connection);
}}
/>
<div class="flex w-full gap-2 items-center">
<Tooltip
className="w-full relative"
content={$i18n.t(`WebUI will make requests to "{{url}}/chat/completions"`, {
url
})}
placement="top-start"
>
{#if !(config?.enable ?? true)}
<div
class="absolute top-0 bottom-0 left-0 right-0 opacity-60 bg-white dark:bg-gray-900 z-10"
></div>
{/if}
<div class="flex w-full">
<div class="flex-1 relative">
<input
class=" outline-none w-full bg-transparent {pipeline ? 'pr-8' : ''}"
placeholder={$i18n.t('API Base URL')}
bind:value={url}
autocomplete="off"
/>
</div>
<SensitiveInput
inputClassName=" outline-none bg-transparent w-full"
placeholder={$i18n.t('API Key')}
bind:value={key}
/>
</div>
</Tooltip>
<div class="flex gap-1">
<Tooltip content={$i18n.t('Configure')} className="self-start">
<button
class="self-center p-1 bg-transparent hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 rounded-lg transition"
on:click={() => {
showConfigModal = true;
}}
type="button"
>
<Cog6 />
</button>
</Tooltip>
</div>
</div>

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { getContext, tick } from 'svelte'; import { getContext, tick } from 'svelte';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { models, settings, user } from '$lib/stores'; import { config, models, settings, user } from '$lib/stores';
import { updateUserSettings } from '$lib/apis/users'; import { updateUserSettings } from '$lib/apis/users';
import { getModels as _getModels } from '$lib/apis'; import { getModels as _getModels } from '$lib/apis';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
@ -17,6 +17,7 @@
import Personalization from './Settings/Personalization.svelte'; import Personalization from './Settings/Personalization.svelte';
import SearchInput from '../layout/Sidebar/SearchInput.svelte'; import SearchInput from '../layout/Sidebar/SearchInput.svelte';
import Search from '../icons/Search.svelte'; import Search from '../icons/Search.svelte';
import Connections from './Settings/Connections.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -122,6 +123,11 @@
'alwaysonwebsearch' 'alwaysonwebsearch'
] ]
}, },
{
id: 'connections',
title: 'Connections',
keywords: []
},
{ {
id: 'personalization', id: 'personalization',
title: 'Personalization', title: 'Personalization',
@ -316,7 +322,10 @@
}; };
const getModels = async () => { const getModels = async () => {
return await _getModels(localStorage.token); return await _getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
);
}; };
let selectedTab = 'general'; let selectedTab = 'general';
@ -447,6 +456,32 @@
</div> </div>
<div class=" self-center">{$i18n.t('Interface')}</div> <div class=" self-center">{$i18n.t('Interface')}</div>
</button> </button>
{:else if tabId === 'connections'}
{#if $user.role === 'admin' || ($user.role === 'user' && $config?.features?.enable_direct_connections)}
<button
class="px-0.5 py-1 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
'connections'
? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => {
selectedTab = 'connections';
}}
>
<div class=" self-center mr-2">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M1 9.5A3.5 3.5 0 0 0 4.5 13H12a3 3 0 0 0 .917-5.857 2.503 2.503 0 0 0-3.198-3.019 3.5 3.5 0 0 0-6.628 2.171A3.5 3.5 0 0 0 1 9.5Z"
/>
</svg>
</div>
<div class=" self-center">{$i18n.t('Connections')}</div>
</button>
{/if}
{:else if tabId === 'personalization'} {:else if tabId === 'personalization'}
<button <button
class="px-0.5 py-1 min-w-fit rounded-lg flex-1 md:flex-none flex text-left transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg flex-1 md:flex-none flex text-left transition {selectedTab ===
@ -620,6 +655,13 @@
toast.success($i18n.t('Settings saved successfully!')); toast.success($i18n.t('Settings saved successfully!'));
}} }}
/> />
{:else if selectedTab === 'connections'}
<Connections
saveSettings={async (updated) => {
await saveSettings(updated);
toast.success($i18n.t('Settings saved successfully!'));
}}
/>
{:else if selectedTab === 'personalization'} {:else if selectedTab === 'personalization'}
<Personalization <Personalization
{saveSettings} {saveSettings}

View file

@ -34,6 +34,7 @@
import Spinner from './Spinner.svelte'; import Spinner from './Spinner.svelte';
export let open = false; export let open = false;
export let id = '';
export let className = ''; export let className = '';
export let buttonClassName = export let buttonClassName =
'w-fit text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition'; 'w-fit text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition';
@ -46,7 +47,7 @@
export let hide = false; export let hide = false;
</script> </script>
<div class={className}> <div id={id} class={className}>
{#if title !== null} {#if title !== null}
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->

View file

@ -68,7 +68,12 @@
toast.success($i18n.t(`Deleted {{name}}`, { name: model.id })); toast.success($i18n.t(`Deleted {{name}}`, { name: model.id }));
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };
@ -134,7 +139,12 @@
); );
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
)
);
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };
@ -371,7 +381,13 @@
bind:state={model.is_active} bind:state={model.is_active}
on:change={async (e) => { on:change={async (e) => {
toggleModelById(localStorage.token, model.id); toggleModelById(localStorage.token, model.id);
_models.set(await getModels(localStorage.token)); _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections &&
($settings?.directConnections ?? null)
)
);
}} }}
/> />
</Tooltip> </Tooltip>
@ -417,7 +433,13 @@
} }
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(
localStorage.token,
$config?.features?.enable_direct_connections &&
($settings?.directConnections ?? null)
)
);
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };

View file

@ -163,6 +163,7 @@
"Click here to": "أضغط هنا الانتقال", "Click here to": "أضغط هنا الانتقال",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "أضغط هنا للاختيار", "Click here to select": "أضغط هنا للاختيار",
"Click here to select a csv file.": "أضغط هنا للاختيار ملف csv", "Click here to select a csv file.": "أضغط هنا للاختيار ملف csv",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "مستندات", "Documents": "مستندات",
"does not make any external connections, and your data stays securely on your locally hosted server.": "لا يجري أي اتصالات خارجية، وتظل بياناتك آمنة على الخادم المستضاف محليًا.", "does not make any external connections, and your data stays securely on your locally hosted server.": "لا يجري أي اتصالات خارجية، وتظل بياناتك آمنة على الخادم المستضاف محليًا.",
"Domain Filter List": "",
"Don't have an account?": "ليس لديك حساب؟", "Don't have an account?": "ليس لديك حساب؟",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "أدخل الChunk Overlap", "Enter Chunk Overlap": "أدخل الChunk Overlap",
"Enter Chunk Size": "أدخل Chunk الحجم", "Enter Chunk Size": "أدخل Chunk الحجم",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "أدخل عنوان URL ل Github Raw", "Enter Github Raw URL": "أدخل عنوان URL ل Github Raw",
"Enter Google PSE API Key": "أدخل مفتاح واجهة برمجة تطبيقات PSE من Google", "Enter Google PSE API Key": "أدخل مفتاح واجهة برمجة تطبيقات PSE من Google",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "اللغة", "Language": "اللغة",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "فاتح", "Light": "فاتح",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Натиснете тук за", "Click here to": "Натиснете тук за",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Натиснете тук, за да изберете", "Click here to select": "Натиснете тук, за да изберете",
"Click here to select a csv file.": "Натиснете тук, за да изберете csv файл.", "Click here to select a csv file.": "Натиснете тук, за да изберете csv файл.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "Документи", "Documents": "Документи",
"does not make any external connections, and your data stays securely on your locally hosted server.": "няма външни връзки, и вашите данни остават сигурни на локално назначен сървър.", "does not make any external connections, and your data stays securely on your locally hosted server.": "няма външни връзки, и вашите данни остават сигурни на локално назначен сървър.",
"Domain Filter List": "",
"Don't have an account?": "Нямате акаунт?", "Don't have an account?": "Нямате акаунт?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Въведете Chunk Overlap", "Enter Chunk Overlap": "Въведете Chunk Overlap",
"Enter Chunk Size": "Въведете Chunk Size", "Enter Chunk Size": "Въведете Chunk Size",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Въведете URL адреса на Github Raw", "Enter Github Raw URL": "Въведете URL адреса на Github Raw",
"Enter Google PSE API Key": "Въведете Google PSE API ключ", "Enter Google PSE API Key": "Въведете Google PSE API ключ",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Език", "Language": "Език",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Светъл", "Light": "Светъл",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "এখানে ক্লিক করুন", "Click here to": "এখানে ক্লিক করুন",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "নির্বাচন করার জন্য এখানে ক্লিক করুন", "Click here to select": "নির্বাচন করার জন্য এখানে ক্লিক করুন",
"Click here to select a csv file.": "একটি csv ফাইল নির্বাচন করার জন্য এখানে ক্লিক করুন", "Click here to select a csv file.": "একটি csv ফাইল নির্বাচন করার জন্য এখানে ক্লিক করুন",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "ডকুমেন্টসমূহ", "Documents": "ডকুমেন্টসমূহ",
"does not make any external connections, and your data stays securely on your locally hosted server.": "কোন এক্সটার্নাল কানেকশন তৈরি করে না, এবং আপনার ডেটা আর লোকালি হোস্টেড সার্ভারেই নিরাপদে থাকে।", "does not make any external connections, and your data stays securely on your locally hosted server.": "কোন এক্সটার্নাল কানেকশন তৈরি করে না, এবং আপনার ডেটা আর লোকালি হোস্টেড সার্ভারেই নিরাপদে থাকে।",
"Domain Filter List": "",
"Don't have an account?": "একাউন্ট নেই?", "Don't have an account?": "একাউন্ট নেই?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "চাঙ্ক ওভারল্যাপ লিখুন", "Enter Chunk Overlap": "চাঙ্ক ওভারল্যাপ লিখুন",
"Enter Chunk Size": "চাংক সাইজ লিখুন", "Enter Chunk Size": "চাংক সাইজ লিখুন",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "গিটহাব কাঁচা URL লিখুন", "Enter Github Raw URL": "গিটহাব কাঁচা URL লিখুন",
"Enter Google PSE API Key": "গুগল পিএসই এপিআই কী লিখুন", "Enter Google PSE API Key": "গুগল পিএসই এপিআই কী লিখুন",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "ভাষা", "Language": "ভাষা",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "লাইট", "Light": "লাইট",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -63,11 +63,11 @@
"Allowed Endpoints": "Punts d'accés permesos", "Allowed Endpoints": "Punts d'accés permesos",
"Already have an account?": "Ja tens un compte?", "Already have an account?": "Ja tens un compte?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternativa al top_p, i pretén garantir un equilibri de qualitat i varietat. El paràmetre p representa la probabilitat mínima que es consideri un token, en relació amb la probabilitat del token més probable. Per exemple, amb p=0,05 i el token més probable amb una probabilitat de 0,9, es filtren els logits amb un valor inferior a 0,045. (Per defecte: 0.0)", "Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternativa al top_p, i pretén garantir un equilibri de qualitat i varietat. El paràmetre p representa la probabilitat mínima que es consideri un token, en relació amb la probabilitat del token més probable. Per exemple, amb p=0,05 i el token més probable amb una probabilitat de 0,9, es filtren els logits amb un valor inferior a 0,045. (Per defecte: 0.0)",
"Always": "", "Always": "Sempre",
"Amazing": "Al·lucinant", "Amazing": "Al·lucinant",
"an assistant": "un assistent", "an assistant": "un assistent",
"Analyzed": "", "Analyzed": "Analitzat",
"Analyzing...": "", "Analyzing...": "Analitzant...",
"and": "i", "and": "i",
"and {{COUNT}} more": "i {{COUNT}} més", "and {{COUNT}} more": "i {{COUNT}} més",
"and create a new shared link.": "i crear un nou enllaç compartit.", "and create a new shared link.": "i crear un nou enllaç compartit.",
@ -163,6 +163,7 @@
"Click here to": "Clic aquí per", "Click here to": "Clic aquí per",
"Click here to download user import template file.": "Fes clic aquí per descarregar l'arxiu de plantilla d'importació d'usuaris", "Click here to download user import template file.": "Fes clic aquí per descarregar l'arxiu de plantilla d'importació d'usuaris",
"Click here to learn more about faster-whisper and see the available models.": "Clica aquí per obtenir més informació sobre faster-whisper i veure els models disponibles.", "Click here to learn more about faster-whisper and see the available models.": "Clica aquí per obtenir més informació sobre faster-whisper i veure els models disponibles.",
"Click here to see available models.": "Clica aquí per veure els models disponibles.",
"Click here to select": "Clica aquí per seleccionar", "Click here to select": "Clica aquí per seleccionar",
"Click here to select a csv file.": "Clica aquí per seleccionar un fitxer csv.", "Click here to select a csv file.": "Clica aquí per seleccionar un fitxer csv.",
"Click here to select a py file.": "Clica aquí per seleccionar un fitxer py.", "Click here to select a py file.": "Clica aquí per seleccionar un fitxer py.",
@ -172,11 +173,11 @@
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permís d'escriptura al porta-retalls denegat. Comprova els ajustos de navegador per donar l'accés necessari.", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permís d'escriptura al porta-retalls denegat. Comprova els ajustos de navegador per donar l'accés necessari.",
"Clone": "Clonar", "Clone": "Clonar",
"Clone Chat": "Clonar el xat", "Clone Chat": "Clonar el xat",
"Clone of {{TITLE}}": "", "Clone of {{TITLE}}": "Clon de {{TITLE}}",
"Close": "Tancar", "Close": "Tancar",
"Code execution": "Execució de codi", "Code execution": "Execució de codi",
"Code formatted successfully": "Codi formatat correctament", "Code formatted successfully": "Codi formatat correctament",
"Code Interpreter": "", "Code Interpreter": "Intèrpret de codi",
"Collection": "Col·lecció", "Collection": "Col·lecció",
"Color": "Color", "Color": "Color",
"ComfyUI": "ComfyUI", "ComfyUI": "ComfyUI",
@ -238,7 +239,7 @@
"Default": "Per defecte", "Default": "Per defecte",
"Default (Open AI)": "Per defecte (Open AI)", "Default (Open AI)": "Per defecte (Open AI)",
"Default (SentenceTransformers)": "Per defecte (SentenceTransformers)", "Default (SentenceTransformers)": "Per defecte (SentenceTransformers)",
"Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the models built-in tool-calling capabilities, but requires the model to inherently support this feature.": "", "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the models built-in tool-calling capabilities, but requires the model to inherently support this feature.": "El mode predeterminat funciona amb una gamma més àmplia de models cridant a les eines una vegada abans de l'execució. El mode natiu aprofita les capacitats de crida d'eines integrades del model, però requereix que el model admeti aquesta funció de manera inherent.",
"Default Model": "Model per defecte", "Default Model": "Model per defecte",
"Default model updated": "Model per defecte actualitzat", "Default model updated": "Model per defecte actualitzat",
"Default Models": "Models per defecte", "Default Models": "Models per defecte",
@ -290,6 +291,7 @@
"Documentation": "Documentació", "Documentation": "Documentació",
"Documents": "Documents", "Documents": "Documents",
"does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.", "does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.",
"Domain Filter List": "Llista de filtre de dominis",
"Don't have an account?": "No tens un compte?", "Don't have an account?": "No tens un compte?",
"don't install random functions from sources you don't trust.": "no instal·lis funcions aleatòries de fonts en què no confiïs.", "don't install random functions from sources you don't trust.": "no instal·lis funcions aleatòries de fonts en què no confiïs.",
"don't install random tools from sources you don't trust.": "no instal·lis eines aleatòries de fonts en què no confiïs.", "don't install random tools from sources you don't trust.": "no instal·lis eines aleatòries de fonts en què no confiïs.",
@ -349,7 +351,8 @@
"Enter Chunk Overlap": "Introdueix la mida de solapament de blocs", "Enter Chunk Overlap": "Introdueix la mida de solapament de blocs",
"Enter Chunk Size": "Introdueix la mida del bloc", "Enter Chunk Size": "Introdueix la mida del bloc",
"Enter description": "Introdueix la descripció", "Enter description": "Introdueix la descripció",
"Enter Exa API Key": "", "Enter domains separated by commas (e.g., example.com,site.org)": "Introdueix els dominis separats per comes (p. ex. example.com,site.org)",
"Enter Exa API Key": "Introdueix la clau API de d'EXA",
"Enter Github Raw URL": "Introdueix l'URL en brut de Github", "Enter Github Raw URL": "Introdueix l'URL en brut de Github",
"Enter Google PSE API Key": "Introdueix la clau API de Google PSE", "Enter Google PSE API Key": "Introdueix la clau API de Google PSE",
"Enter Google PSE Engine Id": "Introdueix l'identificador del motor PSE de Google", "Enter Google PSE Engine Id": "Introdueix l'identificador del motor PSE de Google",
@ -398,14 +401,14 @@
"Error accessing Google Drive: {{error}}": "Error en accedir a Google Drive: {{error}}", "Error accessing Google Drive: {{error}}": "Error en accedir a Google Drive: {{error}}",
"Error uploading file: {{error}}": "Error en pujar l'arxiu: {{error}}", "Error uploading file: {{error}}": "Error en pujar l'arxiu: {{error}}",
"Evaluations": "Avaluacions", "Evaluations": "Avaluacions",
"Exa API Key": "", "Exa API Key": "Clau API d'EXA",
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Exemple: (&(objectClass=inetOrgPerson)(uid=%s))", "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Exemple: (&(objectClass=inetOrgPerson)(uid=%s))",
"Example: ALL": "Exemple: TOTS", "Example: ALL": "Exemple: TOTS",
"Example: mail": "Exemple: mail", "Example: mail": "Exemple: mail",
"Example: ou=users,dc=foo,dc=example": "Exemple: ou=users,dc=foo,dc=example", "Example: ou=users,dc=foo,dc=example": "Exemple: ou=users,dc=foo,dc=example",
"Example: sAMAccountName or uid or userPrincipalName": "Exemple: sAMAccountName o uid o userPrincipalName", "Example: sAMAccountName or uid or userPrincipalName": "Exemple: sAMAccountName o uid o userPrincipalName",
"Exclude": "Excloure", "Exclude": "Excloure",
"Execute code for analysis": "", "Execute code for analysis": "Executa el codi per analitzar-lo",
"Experimental": "Experimental", "Experimental": "Experimental",
"Explore the cosmos": "Explorar el cosmos", "Explore the cosmos": "Explorar el cosmos",
"Export": "Exportar", "Export": "Exportar",
@ -458,7 +461,7 @@
"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í:",
"Frequency Penalty": "Penalització per freqüència", "Frequency Penalty": "Penalització per freqüència",
"Function": "Funció", "Function": "Funció",
"Function Calling": "", "Function Calling": "Crida a funcions",
"Function created successfully": "La funció s'ha creat correctament", "Function created successfully": "La funció s'ha creat correctament",
"Function deleted successfully": "La funció s'ha eliminat correctament", "Function deleted successfully": "La funció s'ha eliminat correctament",
"Function Description": "Descripció de la funció", "Function Description": "Descripció de la funció",
@ -473,7 +476,7 @@
"Functions imported successfully": "Les funcions s'han importat correctament", "Functions imported successfully": "Les funcions s'han importat correctament",
"General": "General", "General": "General",
"General Settings": "Preferències generals", "General Settings": "Preferències generals",
"Generate an image": "", "Generate an image": "Generar una imatge",
"Generate Image": "Generar imatge", "Generate Image": "Generar imatge",
"Generating search query": "Generant consulta", "Generating search query": "Generant consulta",
"Get started": "Començar", "Get started": "Començar",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Coneixement eliminat correctament.", "Knowledge deleted successfully.": "Coneixement eliminat correctament.",
"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 Dtype": "Kokoro.js Dtype",
"Label": "Etiqueta", "Label": "Etiqueta",
"Landing Page Mode": "Mode de la pàgina d'entrada", "Landing Page Mode": "Mode de la pàgina d'entrada",
"Language": "Idioma", "Language": "Idioma",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{URL}}/models\"", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{URL}}/models\"",
"Leave empty to include all models or select specific models": "Deixa-ho en blanc per incloure tots els models o selecciona models específics", "Leave empty to include all models or select specific models": "Deixa-ho en blanc per incloure tots els models o selecciona models específics",
"Leave empty to use the default prompt, or enter a custom prompt": "Deixa-ho en blanc per utilitzar la indicació predeterminada o introdueix una indicació personalitzada", "Leave empty to use the default prompt, or enter a custom prompt": "Deixa-ho en blanc per utilitzar la indicació predeterminada o introdueix una indicació personalitzada",
"Leave model field empty to use the default model.": "Deixa el camp de model buit per utilitzar el model per defecte.",
"Light": "Clar", "Light": "Clar",
"Listening...": "Escoltant...", "Listening...": "Escoltant...",
"Llama.cpp": "Llama.cpp", "Llama.cpp": "Llama.cpp",
@ -630,7 +636,7 @@
"More": "Més", "More": "Més",
"Name": "Nom", "Name": "Nom",
"Name your knowledge base": "Anomena la teva base de coneixement", "Name your knowledge base": "Anomena la teva base de coneixement",
"Native": "", "Native": "Natiu",
"New Chat": "Nou xat", "New Chat": "Nou xat",
"New Folder": "Nova carpeta", "New Folder": "Nova carpeta",
"New Password": "Nova contrasenya", "New Password": "Nova contrasenya",
@ -725,7 +731,7 @@
"Please enter a prompt": "Si us plau, entra una indicació", "Please enter a prompt": "Si us plau, entra una indicació",
"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.": "", "Please select a model.": "Si us plau, selecciona un model.",
"Please select a reason": "Si us plau, selecciona una raó", "Please select a reason": "Si us plau, selecciona una raó",
"Port": "Port", "Port": "Port",
"Positive attitude": "Actitud positiva", "Positive attitude": "Actitud positiva",
@ -734,7 +740,7 @@
"Previous 30 days": "30 dies anteriors", "Previous 30 days": "30 dies anteriors",
"Previous 7 days": "7 dies anteriors", "Previous 7 days": "7 dies anteriors",
"Profile Image": "Imatge de perfil", "Profile Image": "Imatge de perfil",
"Prompt": "", "Prompt": "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 Content": "Contingut de la indicació", "Prompt Content": "Contingut de la indicació",
"Prompt created successfully": "Indicació creada correctament", "Prompt created successfully": "Indicació creada correctament",
@ -810,7 +816,7 @@
"Search options": "Opcions de cerca", "Search options": "Opcions de cerca",
"Search Prompts": "Cercar indicacions", "Search Prompts": "Cercar indicacions",
"Search Result Count": "Recompte de resultats de cerca", "Search Result Count": "Recompte de resultats de cerca",
"Search the internet": "", "Search the internet": "Cerca a internet",
"Search Tools": "Cercar eines", "Search Tools": "Cercar eines",
"SearchApi API Key": "Clau API de SearchApi", "SearchApi API Key": "Clau API de SearchApi",
"SearchApi Engine": "Motor de SearchApi", "SearchApi Engine": "Motor de SearchApi",
@ -943,7 +949,8 @@
"This will delete all models including custom models and cannot be undone.": "Això eliminarà tots els models incloent els personalitzats i no es pot desfer", "This will delete all models including custom models and cannot be undone.": "Això eliminarà tots els models incloent els personalitzats i no es pot desfer",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Això restablirà la base de coneixement i sincronitzarà tots els fitxers. Vols continuar?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Això restablirà la base de coneixement i sincronitzarà tots els fitxers. Vols continuar?",
"Thorough explanation": "Explicació en detall", "Thorough explanation": "Explicació en detall",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "He pensat durant {{DURATION}}",
"Thought for {{DURATION}} seconds": "He pensat durant {{DURATION}} segons",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "La URL del servidor Tika és obligatòria.", "Tika Server URL required.": "La URL del servidor Tika és obligatòria.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",
@ -980,7 +987,7 @@
"Tools": "Eines", "Tools": "Eines",
"Tools Access": "Accés a les eines", "Tools Access": "Accés a les eines",
"Tools are a function calling system with arbitrary code execution": "Les eines són un sistema de crida a funcions amb execució de codi arbitrari", "Tools are a function calling system with arbitrary code execution": "Les eines són un sistema de crida a funcions amb execució de codi arbitrari",
"Tools Function Calling Prompt": "", "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.",
"Top K": "Top K", "Top K": "Top K",
@ -1051,7 +1058,7 @@
"Web Loader Settings": "Preferències del carregador web", "Web Loader Settings": "Preferències del carregador web",
"Web Search": "Cerca la web", "Web Search": "Cerca la web",
"Web Search Engine": "Motor de cerca de la web", "Web Search Engine": "Motor de cerca de la web",
"Web Search in Chat": "", "Web Search in Chat": "Cerca a internet al xat",
"Web Search Query Generation": "Generació de consultes per a la cerca de la web", "Web Search Query Generation": "Generació de consultes per a la cerca de la web",
"Webhook URL": "URL del webhook", "Webhook URL": "URL del webhook",
"WebUI Settings": "Preferències de WebUI", "WebUI Settings": "Preferències de WebUI",
@ -1081,7 +1088,7 @@
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pots personalitzar les teves interaccions amb els models de llenguatge afegint memòries mitjançant el botó 'Gestiona' que hi ha a continuació, fent-les més útils i adaptades a tu.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pots personalitzar les teves interaccions amb els models de llenguatge afegint memòries mitjançant el botó 'Gestiona' que hi ha a continuació, fent-les més útils i adaptades a tu.",
"You cannot upload an empty file.": "No es pot pujar un ariux buit.", "You cannot upload an empty file.": "No es pot pujar un ariux buit.",
"You do not have permission to access this feature.": "No tens permís per accedir a aquesta funcionalitat", "You do not have permission to access this feature.": "No tens permís per accedir a aquesta funcionalitat",
"You do not have permission to upload files": "", "You do not have permission to upload files": "No tens permisos per pujar arxius",
"You do not have permission to upload files.": "No tens permisos per pujar arxius.", "You do not have permission to upload files.": "No tens permisos per pujar arxius.",
"You have no archived conversations.": "No tens converses arxivades.", "You have no archived conversations.": "No tens converses arxivades.",
"You have shared this chat": "Has compartit aquest xat", "You have shared this chat": "Has compartit aquest xat",

View file

@ -163,6 +163,7 @@
"Click here to": "", "Click here to": "",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "I-klik dinhi aron makapili", "Click here to select": "I-klik dinhi aron makapili",
"Click here to select a csv file.": "", "Click here to select a csv file.": "",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "Mga dokumento", "Documents": "Mga dokumento",
"does not make any external connections, and your data stays securely on your locally hosted server.": "wala maghimo ug eksternal nga koneksyon, ug ang imong data nagpabiling luwas sa imong lokal nga host server.", "does not make any external connections, and your data stays securely on your locally hosted server.": "wala maghimo ug eksternal nga koneksyon, ug ang imong data nagpabiling luwas sa imong lokal nga host server.",
"Domain Filter List": "",
"Don't have an account?": "Wala kay account ?", "Don't have an account?": "Wala kay account ?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Pagsulod sa block overlap", "Enter Chunk Overlap": "Pagsulod sa block overlap",
"Enter Chunk Size": "Isulod ang block size", "Enter Chunk Size": "Isulod ang block size",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "", "Enter Github Raw URL": "",
"Enter Google PSE API Key": "", "Enter Google PSE API Key": "",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Pinulongan", "Language": "Pinulongan",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Kahayag", "Light": "Kahayag",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klikněte sem pro", "Click here to": "Klikněte sem pro",
"Click here to download user import template file.": "Klikněte zde pro stažení šablony souboru pro import uživatelů.", "Click here to download user import template file.": "Klikněte zde pro stažení šablony souboru pro import uživatelů.",
"Click here to learn more about faster-whisper and see the available models.": "Klikněte sem a zjistěte více o faster-whisper a podívejte se na dostupné modely.", "Click here to learn more about faster-whisper and see the available models.": "Klikněte sem a zjistěte více o faster-whisper a podívejte se na dostupné modely.",
"Click here to see available models.": "",
"Click here to select": "Klikněte sem pro výběr", "Click here to select": "Klikněte sem pro výběr",
"Click here to select a csv file.": "Klikněte zde pro výběr souboru typu csv.", "Click here to select a csv file.": "Klikněte zde pro výběr souboru typu csv.",
"Click here to select a py file.": "Klikněte sem pro výběr {{py}} souboru.", "Click here to select a py file.": "Klikněte sem pro výběr {{py}} souboru.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentace", "Documentation": "Dokumentace",
"Documents": "Dokumenty", "Documents": "Dokumenty",
"does not make any external connections, and your data stays securely on your locally hosted server.": "nevytváří žádná externí připojení a vaše data zůstávají bezpečně na vašem lokálním serveru.", "does not make any external connections, and your data stays securely on your locally hosted server.": "nevytváří žádná externí připojení a vaše data zůstávají bezpečně na vašem lokálním serveru.",
"Domain Filter List": "",
"Don't have an account?": "Nemáte účet?", "Don't have an account?": "Nemáte účet?",
"don't install random functions from sources you don't trust.": "Neinstalujte náhodné funkce ze zdrojů, kterým nedůvěřujete.", "don't install random functions from sources you don't trust.": "Neinstalujte náhodné funkce ze zdrojů, kterým nedůvěřujete.",
"don't install random tools from sources you don't trust.": "Neinstalujte náhodné nástroje ze zdrojů, kterým nedůvěřujete.", "don't install random tools from sources you don't trust.": "Neinstalujte náhodné nástroje ze zdrojů, kterým nedůvěřujete.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Zadejte překryv části", "Enter Chunk Overlap": "Zadejte překryv části",
"Enter Chunk Size": "Zadejte velikost bloku", "Enter Chunk Size": "Zadejte velikost bloku",
"Enter description": "Zadejte popis", "Enter description": "Zadejte popis",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Zadejte URL adresu Github Raw", "Enter Github Raw URL": "Zadejte URL adresu Github Raw",
"Enter Google PSE API Key": "Zadejte klíč rozhraní API Google PSE", "Enter Google PSE API Key": "Zadejte klíč rozhraní API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Znalosti byly úspěšně odstraněny.", "Knowledge deleted successfully.": "Znalosti byly úspěšně odstraněny.",
"Knowledge reset successfully.": "Úspěšné obnovení znalostí.", "Knowledge reset successfully.": "Úspěšné obnovení znalostí.",
"Knowledge updated successfully": "Znalosti úspěšně aktualizovány", "Knowledge updated successfully": "Znalosti úspěšně aktualizovány",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Režim vstupní stránky", "Landing Page Mode": "Režim vstupní stránky",
"Language": "Jazyk", "Language": "Jazyk",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"Leave empty to include all models or select specific models": "Nechte prázdné pro zahrnutí všech modelů nebo vyberte konkrétní modely.", "Leave empty to include all models or select specific models": "Nechte prázdné pro zahrnutí všech modelů nebo vyberte konkrétní modely.",
"Leave empty to use the default prompt, or enter a custom prompt": "Nechte prázdné pro použití výchozího podnětu, nebo zadejte vlastní podnět.", "Leave empty to use the default prompt, or enter a custom prompt": "Nechte prázdné pro použití výchozího podnětu, nebo zadejte vlastní podnět.",
"Leave model field empty to use the default model.": "",
"Light": "Světlo", "Light": "Světlo",
"Listening...": "Poslouchání...", "Listening...": "Poslouchání...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostní databázi a synchronizuje všechny soubory. Přejete si pokračovat?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostní databázi a synchronizuje všechny soubory. Přejete si pokračovat?",
"Thorough explanation": "Obsáhlé vysvětlení", "Thorough explanation": "Obsáhlé vysvětlení",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Je vyžadována URL adresa serveru Tika.", "Tika Server URL required.": "Je vyžadována URL adresa serveru Tika.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Klik her for at", "Click here to": "Klik her for at",
"Click here to download user import template file.": "Klik her for at downloade bruger import template fil.", "Click here to download user import template file.": "Klik her for at downloade bruger import template fil.",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Klik her for at vælge", "Click here to select": "Klik her for at vælge",
"Click here to select a csv file.": "Klik her for at vælge en csv fil", "Click here to select a csv file.": "Klik her for at vælge en csv fil",
"Click here to select a py file.": "Klik her for at vælge en py fil", "Click here to select a py file.": "Klik her for at vælge en py fil",
@ -290,6 +291,7 @@
"Documentation": "Dokumentation", "Documentation": "Dokumentation",
"Documents": "Dokumenter", "Documents": "Dokumenter",
"does not make any external connections, and your data stays securely on your locally hosted server.": "laver ikke eksterne kald, og din data bliver sikkert på din egen lokalt hostede server.", "does not make any external connections, and your data stays securely on your locally hosted server.": "laver ikke eksterne kald, og din data bliver sikkert på din egen lokalt hostede server.",
"Domain Filter List": "",
"Don't have an account?": "Har du ikke en profil?", "Don't have an account?": "Har du ikke en profil?",
"don't install random functions from sources you don't trust.": "lad være med at installere tilfældige funktioner fra kilder, som du ikke stoler på.", "don't install random functions from sources you don't trust.": "lad være med at installere tilfældige funktioner fra kilder, som du ikke stoler på.",
"don't install random tools from sources you don't trust.": "lad være med at installere tilfældige værktøjer fra kilder, som du ikke stoler på.", "don't install random tools from sources you don't trust.": "lad være med at installere tilfældige værktøjer fra kilder, som du ikke stoler på.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Indtast overlapning af tekststykker", "Enter Chunk Overlap": "Indtast overlapning af tekststykker",
"Enter Chunk Size": "Indtast størrelse af tekststykker", "Enter Chunk Size": "Indtast størrelse af tekststykker",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Indtast Github Raw URL", "Enter Github Raw URL": "Indtast Github Raw URL",
"Enter Google PSE API Key": "Indtast Google PSE API-nøgle", "Enter Google PSE API Key": "Indtast Google PSE API-nøgle",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Viden slettet.", "Knowledge deleted successfully.": "Viden slettet.",
"Knowledge reset successfully.": "Viden nulstillet.", "Knowledge reset successfully.": "Viden nulstillet.",
"Knowledge updated successfully": "Viden opdateret.", "Knowledge updated successfully": "Viden opdateret.",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Landing Page-tilstand", "Landing Page Mode": "Landing Page-tilstand",
"Language": "Sprog", "Language": "Sprog",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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": "Lad stå tomt for at bruge standardprompten, eller indtast en brugerdefineret prompt", "Leave empty to use the default prompt, or enter a custom prompt": "Lad stå tomt for at bruge standardprompten, eller indtast en brugerdefineret prompt",
"Leave model field empty to use the default model.": "",
"Light": "Lys", "Light": "Lys",
"Listening...": "Lytter...", "Listening...": "Lytter...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette vil nulstille vidensbasen og synkronisere alle filer. Vil du fortsætte?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette vil nulstille vidensbasen og synkronisere alle filer. Vil du fortsætte?",
"Thorough explanation": "Grundig forklaring", "Thorough explanation": "Grundig forklaring",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika-server-URL påkrævet.", "Tika Server URL required.": "Tika-server-URL påkrævet.",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klicken Sie hier, um", "Click here to": "Klicken Sie hier, um",
"Click here to download user import template file.": "Klicken Sie hier, um die Vorlage für den Benutzerimport herunterzuladen.", "Click here to download user import template file.": "Klicken Sie hier, um die Vorlage für den Benutzerimport herunterzuladen.",
"Click here to learn more about faster-whisper and see the available models.": "Klicken Sie hier, um mehr über faster-whisper zu erfahren und die verfügbaren Modelle zu sehen.", "Click here to learn more about faster-whisper and see the available models.": "Klicken Sie hier, um mehr über faster-whisper zu erfahren und die verfügbaren Modelle zu sehen.",
"Click here to see available models.": "",
"Click here to select": "Klicke Sie zum Auswählen hier", "Click here to select": "Klicke Sie zum Auswählen hier",
"Click here to select a csv file.": "Klicken Sie zum Auswählen einer CSV-Datei hier.", "Click here to select a csv file.": "Klicken Sie zum Auswählen einer CSV-Datei hier.",
"Click here to select a py file.": "Klicken Sie zum Auswählen einer py-Datei hier.", "Click here to select a py file.": "Klicken Sie zum Auswählen einer py-Datei hier.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentation", "Documentation": "Dokumentation",
"Documents": "Dokumente", "Documents": "Dokumente",
"does not make any external connections, and your data stays securely on your locally hosted server.": "stellt keine externen Verbindungen her, und Ihre Daten bleiben sicher auf Ihrem lokal gehosteten Server.", "does not make any external connections, and your data stays securely on your locally hosted server.": "stellt keine externen Verbindungen her, und Ihre Daten bleiben sicher auf Ihrem lokal gehosteten Server.",
"Domain Filter List": "",
"Don't have an account?": "Haben Sie noch kein Benutzerkonto?", "Don't have an account?": "Haben Sie noch kein Benutzerkonto?",
"don't install random functions from sources you don't trust.": "installieren Sie keine Funktionen aus Quellen, denen Sie nicht vertrauen.", "don't install random functions from sources you don't trust.": "installieren Sie keine Funktionen aus Quellen, denen Sie nicht vertrauen.",
"don't install random tools from sources you don't trust.": "installieren Sie keine Werkzeuge aus Quellen, denen Sie nicht vertrauen.", "don't install random tools from sources you don't trust.": "installieren Sie keine Werkzeuge aus Quellen, denen Sie nicht vertrauen.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Geben Sie die Blocküberlappung ein", "Enter Chunk Overlap": "Geben Sie die Blocküberlappung ein",
"Enter Chunk Size": "Geben Sie die Blockgröße ein", "Enter Chunk Size": "Geben Sie die Blockgröße ein",
"Enter description": "Geben Sie eine Beschreibung ein", "Enter description": "Geben Sie eine Beschreibung ein",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "Geben Sie den Exa-API-Schlüssel ein", "Enter Exa API Key": "Geben Sie den Exa-API-Schlüssel ein",
"Enter Github Raw URL": "Geben Sie die Github Raw-URL ein", "Enter Github Raw URL": "Geben Sie die Github Raw-URL ein",
"Enter Google PSE API Key": "Geben Sie den Google PSE-API-Schlüssel ein", "Enter Google PSE API Key": "Geben Sie den Google PSE-API-Schlüssel ein",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Wissen erfolgreich gelöscht.", "Knowledge deleted successfully.": "Wissen erfolgreich gelöscht.",
"Knowledge reset successfully.": "Wissen erfolgreich zurückgesetzt.", "Knowledge reset successfully.": "Wissen erfolgreich zurückgesetzt.",
"Knowledge updated successfully": "Wissen erfolgreich aktualisiert", "Knowledge updated successfully": "Wissen erfolgreich aktualisiert",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Label", "Label": "Label",
"Landing Page Mode": "Startseitenmodus", "Landing Page Mode": "Startseitenmodus",
"Language": "Sprache", "Language": "Sprache",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Leer lassen, um alle Modelle vom \"{{URL}}/models\"-Endpunkt einzuschließen", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Leer lassen, um alle Modelle vom \"{{URL}}/models\"-Endpunkt einzuschließen",
"Leave empty to include all models or select specific models": "Leer lassen, um alle Modelle einzuschließen oder spezifische Modelle auszuwählen", "Leave empty to include all models or select specific models": "Leer lassen, um alle Modelle einzuschließen oder spezifische Modelle auszuwählen",
"Leave empty to use the default prompt, or enter a custom prompt": "Leer lassen, um den Standardprompt zu verwenden, oder geben Sie einen benutzerdefinierten Prompt ein", "Leave empty to use the default prompt, or enter a custom prompt": "Leer lassen, um den Standardprompt zu verwenden, oder geben Sie einen benutzerdefinierten Prompt ein",
"Leave model field empty to use the default model.": "",
"Light": "Hell", "Light": "Hell",
"Listening...": "Höre zu...", "Listening...": "Höre zu...",
"Llama.cpp": "Llama.cpp", "Llama.cpp": "Llama.cpp",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dadurch wird die Wissensdatenbank zurückgesetzt und alle Dateien synchronisiert. Möchten Sie fortfahren?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Dadurch wird die Wissensdatenbank zurückgesetzt und alle Dateien synchronisiert. Möchten Sie fortfahren?",
"Thorough explanation": "Ausführliche Erklärung", "Thorough explanation": "Ausführliche Erklärung",
"Thought for {{DURATION}}": "Nachgedacht für {{DURATION}}", "Thought for {{DURATION}}": "Nachgedacht für {{DURATION}}",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika-Server-URL erforderlich.", "Tika Server URL required.": "Tika-Server-URL erforderlich.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "", "Click here to": "",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Click to select", "Click here to select": "Click to select",
"Click here to select a csv file.": "", "Click here to select a csv file.": "",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "Documents", "Documents": "Documents",
"does not make any external connections, and your data stays securely on your locally hosted server.": "does not connect external, data stays safe locally.", "does not make any external connections, and your data stays securely on your locally hosted server.": "does not connect external, data stays safe locally.",
"Domain Filter List": "",
"Don't have an account?": "No account? Much sad.", "Don't have an account?": "No account? Much sad.",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Enter Overlap of Chunks", "Enter Chunk Overlap": "Enter Overlap of Chunks",
"Enter Chunk Size": "Enter Size of Chunk", "Enter Chunk Size": "Enter Size of Chunk",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "", "Enter Github Raw URL": "",
"Enter Google PSE API Key": "", "Enter Google PSE API Key": "",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Doge Speak", "Language": "Doge Speak",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Light", "Light": "Light",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Κάντε κλικ εδώ για να", "Click here to": "Κάντε κλικ εδώ για να",
"Click here to download user import template file.": "Κάντε κλικ εδώ για να κατεβάσετε το αρχείο προτύπου εισαγωγής χρήστη.", "Click here to download user import template file.": "Κάντε κλικ εδώ για να κατεβάσετε το αρχείο προτύπου εισαγωγής χρήστη.",
"Click here to learn more about faster-whisper and see the available models.": "Κάντε κλικ εδώ για να μάθετε περισσότερα σχετικά με το faster-whisper και να δείτε τα διαθέσιμα μοντέλα.", "Click here to learn more about faster-whisper and see the available models.": "Κάντε κλικ εδώ για να μάθετε περισσότερα σχετικά με το faster-whisper και να δείτε τα διαθέσιμα μοντέλα.",
"Click here to see available models.": "",
"Click here to select": "Κάντε κλικ εδώ για επιλογή", "Click here to select": "Κάντε κλικ εδώ για επιλογή",
"Click here to select a csv file.": "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο csv.", "Click here to select a csv file.": "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο csv.",
"Click here to select a py file.": "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο py.", "Click here to select a py file.": "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο py.",
@ -290,6 +291,7 @@
"Documentation": "Τεκμηρίωση", "Documentation": "Τεκμηρίωση",
"Documents": "Έγγραφα", "Documents": "Έγγραφα",
"does not make any external connections, and your data stays securely on your locally hosted server.": "δεν κάνει καμία εξωτερική σύνδεση, και τα δεδομένα σας παραμένουν ασφαλή στον τοπικά φιλοξενούμενο διακομιστή σας.", "does not make any external connections, and your data stays securely on your locally hosted server.": "δεν κάνει καμία εξωτερική σύνδεση, και τα δεδομένα σας παραμένουν ασφαλή στον τοπικά φιλοξενούμενο διακομιστή σας.",
"Domain Filter List": "",
"Don't have an account?": "Δεν έχετε λογαριασμό;", "Don't have an account?": "Δεν έχετε λογαριασμό;",
"don't install random functions from sources you don't trust.": "μην εγκαθιστάτε τυχαίες λειτουργίες από πηγές που δεν εμπιστεύεστε.", "don't install random functions from sources you don't trust.": "μην εγκαθιστάτε τυχαίες λειτουργίες από πηγές που δεν εμπιστεύεστε.",
"don't install random tools from sources you don't trust.": "μην εγκαθιστάτε τυχαία εργαλεία από πηγές που δεν εμπιστεύεστε.", "don't install random tools from sources you don't trust.": "μην εγκαθιστάτε τυχαία εργαλεία από πηγές που δεν εμπιστεύεστε.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Εισάγετε την Επικάλυψη Τμημάτων", "Enter Chunk Overlap": "Εισάγετε την Επικάλυψη Τμημάτων",
"Enter Chunk Size": "Εισάγετε το Μέγεθος Τμημάτων", "Enter Chunk Size": "Εισάγετε το Μέγεθος Τμημάτων",
"Enter description": "Εισάγετε την περιγραφή", "Enter description": "Εισάγετε την περιγραφή",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Εισάγετε το Github Raw URL", "Enter Github Raw URL": "Εισάγετε το Github Raw URL",
"Enter Google PSE API Key": "Εισάγετε το Κλειδί API Google PSE", "Enter Google PSE API Key": "Εισάγετε το Κλειδί API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Η γνώση διαγράφηκε με επιτυχία.", "Knowledge deleted successfully.": "Η γνώση διαγράφηκε με επιτυχία.",
"Knowledge reset successfully.": "Η γνώση επαναφέρθηκε με επιτυχία.", "Knowledge reset successfully.": "Η γνώση επαναφέρθηκε με επιτυχία.",
"Knowledge updated successfully": "Η γνώση ενημερώθηκε με επιτυχία", "Knowledge updated successfully": "Η γνώση ενημερώθηκε με επιτυχία",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Ετικέτα", "Label": "Ετικέτα",
"Landing Page Mode": "Λειτουργία Σελίδας Άφιξης", "Landing Page Mode": "Λειτουργία Σελίδας Άφιξης",
"Language": "Γλώσσα", "Language": "Γλώσσα",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Αφήστε κενό για να συμπεριλάβετε όλα τα μοντέλα από το endpoint \"{{URL}}/models\"", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Αφήστε κενό για να συμπεριλάβετε όλα τα μοντέλα από το endpoint \"{{URL}}/models\"",
"Leave empty to include all models or select specific models": "Αφήστε κενό για να χρησιμοποιήσετε όλα τα μοντέλα ή επιλέξτε συγκεκριμένα μοντέλα", "Leave empty to 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.": "",
"Light": "Φως", "Light": "Φως",
"Listening...": "Ακούγεται...", "Listening...": "Ακούγεται...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Απαιτείται το URL διακομιστή Tika.", "Tika Server URL required.": "Απαιτείται το URL διακομιστή Tika.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "", "Click here to": "",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "", "Click here to select": "",
"Click here to select a csv file.": "", "Click here to select a csv file.": "",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "", "Documents": "",
"does not make any external connections, and your data stays securely on your locally hosted server.": "", "does not make any external connections, and your data stays securely on your locally hosted server.": "",
"Domain Filter List": "",
"Don't have an account?": "", "Don't have an account?": "",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "", "Enter Chunk Overlap": "",
"Enter Chunk Size": "", "Enter Chunk Size": "",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "", "Enter Github Raw URL": "",
"Enter Google PSE API Key": "", "Enter Google PSE API Key": "",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "", "Language": "",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "", "Light": "",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "", "Click here to": "",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "", "Click here to select": "",
"Click here to select a csv file.": "", "Click here to select a csv file.": "",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "", "Documents": "",
"does not make any external connections, and your data stays securely on your locally hosted server.": "", "does not make any external connections, and your data stays securely on your locally hosted server.": "",
"Domain Filter List": "",
"Don't have an account?": "", "Don't have an account?": "",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "", "Enter Chunk Overlap": "",
"Enter Chunk Size": "", "Enter Chunk Size": "",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "", "Enter Github Raw URL": "",
"Enter Google PSE API Key": "", "Enter Google PSE API Key": "",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "", "Language": "",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "", "Light": "",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",

File diff suppressed because it is too large Load diff

View file

@ -163,6 +163,7 @@
"Click here to": "Klikatu hemen", "Click here to": "Klikatu hemen",
"Click here to download user import template file.": "Klikatu hemen erabiltzaileen inportazio txantiloia deskargatzeko.", "Click here to download user import template file.": "Klikatu hemen erabiltzaileen inportazio txantiloia deskargatzeko.",
"Click here to learn more about faster-whisper and see the available models.": "Klikatu hemen faster-whisper-i buruz gehiago ikasteko eta eredu erabilgarriak ikusteko.", "Click here to learn more about faster-whisper and see the available models.": "Klikatu hemen faster-whisper-i buruz gehiago ikasteko eta eredu erabilgarriak ikusteko.",
"Click here to see available models.": "",
"Click here to select": "Klikatu hemen hautatzeko", "Click here to select": "Klikatu hemen hautatzeko",
"Click here to select a csv file.": "Klikatu hemen csv fitxategi bat hautatzeko.", "Click here to select a csv file.": "Klikatu hemen csv fitxategi bat hautatzeko.",
"Click here to select a py file.": "Klikatu hemen py fitxategi bat hautatzeko.", "Click here to select a py file.": "Klikatu hemen py fitxategi bat hautatzeko.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentazioa", "Documentation": "Dokumentazioa",
"Documents": "Dokumentuak", "Documents": "Dokumentuak",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ez du kanpo konexiorik egiten, eta zure datuak modu seguruan mantentzen dira zure zerbitzari lokalean.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ez du kanpo konexiorik egiten, eta zure datuak modu seguruan mantentzen dira zure zerbitzari lokalean.",
"Domain Filter List": "",
"Don't have an account?": "Ez duzu konturik?", "Don't have an account?": "Ez duzu konturik?",
"don't install random functions from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko funtzioak.", "don't install random functions from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko funtzioak.",
"don't install random tools from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko tresnak.", "don't install random tools from sources you don't trust.": "ez instalatu fidagarriak ez diren iturrietatik datozen ausazko tresnak.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Sartu Zatien Gainjartzea (chunk overlap)", "Enter Chunk Overlap": "Sartu Zatien Gainjartzea (chunk overlap)",
"Enter Chunk Size": "Sartu Zati Tamaina", "Enter Chunk Size": "Sartu Zati Tamaina",
"Enter description": "Sartu deskribapena", "Enter description": "Sartu deskribapena",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Sartu Github Raw URLa", "Enter Github Raw URL": "Sartu Github Raw URLa",
"Enter Google PSE API Key": "Sartu Google PSE API Gakoa", "Enter Google PSE API Key": "Sartu Google PSE API Gakoa",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Ezagutza ongi ezabatu da.", "Knowledge deleted successfully.": "Ezagutza ongi ezabatu da.",
"Knowledge reset successfully.": "Ezagutza ongi berrezarri da.", "Knowledge reset successfully.": "Ezagutza ongi berrezarri da.",
"Knowledge updated successfully": "Ezagutza ongi eguneratu da.", "Knowledge updated successfully": "Ezagutza ongi eguneratu da.",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Etiketa", "Label": "Etiketa",
"Landing Page Mode": "Hasiera Orriaren Modua", "Landing Page Mode": "Hasiera Orriaren Modua",
"Language": "Hizkuntza", "Language": "Hizkuntza",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Utzi hutsik \"{{URL}}/models\" endpointuko eredu guztiak sartzeko", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Utzi hutsik \"{{URL}}/models\" endpointuko eredu guztiak sartzeko",
"Leave empty to include all models or select specific models": "Utzi hutsik eredu guztiak sartzeko edo hautatu eredu zehatzak", "Leave empty to include all models or select specific models": "Utzi hutsik eredu guztiak sartzeko edo hautatu eredu zehatzak",
"Leave empty to use the default prompt, or enter a custom prompt": "Utzi hutsik prompt lehenetsia erabiltzeko, edo sartu prompt pertsonalizatu bat", "Leave empty to use the default prompt, or enter a custom prompt": "Utzi hutsik prompt lehenetsia erabiltzeko, edo sartu prompt pertsonalizatu bat",
"Leave model field empty to use the default model.": "",
"Light": "Argia", "Light": "Argia",
"Listening...": "Entzuten...", "Listening...": "Entzuten...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Honek ezagutza-basea berrezarri eta fitxategi guztiak sinkronizatuko ditu. Jarraitu nahi duzu?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Honek ezagutza-basea berrezarri eta fitxategi guztiak sinkronizatuko ditu. Jarraitu nahi duzu?",
"Thorough explanation": "Azalpen sakona", "Thorough explanation": "Azalpen sakona",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika zerbitzariaren URLa beharrezkoa da.", "Tika Server URL required.": "Tika zerbitzariaren URLa beharrezkoa da.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "برای کمک اینجا را کلیک کنید.", "Click here to": "برای کمک اینجا را کلیک کنید.",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "برای انتخاب اینجا کلیک کنید", "Click here to select": "برای انتخاب اینجا کلیک کنید",
"Click here to select a csv file.": "برای انتخاب یک فایل csv اینجا را کلیک کنید.", "Click here to select a csv file.": "برای انتخاب یک فایل csv اینجا را کلیک کنید.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "اسناد", "Documents": "اسناد",
"does not make any external connections, and your data stays securely on your locally hosted server.": "هیچ اتصال خارجی ایجاد نمی کند و داده های شما به طور ایمن در سرور میزبان محلی شما باقی می ماند.", "does not make any external connections, and your data stays securely on your locally hosted server.": "هیچ اتصال خارجی ایجاد نمی کند و داده های شما به طور ایمن در سرور میزبان محلی شما باقی می ماند.",
"Domain Filter List": "",
"Don't have an account?": "حساب کاربری ندارید؟", "Don't have an account?": "حساب کاربری ندارید؟",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "مقدار Chunk Overlap را وارد کنید", "Enter Chunk Overlap": "مقدار Chunk Overlap را وارد کنید",
"Enter Chunk Size": "مقدار Chunk Size را وارد کنید", "Enter Chunk Size": "مقدار Chunk Size را وارد کنید",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "ادرس Github Raw را وارد کنید", "Enter Github Raw URL": "ادرس Github Raw را وارد کنید",
"Enter Google PSE API Key": "کلید API گوگل PSE را وارد کنید", "Enter Google PSE API Key": "کلید API گوگل PSE را وارد کنید",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "زبان", "Language": "زبان",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "روشن", "Light": "روشن",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klikkaa tästä", "Click here to": "Klikkaa tästä",
"Click here to download user import template file.": "Lataa käyttäjien tuontipohjatiedosto klikkaamalla tästä.", "Click here to download user import template file.": "Lataa käyttäjien tuontipohjatiedosto klikkaamalla tästä.",
"Click here to learn more about faster-whisper and see the available models.": "Klikkaa tästä oppiaksesi lisää faster-whisperista ja nähdäksesi saatavilla olevat mallit.", "Click here to learn more about faster-whisper and see the available models.": "Klikkaa tästä oppiaksesi lisää faster-whisperista ja nähdäksesi saatavilla olevat mallit.",
"Click here to see available models.": "",
"Click here to select": "Klikkaa tästä valitaksesi", "Click here to select": "Klikkaa tästä valitaksesi",
"Click here to select a csv file.": "Klikkaa tästä valitaksesi CSV-tiedosto.", "Click here to select a csv file.": "Klikkaa tästä valitaksesi CSV-tiedosto.",
"Click here to select a py file.": "Klikkaa tästä valitaksesi py-tiedosto.", "Click here to select a py file.": "Klikkaa tästä valitaksesi py-tiedosto.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentaatio", "Documentation": "Dokumentaatio",
"Documents": "Asiakirjat", "Documents": "Asiakirjat",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ei tee ulkoisia yhteyksiä, ja tietosi pysyvät turvallisesti paikallisesti isännöidyllä palvelimellasi.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ei tee ulkoisia yhteyksiä, ja tietosi pysyvät turvallisesti paikallisesti isännöidyllä palvelimellasi.",
"Domain Filter List": "",
"Don't have an account?": "Eikö sinulla ole tiliä?", "Don't have an account?": "Eikö sinulla ole tiliä?",
"don't install random functions from sources you don't trust.": "älä asenna satunnaisia toimintoja lähteistä, joihin et luota.", "don't install random functions from sources you don't trust.": "älä asenna satunnaisia toimintoja lähteistä, joihin et luota.",
"don't install random tools from sources you don't trust.": "älä asenna satunnaisia työkaluja lähteistä, joihin et luota.", "don't install random tools from sources you don't trust.": "älä asenna satunnaisia työkaluja lähteistä, joihin et luota.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Syötä osien päällekkäisyys", "Enter Chunk Overlap": "Syötä osien päällekkäisyys",
"Enter Chunk Size": "Syötä osien koko", "Enter Chunk Size": "Syötä osien koko",
"Enter description": "Kirjoita kuvaus", "Enter description": "Kirjoita kuvaus",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Kirjoita Github Raw -URL-osoite", "Enter Github Raw URL": "Kirjoita Github Raw -URL-osoite",
"Enter Google PSE API Key": "Kirjoita Google PSE API -avain", "Enter Google PSE API Key": "Kirjoita Google PSE API -avain",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Tietokanta poistettu onnistuneesti.", "Knowledge deleted successfully.": "Tietokanta poistettu onnistuneesti.",
"Knowledge reset successfully.": "Tietokanta nollattu onnistuneesti.", "Knowledge reset successfully.": "Tietokanta nollattu onnistuneesti.",
"Knowledge updated successfully": "Tietokanta päivitetty onnistuneesti", "Knowledge updated successfully": "Tietokanta päivitetty onnistuneesti",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Tunniste", "Label": "Tunniste",
"Landing Page Mode": "Etusivun tila", "Landing Page Mode": "Etusivun tila",
"Language": "Kieli", "Language": "Kieli",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit \"{{URL}}/models\" -päätepistestä", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit \"{{URL}}/models\" -päätepistestä",
"Leave empty to include all models or select specific models": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit tai valitse tietyt mallit", "Leave empty to include all models or select specific models": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit tai valitse tietyt mallit",
"Leave empty to use the default prompt, or enter a custom prompt": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote", "Leave empty to use the default prompt, or enter a custom prompt": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote",
"Leave model field empty to use the default model.": "",
"Light": "Vaalea", "Light": "Vaalea",
"Listening...": "Kuuntelee...", "Listening...": "Kuuntelee...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Tämä nollaa tietokannan ja synkronoi kaikki tiedostot. Haluatko jatkaa?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Tämä nollaa tietokannan ja synkronoi kaikki tiedostot. Haluatko jatkaa?",
"Thorough explanation": "Perusteellinen selitys", "Thorough explanation": "Perusteellinen selitys",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika Server URL vaaditaan.", "Tika Server URL required.": "Tika Server URL vaaditaan.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Cliquez ici pour", "Click here to": "Cliquez ici pour",
"Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation utilisateur.", "Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation utilisateur.",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Cliquez ici pour sélectionner", "Click here to select": "Cliquez ici pour sélectionner",
"Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier CSV.", "Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier CSV.",
"Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.", "Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.",
@ -290,6 +291,7 @@
"Documentation": "Documentation", "Documentation": "Documentation",
"Documents": "Documents", "Documents": "Documents",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ne fait aucune connexion externe et garde vos données en sécurité sur votre serveur local.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ne fait aucune connexion externe et garde vos données en sécurité sur votre serveur local.",
"Domain Filter List": "",
"Don't have an account?": "Vous n'avez pas de compte ?", "Don't have an account?": "Vous n'avez pas de compte ?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Entrez le chevauchement de chunk", "Enter Chunk Overlap": "Entrez le chevauchement de chunk",
"Enter Chunk Size": "Entrez la taille de bloc", "Enter Chunk Size": "Entrez la taille de bloc",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Entrez l'URL brute de GitHub", "Enter Github Raw URL": "Entrez l'URL brute de GitHub",
"Enter Google PSE API Key": "Entrez la clé API Google PSE", "Enter Google PSE API Key": "Entrez la clé API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Langue", "Language": "Langue",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Lumineux", "Light": "Lumineux",
"Listening...": "En train d'écouter...", "Listening...": "En train d'écouter...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Explication approfondie", "Thorough explanation": "Explication approfondie",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "URL du serveur Tika requise.", "Tika Server URL required.": "URL du serveur Tika requise.",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Cliquez ici pour", "Click here to": "Cliquez ici pour",
"Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation des utilisateurs.", "Click here to download user import template file.": "Cliquez ici pour télécharger le fichier modèle d'importation des utilisateurs.",
"Click here to learn more about faster-whisper and see the available models.": "Cliquez ici pour en savoir plus sur faster-whisper et voir les modèles disponibles.", "Click here to learn more about faster-whisper and see the available models.": "Cliquez ici pour en savoir plus sur faster-whisper et voir les modèles disponibles.",
"Click here to see available models.": "",
"Click here to select": "Cliquez ici pour sélectionner", "Click here to select": "Cliquez ici pour sélectionner",
"Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier .csv.", "Click here to select a csv file.": "Cliquez ici pour sélectionner un fichier .csv.",
"Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.", "Click here to select a py file.": "Cliquez ici pour sélectionner un fichier .py.",
@ -290,6 +291,7 @@
"Documentation": "Documentation", "Documentation": "Documentation",
"Documents": "Documents", "Documents": "Documents",
"does not make any external connections, and your data stays securely on your locally hosted server.": "n'établit aucune connexion externe et garde vos données en sécurité sur votre serveur local.", "does not make any external connections, and your data stays securely on your locally hosted server.": "n'établit aucune connexion externe et garde vos données en sécurité sur votre serveur local.",
"Domain Filter List": "",
"Don't have an account?": "Vous n'avez pas de compte ?", "Don't have an account?": "Vous n'avez pas de compte ?",
"don't install random functions from sources you don't trust.": "n'installez pas de fonctions aléatoires provenant de sources auxquelles vous ne faites pas confiance.", "don't install random functions from sources you don't trust.": "n'installez pas de fonctions aléatoires provenant de sources auxquelles vous ne faites pas confiance.",
"don't install random tools from sources you don't trust.": "n'installez pas d'outils aléatoires provenant de sources auxquelles vous ne faites pas confiance.", "don't install random tools from sources you don't trust.": "n'installez pas d'outils aléatoires provenant de sources auxquelles vous ne faites pas confiance.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Entrez le chevauchement des chunks", "Enter Chunk Overlap": "Entrez le chevauchement des chunks",
"Enter Chunk Size": "Entrez la taille des chunks", "Enter Chunk Size": "Entrez la taille des chunks",
"Enter description": "Entrez la description", "Enter description": "Entrez la description",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Entrez l'URL brute de GitHub", "Enter Github Raw URL": "Entrez l'URL brute de GitHub",
"Enter Google PSE API Key": "Entrez la clé API Google PSE", "Enter Google PSE API Key": "Entrez la clé API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Connaissance supprimée avec succès.", "Knowledge deleted successfully.": "Connaissance supprimée avec succès.",
"Knowledge reset successfully.": "Connaissance réinitialisée avec succès.", "Knowledge reset successfully.": "Connaissance réinitialisée avec succès.",
"Knowledge updated successfully": "Connaissance mise à jour avec succès", "Knowledge updated successfully": "Connaissance mise à jour avec succès",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Étiquette", "Label": "Étiquette",
"Landing Page Mode": "Mode de la page d'accueil", "Landing Page Mode": "Mode de la page d'accueil",
"Language": "Langue", "Language": "Langue",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laissez vide pour inclure tous les modèles depuis le point de terminaison \"{{URL}}/models\"", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laissez vide pour inclure tous les modèles depuis le point de terminaison \"{{URL}}/models\"",
"Leave empty to include all models or select specific models": "Laissez vide pour inclure tous les modèles ou sélectionnez des modèles spécifiques", "Leave empty to include all models or select specific models": "Laissez vide pour inclure tous les modèles ou sélectionnez des modèles spécifiques",
"Leave empty to use the default prompt, or enter a custom prompt": "Laissez vide pour utiliser le prompt par défaut, ou entrez un prompt personnalisé", "Leave empty to use the default prompt, or enter a custom prompt": "Laissez vide pour utiliser le prompt par défaut, ou entrez un prompt personnalisé",
"Leave model field empty to use the default model.": "",
"Light": "Clair", "Light": "Clair",
"Listening...": "Écoute en cours...", "Listening...": "Écoute en cours...",
"Llama.cpp": "Llama.cpp", "Llama.cpp": "Llama.cpp",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Cela réinitialisera la base de connaissances et synchronisera tous les fichiers. Souhaitez-vous continuer ?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Cela réinitialisera la base de connaissances et synchronisera tous les fichiers. Souhaitez-vous continuer ?",
"Thorough explanation": "Explication approfondie", "Thorough explanation": "Explication approfondie",
"Thought for {{DURATION}}": "Réflexion de {{DURATION}}", "Thought for {{DURATION}}": "Réflexion de {{DURATION}}",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "URL du serveur Tika requise.", "Tika Server URL required.": "URL du serveur Tika requise.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "לחץ כאן כדי", "Click here to": "לחץ כאן כדי",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "לחץ כאן לבחירה", "Click here to select": "לחץ כאן לבחירה",
"Click here to select a csv file.": "לחץ כאן לבחירת קובץ csv.", "Click here to select a csv file.": "לחץ כאן לבחירת קובץ csv.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "מסמכים", "Documents": "מסמכים",
"does not make any external connections, and your data stays securely on your locally hosted server.": "לא מבצע חיבורים חיצוניים, והנתונים שלך נשמרים באופן מאובטח בשרת המקומי שלך.", "does not make any external connections, and your data stays securely on your locally hosted server.": "לא מבצע חיבורים חיצוניים, והנתונים שלך נשמרים באופן מאובטח בשרת המקומי שלך.",
"Domain Filter List": "",
"Don't have an account?": "אין לך חשבון?", "Don't have an account?": "אין לך חשבון?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "הזן חפיפת נתונים", "Enter Chunk Overlap": "הזן חפיפת נתונים",
"Enter Chunk Size": "הזן גודל נתונים", "Enter Chunk Size": "הזן גודל נתונים",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "הזן כתובת URL של Github Raw", "Enter Github Raw URL": "הזן כתובת URL של Github Raw",
"Enter Google PSE API Key": "הזן מפתח API של Google PSE", "Enter Google PSE API Key": "הזן מפתח API של Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "שפה", "Language": "שפה",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "בהיר", "Light": "בהיר",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "यहां क्लिक करें", "Click here to": "यहां क्लिक करें",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "चयन करने के लिए यहां क्लिक करें।", "Click here to select": "चयन करने के लिए यहां क्लिक करें।",
"Click here to select a csv file.": "सीएसवी फ़ाइल का चयन करने के लिए यहां क्लिक करें।", "Click here to select a csv file.": "सीएसवी फ़ाइल का चयन करने के लिए यहां क्लिक करें।",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "दस्तावेज़", "Documents": "दस्तावेज़",
"does not make any external connections, and your data stays securely on your locally hosted server.": "कोई बाहरी कनेक्शन नहीं बनाता है, और आपका डेटा आपके स्थानीय रूप से होस्ट किए गए सर्वर पर सुरक्षित रूप से रहता है।", "does not make any external connections, and your data stays securely on your locally hosted server.": "कोई बाहरी कनेक्शन नहीं बनाता है, और आपका डेटा आपके स्थानीय रूप से होस्ट किए गए सर्वर पर सुरक्षित रूप से रहता है।",
"Domain Filter List": "",
"Don't have an account?": "कोई खाता नहीं है?", "Don't have an account?": "कोई खाता नहीं है?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "चंक ओवरलैप दर्ज करें", "Enter Chunk Overlap": "चंक ओवरलैप दर्ज करें",
"Enter Chunk Size": "खंड आकार दर्ज करें", "Enter Chunk Size": "खंड आकार दर्ज करें",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Github Raw URL दर्ज करें", "Enter Github Raw URL": "Github Raw URL दर्ज करें",
"Enter Google PSE API Key": "Google PSE API कुंजी दर्ज करें", "Enter Google PSE API Key": "Google PSE API कुंजी दर्ज करें",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "भाषा", "Language": "भाषा",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "सुन", "Light": "सुन",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Kliknite ovdje za", "Click here to": "Kliknite ovdje za",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Kliknite ovdje za odabir", "Click here to select": "Kliknite ovdje za odabir",
"Click here to select a csv file.": "Kliknite ovdje da odaberete csv datoteku.", "Click here to select a csv file.": "Kliknite ovdje da odaberete csv datoteku.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "Dokumentacija", "Documentation": "Dokumentacija",
"Documents": "Dokumenti", "Documents": "Dokumenti",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ne uspostavlja vanjske veze, a vaši podaci ostaju sigurno na vašem lokalno hostiranom poslužitelju.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ne uspostavlja vanjske veze, a vaši podaci ostaju sigurno na vašem lokalno hostiranom poslužitelju.",
"Domain Filter List": "",
"Don't have an account?": "Nemate račun?", "Don't have an account?": "Nemate račun?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Unesite preklapanje dijelova", "Enter Chunk Overlap": "Unesite preklapanje dijelova",
"Enter Chunk Size": "Unesite veličinu dijela", "Enter Chunk Size": "Unesite veličinu dijela",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Unesite Github sirovi URL", "Enter Github Raw URL": "Unesite Github sirovi URL",
"Enter Google PSE API Key": "Unesite Google PSE API ključ", "Enter Google PSE API Key": "Unesite Google PSE API ključ",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Jezik", "Language": "Jezik",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Svijetlo", "Light": "Svijetlo",
"Listening...": "Slušam...", "Listening...": "Slušam...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Detaljno objašnjenje", "Thorough explanation": "Detaljno objašnjenje",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Kattints ide", "Click here to": "Kattints ide",
"Click here to download user import template file.": "Kattints ide a felhasználó importálási sablon letöltéséhez.", "Click here to download user import template file.": "Kattints ide a felhasználó importálási sablon letöltéséhez.",
"Click here to learn more about faster-whisper and see the available models.": "Kattints ide, hogy többet tudj meg a faster-whisperről és lásd az elérhető modelleket.", "Click here to learn more about faster-whisper and see the available models.": "Kattints ide, hogy többet tudj meg a faster-whisperről és lásd az elérhető modelleket.",
"Click here to see available models.": "",
"Click here to select": "Kattints ide a kiválasztáshoz", "Click here to select": "Kattints ide a kiválasztáshoz",
"Click here to select a csv file.": "Kattints ide egy CSV fájl kiválasztásához.", "Click here to select a csv file.": "Kattints ide egy CSV fájl kiválasztásához.",
"Click here to select a py file.": "Kattints ide egy py fájl kiválasztásához.", "Click here to select a py file.": "Kattints ide egy py fájl kiválasztásához.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentáció", "Documentation": "Dokumentáció",
"Documents": "Dokumentumok", "Documents": "Dokumentumok",
"does not make any external connections, and your data stays securely on your locally hosted server.": "nem létesít külső kapcsolatokat, és az adataid biztonságban maradnak a helyileg hosztolt szervereden.", "does not make any external connections, and your data stays securely on your locally hosted server.": "nem létesít külső kapcsolatokat, és az adataid biztonságban maradnak a helyileg hosztolt szervereden.",
"Domain Filter List": "",
"Don't have an account?": "Nincs még fiókod?", "Don't have an account?": "Nincs még fiókod?",
"don't install random functions from sources you don't trust.": "ne telepíts véletlenszerű funkciókat olyan forrásokból, amelyekben nem bízol.", "don't install random functions from sources you don't trust.": "ne telepíts véletlenszerű funkciókat olyan forrásokból, amelyekben nem bízol.",
"don't install random tools from sources you don't trust.": "ne telepíts véletlenszerű eszközöket olyan forrásokból, amelyekben nem bízol.", "don't install random tools from sources you don't trust.": "ne telepíts véletlenszerű eszközöket olyan forrásokból, amelyekben nem bízol.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Add meg a darab átfedést", "Enter Chunk Overlap": "Add meg a darab átfedést",
"Enter Chunk Size": "Add meg a darab méretet", "Enter Chunk Size": "Add meg a darab méretet",
"Enter description": "Add meg a leírást", "Enter description": "Add meg a leírást",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Add meg a Github Raw URL-t", "Enter Github Raw URL": "Add meg a Github Raw URL-t",
"Enter Google PSE API Key": "Add meg a Google PSE API kulcsot", "Enter Google PSE API Key": "Add meg a Google PSE API kulcsot",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Tudásbázis sikeresen törölve.", "Knowledge deleted successfully.": "Tudásbázis sikeresen törölve.",
"Knowledge reset successfully.": "Tudásbázis sikeresen visszaállítva.", "Knowledge reset successfully.": "Tudásbázis sikeresen visszaállítva.",
"Knowledge updated successfully": "Tudásbázis sikeresen frissítve", "Knowledge updated successfully": "Tudásbázis sikeresen frissítve",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Kezdőlap mód", "Landing Page Mode": "Kezdőlap mód",
"Language": "Nyelv", "Language": "Nyelv",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"Leave empty to include all models or select specific models": "Hagyja üresen az összes modell használatához, vagy válasszon ki konkrét modelleket", "Leave empty to include all models or select specific models": "Hagyja üresen az összes modell használatához, vagy válasszon ki konkrét modelleket",
"Leave empty to use the default prompt, or enter a custom prompt": "Hagyja üresen az alapértelmezett prompt használatához, vagy adjon meg egyéni promptot", "Leave empty to use the default prompt, or enter a custom prompt": "Hagyja üresen az alapértelmezett prompt használatához, vagy adjon meg egyéni promptot",
"Leave model field empty to use the default model.": "",
"Light": "Világos", "Light": "Világos",
"Listening...": "Hallgatás...", "Listening...": "Hallgatás...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Ez visszaállítja a tudásbázist és szinkronizálja az összes fájlt. Szeretné folytatni?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Ez visszaállítja a tudásbázist és szinkronizálja az összes fájlt. Szeretné folytatni?",
"Thorough explanation": "Alapos magyarázat", "Thorough explanation": "Alapos magyarázat",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika szerver URL szükséges.", "Tika Server URL required.": "Tika szerver URL szükséges.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Klik di sini untuk", "Click here to": "Klik di sini untuk",
"Click here to download user import template file.": "Klik di sini untuk mengunduh file templat impor pengguna.", "Click here to download user import template file.": "Klik di sini untuk mengunduh file templat impor pengguna.",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Klik di sini untuk memilih", "Click here to select": "Klik di sini untuk memilih",
"Click here to select a csv file.": "Klik di sini untuk memilih file csv.", "Click here to select a csv file.": "Klik di sini untuk memilih file csv.",
"Click here to select a py file.": "Klik di sini untuk memilih file py.", "Click here to select a py file.": "Klik di sini untuk memilih file py.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentasi", "Documentation": "Dokumentasi",
"Documents": "Dokumen", "Documents": "Dokumen",
"does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat koneksi eksternal apa pun, dan data Anda tetap aman di server yang dihosting secara lokal.", "does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat koneksi eksternal apa pun, dan data Anda tetap aman di server yang dihosting secara lokal.",
"Domain Filter List": "",
"Don't have an account?": "Tidak memiliki akun?", "Don't have an account?": "Tidak memiliki akun?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Masukkan Tumpang Tindih Chunk", "Enter Chunk Overlap": "Masukkan Tumpang Tindih Chunk",
"Enter Chunk Size": "Masukkan Ukuran Potongan", "Enter Chunk Size": "Masukkan Ukuran Potongan",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Masukkan URL Mentah Github", "Enter Github Raw URL": "Masukkan URL Mentah Github",
"Enter Google PSE API Key": "Masukkan Kunci API Google PSE", "Enter Google PSE API Key": "Masukkan Kunci API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Bahasa", "Language": "Bahasa",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Cahaya", "Light": "Cahaya",
"Listening...": "Mendengarkan", "Listening...": "Mendengarkan",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Penjelasan menyeluruh", "Thorough explanation": "Penjelasan menyeluruh",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Cliceáil anseo chun", "Click here to": "Cliceáil anseo chun",
"Click here to download user import template file.": "Cliceáil anseo chun an comhad iompórtála úsáideora a íoslódáil.", "Click here to download user import template file.": "Cliceáil anseo chun an comhad iompórtála úsáideora a íoslódáil.",
"Click here to learn more about faster-whisper and see the available models.": "Cliceáil anseo chun níos mó a fhoghlaim faoi cogar níos tapúla agus na múnlaí atá ar fáil a fheiceáil.", "Click here to learn more about faster-whisper and see the available models.": "Cliceáil anseo chun níos mó a fhoghlaim faoi cogar níos tapúla agus na múnlaí atá ar fáil a fheiceáil.",
"Click here to see available models.": "",
"Click here to select": "Cliceáil anseo chun roghnú", "Click here to select": "Cliceáil anseo chun roghnú",
"Click here to select a csv file.": "Cliceáil anseo chun comhad csv a roghnú.", "Click here to select a csv file.": "Cliceáil anseo chun comhad csv a roghnú.",
"Click here to select a py file.": "Cliceáil anseo chun comhad py a roghnú.", "Click here to select a py file.": "Cliceáil anseo chun comhad py a roghnú.",
@ -290,6 +291,7 @@
"Documentation": "Doiciméadú", "Documentation": "Doiciméadú",
"Documents": "Doiciméid", "Documents": "Doiciméid",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ní dhéanann sé aon naisc sheachtracha, agus fanann do chuid sonraí go slán ar do fhreastalaí a óstáiltear go háitiúil.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ní dhéanann sé aon naisc sheachtracha, agus fanann do chuid sonraí go slán ar do fhreastalaí a óstáiltear go háitiúil.",
"Domain Filter List": "",
"Don't have an account?": "Níl cuntas agat?", "Don't have an account?": "Níl cuntas agat?",
"don't install random functions from sources you don't trust.": "ná suiteáil feidhmeanna randamacha ó fhoinsí nach bhfuil muinín agat.", "don't install random functions from sources you don't trust.": "ná suiteáil feidhmeanna randamacha ó fhoinsí nach bhfuil muinín agat.",
"don't install random tools from sources you don't trust.": "ná suiteáil uirlisí randamacha ó fhoinsí nach bhfuil muinín agat.", "don't install random tools from sources you don't trust.": "ná suiteáil uirlisí randamacha ó fhoinsí nach bhfuil muinín agat.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Cuir isteach Chunk Forluí", "Enter Chunk Overlap": "Cuir isteach Chunk Forluí",
"Enter Chunk Size": "Cuir isteach Méid an Chunc", "Enter Chunk Size": "Cuir isteach Méid an Chunc",
"Enter description": "Iontráil cur síos", "Enter description": "Iontráil cur síos",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "Cuir isteach Eochair Exa API", "Enter Exa API Key": "Cuir isteach Eochair Exa API",
"Enter Github Raw URL": "Cuir isteach URL Github Raw", "Enter Github Raw URL": "Cuir isteach URL Github Raw",
"Enter Google PSE API Key": "Cuir isteach Eochair API Google PSE", "Enter Google PSE API Key": "Cuir isteach Eochair API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "D'éirigh leis an eolas a scriosadh.", "Knowledge deleted successfully.": "D'éirigh leis an eolas a scriosadh.",
"Knowledge reset successfully.": "D'éirigh le hathshocrú eolais.", "Knowledge reset successfully.": "D'éirigh le hathshocrú eolais.",
"Knowledge updated successfully": "D'éirigh leis an eolas a nuashonrú", "Knowledge updated successfully": "D'éirigh leis an eolas a nuashonrú",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Lipéad", "Label": "Lipéad",
"Landing Page Mode": "Mód Leathanach Tuirlingthe", "Landing Page Mode": "Mód Leathanach Tuirlingthe",
"Language": "Teanga", "Language": "Teanga",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Fág folamh chun gach múnla ón gcríochphointe \"{{URL}}/models\" a chur san áireamh", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Fág folamh chun gach múnla ón gcríochphointe \"{{URL}}/models\" a chur san áireamh",
"Leave empty to include all models or select specific models": "Fág folamh chun gach múnla a chur san áireamh nó roghnaigh múnlaí sonracha", "Leave empty to include all models or select specific models": "Fág folamh chun gach múnla a chur san áireamh nó roghnaigh múnlaí sonracha",
"Leave empty to use the default prompt, or enter a custom prompt": "Fág folamh chun an leid réamhshocraithe a úsáid, nó cuir isteach leid saincheaptha", "Leave empty to use the default prompt, or enter a custom prompt": "Fág folamh chun an leid réamhshocraithe a úsáid, nó cuir isteach leid saincheaptha",
"Leave model field empty to use the default model.": "",
"Light": "Solas", "Light": "Solas",
"Listening...": "Éisteacht...", "Listening...": "Éisteacht...",
"Llama.cpp": "Llama.cpp", "Llama.cpp": "Llama.cpp",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Déanfaidh sé seo an bonn eolais a athshocrú agus gach comhad a shioncronú. Ar mhaith leat leanúint ar aghaidh?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Déanfaidh sé seo an bonn eolais a athshocrú agus gach comhad a shioncronú. Ar mhaith leat leanúint ar aghaidh?",
"Thorough explanation": "Míniú críochnúil", "Thorough explanation": "Míniú críochnúil",
"Thought for {{DURATION}}": "Smaoineamh ar {{DURATION}}", "Thought for {{DURATION}}": "Smaoineamh ar {{DURATION}}",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Teastaíonn URL Freastalaí Tika.", "Tika Server URL required.": "Teastaíonn URL Freastalaí Tika.",
"Tiktoken": "Tictoken", "Tiktoken": "Tictoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Clicca qui per", "Click here to": "Clicca qui per",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Clicca qui per selezionare", "Click here to select": "Clicca qui per selezionare",
"Click here to select a csv file.": "Clicca qui per selezionare un file csv.", "Click here to select a csv file.": "Clicca qui per selezionare un file csv.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "Documenti", "Documents": "Documenti",
"does not make any external connections, and your data stays securely on your locally hosted server.": "non effettua connessioni esterne e i tuoi dati rimangono al sicuro sul tuo server ospitato localmente.", "does not make any external connections, and your data stays securely on your locally hosted server.": "non effettua connessioni esterne e i tuoi dati rimangono al sicuro sul tuo server ospitato localmente.",
"Domain Filter List": "",
"Don't have an account?": "Non hai un account?", "Don't have an account?": "Non hai un account?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Inserisci la sovrapposizione chunk", "Enter Chunk Overlap": "Inserisci la sovrapposizione chunk",
"Enter Chunk Size": "Inserisci la dimensione chunk", "Enter Chunk Size": "Inserisci la dimensione chunk",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Immettere l'URL grezzo di Github", "Enter Github Raw URL": "Immettere l'URL grezzo di Github",
"Enter Google PSE API Key": "Inserisci la chiave API PSE di Google", "Enter Google PSE API Key": "Inserisci la chiave API PSE di Google",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Lingua", "Language": "Lingua",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Chiaro", "Light": "Chiaro",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Spiegazione dettagliata", "Thorough explanation": "Spiegazione dettagliata",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "ここをクリックして", "Click here to": "ここをクリックして",
"Click here to download user import template file.": "ユーザーテンプレートをインポートするにはここをクリックしてください。", "Click here to download user import template file.": "ユーザーテンプレートをインポートするにはここをクリックしてください。",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "選択するにはここをクリックしてください", "Click here to select": "選択するにはここをクリックしてください",
"Click here to select a csv file.": "CSVファイルを選択するにはここをクリックしてください。", "Click here to select a csv file.": "CSVファイルを選択するにはここをクリックしてください。",
"Click here to select a py file.": "Pythonスクリプトファイルを選択するにはここをクリックしてください。", "Click here to select a py file.": "Pythonスクリプトファイルを選択するにはここをクリックしてください。",
@ -290,6 +291,7 @@
"Documentation": "ドキュメント", "Documentation": "ドキュメント",
"Documents": "ドキュメント", "Documents": "ドキュメント",
"does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。", "does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。",
"Domain Filter List": "",
"Don't have an account?": "アカウントをお持ちではありませんか?", "Don't have an account?": "アカウントをお持ちではありませんか?",
"don't install random functions from sources you don't trust.": "信頼出来ないソースからランダムFunctionをインストールしないでください。", "don't install random functions from sources you don't trust.": "信頼出来ないソースからランダムFunctionをインストールしないでください。",
"don't install random tools from sources you don't trust.": "信頼出来ないソースからランダムツールをインストールしないでください。", "don't install random tools from sources you don't trust.": "信頼出来ないソースからランダムツールをインストールしないでください。",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "チャンクオーバーラップを入力してください", "Enter Chunk Overlap": "チャンクオーバーラップを入力してください",
"Enter Chunk Size": "チャンクサイズを入力してください", "Enter Chunk Size": "チャンクサイズを入力してください",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Github Raw URLを入力", "Enter Github Raw URL": "Github Raw URLを入力",
"Enter Google PSE API Key": "Google PSE APIキーの入力", "Enter Google PSE API Key": "Google PSE APIキーの入力",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "ナレッジベースの削除に成功しました", "Knowledge deleted successfully.": "ナレッジベースの削除に成功しました",
"Knowledge reset successfully.": "ナレッジベースのリセットに成功しました", "Knowledge reset successfully.": "ナレッジベースのリセットに成功しました",
"Knowledge updated successfully": "ナレッジベースのアップデートに成功しました", "Knowledge updated successfully": "ナレッジベースのアップデートに成功しました",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "ランディングページモード", "Landing Page Mode": "ランディングページモード",
"Language": "言語", "Language": "言語",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "ライト", "Light": "ライト",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "დააკლიკე აქ", "Click here to": "დააკლიკე აქ",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "ასარჩევად, დააკლიკე აქ", "Click here to select": "ასარჩევად, დააკლიკე აქ",
"Click here to select a csv file.": "ასარჩევად, დააკლიკე აქ", "Click here to select a csv file.": "ასარჩევად, დააკლიკე აქ",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "დოკუმენტები", "Documents": "დოკუმენტები",
"does not make any external connections, and your data stays securely on your locally hosted server.": "არ ამყარებს გარე კავშირებს და თქვენი მონაცემები უსაფრთხოდ რჩება თქვენს ადგილობრივ სერვერზე.", "does not make any external connections, and your data stays securely on your locally hosted server.": "არ ამყარებს გარე კავშირებს და თქვენი მონაცემები უსაფრთხოდ რჩება თქვენს ადგილობრივ სერვერზე.",
"Domain Filter List": "",
"Don't have an account?": "არ გაქვს ანგარიში?", "Don't have an account?": "არ გაქვს ანგარიში?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "შეიყვანეთ ნაწილის გადახურვა", "Enter Chunk Overlap": "შეიყვანეთ ნაწილის გადახურვა",
"Enter Chunk Size": "შეიყვანე ბლოკის ზომა", "Enter Chunk Size": "შეიყვანე ბლოკის ზომა",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "შეიყვანეთ Github Raw URL", "Enter Github Raw URL": "შეიყვანეთ Github Raw URL",
"Enter Google PSE API Key": "შეიყვანეთ Google PSE API გასაღები", "Enter Google PSE API Key": "შეიყვანეთ Google PSE API გასაღები",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "ენა", "Language": "ენა",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "მსუბუქი", "Light": "მსუბუქი",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "여기를 클릭하면", "Click here to": "여기를 클릭하면",
"Click here to download user import template file.": "사용자 삽입 템플렛 파일을 다운받으려면 여기를 클릭하세요", "Click here to download user import template file.": "사용자 삽입 템플렛 파일을 다운받으려면 여기를 클릭하세요",
"Click here to learn more about faster-whisper and see the available models.": "빠른 속삭임에 대해 배우거나 가능한 모델을 보려면 여기를 클릭하세요", "Click here to learn more about faster-whisper and see the available models.": "빠른 속삭임에 대해 배우거나 가능한 모델을 보려면 여기를 클릭하세요",
"Click here to see available models.": "",
"Click here to select": "선택하려면 여기를 클릭하세요.", "Click here to select": "선택하려면 여기를 클릭하세요.",
"Click here to select a csv file.": "csv 파일을 선택하려면 여기를 클릭하세요.", "Click here to select a csv file.": "csv 파일을 선택하려면 여기를 클릭하세요.",
"Click here to select a py file.": "py 파일을 선택하려면 여기를 클릭하세요.", "Click here to select a py file.": "py 파일을 선택하려면 여기를 클릭하세요.",
@ -290,6 +291,7 @@
"Documentation": "문서 조사", "Documentation": "문서 조사",
"Documents": "문서", "Documents": "문서",
"does not make any external connections, and your data stays securely on your locally hosted server.": "외부와 어떠한 연결도 하지 않으며, 데이터는 로컬에서 호스팅되는 서버에 안전하게 유지됩니다.", "does not make any external connections, and your data stays securely on your locally hosted server.": "외부와 어떠한 연결도 하지 않으며, 데이터는 로컬에서 호스팅되는 서버에 안전하게 유지됩니다.",
"Domain Filter List": "",
"Don't have an account?": "계정이 없으신가요?", "Don't have an account?": "계정이 없으신가요?",
"don't install random functions from sources you don't trust.": "불분명한 출처를 가진 임의의 함수를 설치하지마세요", "don't install random functions from sources you don't trust.": "불분명한 출처를 가진 임의의 함수를 설치하지마세요",
"don't install random tools from sources you don't trust.": "불분명한 출처를 가진 임의의 도구를 설치하지마세요", "don't install random tools from sources you don't trust.": "불분명한 출처를 가진 임의의 도구를 설치하지마세요",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "청크 오버랩 입력", "Enter Chunk Overlap": "청크 오버랩 입력",
"Enter Chunk Size": "청크 크기 입력", "Enter Chunk Size": "청크 크기 입력",
"Enter description": "설명 입력", "Enter description": "설명 입력",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Github Raw URL 입력", "Enter Github Raw URL": "Github Raw URL 입력",
"Enter Google PSE API Key": "Google PSE API 키 입력", "Enter Google PSE API Key": "Google PSE API 키 입력",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "성공적으로 지식 기반이 삭제되었습니다", "Knowledge deleted successfully.": "성공적으로 지식 기반이 삭제되었습니다",
"Knowledge reset successfully.": "성공적으로 지식 기반이 초기화되었습니다", "Knowledge reset successfully.": "성공적으로 지식 기반이 초기화되었습니다",
"Knowledge updated successfully": "성공적으로 지식 기반이 업데이트되었습니다", "Knowledge updated successfully": "성공적으로 지식 기반이 업데이트되었습니다",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "랜딩페이지 모드", "Landing Page Mode": "랜딩페이지 모드",
"Language": "언어", "Language": "언어",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "라이트", "Light": "라이트",
"Listening...": "듣는 중...", "Listening...": "듣는 중...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "",
"Tika": "티카(Tika)", "Tika": "티카(Tika)",
"Tika Server URL required.": "티카 서버 URL이 필요합니다", "Tika Server URL required.": "티카 서버 URL이 필요합니다",
"Tiktoken": "틱토큰 (Tiktoken)", "Tiktoken": "틱토큰 (Tiktoken)",

View file

@ -163,6 +163,7 @@
"Click here to": "Paspauskite čia, kad:", "Click here to": "Paspauskite čia, kad:",
"Click here to download user import template file.": "Pasauskite čia norėdami sukurti naudotojo įkėlimo šablono rinkmeną", "Click here to download user import template file.": "Pasauskite čia norėdami sukurti naudotojo įkėlimo šablono rinkmeną",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Spauskite čia norėdami pasirinkti", "Click here to select": "Spauskite čia norėdami pasirinkti",
"Click here to select a csv file.": "Spauskite čia tam, kad pasirinkti csv failą", "Click here to select a csv file.": "Spauskite čia tam, kad pasirinkti csv failą",
"Click here to select a py file.": "Spauskite čia norėdami pasirinkti py failą", "Click here to select a py file.": "Spauskite čia norėdami pasirinkti py failą",
@ -290,6 +291,7 @@
"Documentation": "Dokumentacija", "Documentation": "Dokumentacija",
"Documents": "Dokumentai", "Documents": "Dokumentai",
"does not make any external connections, and your data stays securely on your locally hosted server.": "neturi jokių išorinių ryšių ir duomenys lieka serveryje.", "does not make any external connections, and your data stays securely on your locally hosted server.": "neturi jokių išorinių ryšių ir duomenys lieka serveryje.",
"Domain Filter List": "",
"Don't have an account?": "Neturite paskyros?", "Don't have an account?": "Neturite paskyros?",
"don't install random functions from sources you don't trust.": "neinstaliuokite funkcijų iš nepatikimų šaltinių", "don't install random functions from sources you don't trust.": "neinstaliuokite funkcijų iš nepatikimų šaltinių",
"don't install random tools from sources you don't trust.": "neinstaliuokite įrankių iš nepatikimų šaltinių", "don't install random tools from sources you don't trust.": "neinstaliuokite įrankių iš nepatikimų šaltinių",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Įveskite blokų persidengimą", "Enter Chunk Overlap": "Įveskite blokų persidengimą",
"Enter Chunk Size": "Įveskite blokų dydį", "Enter Chunk Size": "Įveskite blokų dydį",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Įveskite GitHub Raw nuorodą", "Enter Github Raw URL": "Įveskite GitHub Raw nuorodą",
"Enter Google PSE API Key": "Įveskite Google PSE API raktą", "Enter Google PSE API Key": "Įveskite Google PSE API raktą",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Kalba", "Language": "Kalba",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Šviesus", "Light": "Šviesus",
"Listening...": "Klausoma...", "Listening...": "Klausoma...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Platus paaiškinimas", "Thorough explanation": "Platus paaiškinimas",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Reiklainga Tika serverio nuorodą", "Tika Server URL required.": "Reiklainga Tika serverio nuorodą",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klik disini untuk", "Click here to": "Klik disini untuk",
"Click here to download user import template file.": "Klik disini untuk memuat turun fail templat import pengguna", "Click here to download user import template file.": "Klik disini untuk memuat turun fail templat import pengguna",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Klik disini untuk memilih", "Click here to select": "Klik disini untuk memilih",
"Click here to select a csv file.": "Klik disini untuk memilih fail csv", "Click here to select a csv file.": "Klik disini untuk memilih fail csv",
"Click here to select a py file.": "Klik disini untuk memilih fail py", "Click here to select a py file.": "Klik disini untuk memilih fail py",
@ -290,6 +291,7 @@
"Documentation": "Dokumentasi", "Documentation": "Dokumentasi",
"Documents": "Dokumen", "Documents": "Dokumen",
"does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat sebarang sambungan luaran, dan data anda kekal selamat pada pelayan yang dihoskan ditempat anda", "does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat sebarang sambungan luaran, dan data anda kekal selamat pada pelayan yang dihoskan ditempat anda",
"Domain Filter List": "",
"Don't have an account?": "Anda tidak mempunyai akaun?", "Don't have an account?": "Anda tidak mempunyai akaun?",
"don't install random functions from sources you don't trust.": "jangan pasang mana-mana fungsi daripada sumber yang anda tidak percayai.", "don't install random functions from sources you don't trust.": "jangan pasang mana-mana fungsi daripada sumber yang anda tidak percayai.",
"don't install random tools from sources you don't trust.": "jangan pasang mana-mana alat daripada sumber yang anda tidak percayai.", "don't install random tools from sources you don't trust.": "jangan pasang mana-mana alat daripada sumber yang anda tidak percayai.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Masukkan Tindihan 'Chunk'", "Enter Chunk Overlap": "Masukkan Tindihan 'Chunk'",
"Enter Chunk Size": "Masukkan Saiz 'Chunk'", "Enter Chunk Size": "Masukkan Saiz 'Chunk'",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Masukkan URL 'Github Raw'", "Enter Github Raw URL": "Masukkan URL 'Github Raw'",
"Enter Google PSE API Key": "Masukkan kunci API Google PSE", "Enter Google PSE API Key": "Masukkan kunci API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Bahasa", "Language": "Bahasa",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Cerah", "Light": "Cerah",
"Listening...": "Mendengar...", "Listening...": "Mendengar...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Penjelasan menyeluruh", "Thorough explanation": "Penjelasan menyeluruh",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "URL Pelayan Tika diperlukan.", "Tika Server URL required.": "URL Pelayan Tika diperlukan.",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klikk her for å", "Click here to": "Klikk her for å",
"Click here to download user import template file.": "Klikk her for å hente ned malfilen for import av brukere.", "Click here to download user import template file.": "Klikk her for å hente ned malfilen for import av brukere.",
"Click here to learn more about faster-whisper and see the available models.": "Klikk her for å lære mer om faster-whisper, og se de tilgjengelige modellene.", "Click here to learn more about faster-whisper and see the available models.": "Klikk her for å lære mer om faster-whisper, og se de tilgjengelige modellene.",
"Click here to see available models.": "",
"Click here to select": "Klikk her for å velge", "Click here to select": "Klikk her for å velge",
"Click here to select a csv file.": "Klikk her for å velge en CSV-fil.", "Click here to select a csv file.": "Klikk her for å velge en CSV-fil.",
"Click here to select a py file.": "Klikk her for å velge en PY-fil.", "Click here to select a py file.": "Klikk her for å velge en PY-fil.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentasjon", "Documentation": "Dokumentasjon",
"Documents": "Dokumenter", "Documents": "Dokumenter",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ikke ingen tilkobling til eksterne tjenester. Dataene dine forblir sikkert på den lokale serveren.", "does not make any external connections, and your data stays securely on your locally hosted server.": "ikke ingen tilkobling til eksterne tjenester. Dataene dine forblir sikkert på den lokale serveren.",
"Domain Filter List": "",
"Don't have an account?": "Har du ingen konto?", "Don't have an account?": "Har du ingen konto?",
"don't install random functions from sources you don't trust.": "ikke installer tilfeldige funksjoner fra kilder du ikke stoler på.", "don't install random functions from sources you don't trust.": "ikke installer tilfeldige funksjoner fra kilder du ikke stoler på.",
"don't install random tools from sources you don't trust.": "ikke installer tilfeldige verktøy fra kilder du ikke stoler på.", "don't install random tools from sources you don't trust.": "ikke installer tilfeldige verktøy fra kilder du ikke stoler på.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Angi Chunk-overlapp", "Enter Chunk Overlap": "Angi Chunk-overlapp",
"Enter Chunk Size": "Angi Chunk-størrelse", "Enter Chunk Size": "Angi Chunk-størrelse",
"Enter description": "Angi beskrivelse", "Enter description": "Angi beskrivelse",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Angi Github Raw-URL", "Enter Github Raw URL": "Angi Github Raw-URL",
"Enter Google PSE API Key": "Angi API-nøkkel for Google PSE", "Enter Google PSE API Key": "Angi API-nøkkel for Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Kunnskap slettet.", "Knowledge deleted successfully.": "Kunnskap slettet.",
"Knowledge reset successfully.": "Tilbakestilling av kunnskap vellykket.", "Knowledge reset successfully.": "Tilbakestilling av kunnskap vellykket.",
"Knowledge updated successfully": "Kunnskap oppdatert", "Knowledge updated successfully": "Kunnskap oppdatert",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Etikett", "Label": "Etikett",
"Landing Page Mode": "Modus for startside", "Landing Page Mode": "Modus for startside",
"Language": "Språk", "Language": "Språk",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "La stå tomt for å inkludere alle modeller fra endepunktet \"{{URL}}/api/models\"", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "La stå tomt for å inkludere alle modeller fra endepunktet \"{{URL}}/api/models\"",
"Leave empty to include all models or select specific models": "La stå tomt for å inkludere alle modeller", "Leave empty to include all models or select specific models": "La stå tomt for å inkludere alle modeller",
"Leave empty to use the default prompt, or enter a custom prompt": "La stå tomt for å bruke standard ledetekst, eller angi en tilpasset ledetekst", "Leave empty to use the default prompt, or enter a custom prompt": "La stå tomt for å bruke standard ledetekst, eller angi en tilpasset ledetekst",
"Leave model field empty to use the default model.": "",
"Light": "Lys", "Light": "Lys",
"Listening...": "Lytter ...", "Listening...": "Lytter ...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette tilbakestiller kunnskapsbasen og synkroniserer alle filer. Vil du fortsette?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Dette tilbakestiller kunnskapsbasen og synkroniserer alle filer. Vil du fortsette?",
"Thorough explanation": "Grundig forklaring", "Thorough explanation": "Grundig forklaring",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Server-URL for Tika kreves.", "Tika Server URL required.": "Server-URL for Tika kreves.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Klik hier om", "Click here to": "Klik hier om",
"Click here to download user import template file.": "Klik hier om het sjabloonbestand voor gebruikersimport te downloaden.", "Click here to download user import template file.": "Klik hier om het sjabloonbestand voor gebruikersimport te downloaden.",
"Click here to learn more about faster-whisper and see the available models.": "Klik hier om meer te leren over faster-whisper en de beschikbare modellen te bekijken.", "Click here to learn more about faster-whisper and see the available models.": "Klik hier om meer te leren over faster-whisper en de beschikbare modellen te bekijken.",
"Click here to see available models.": "",
"Click here to select": "Klik hier om te selecteren", "Click here to select": "Klik hier om te selecteren",
"Click here to select a csv file.": "Klik hier om een csv file te selecteren.", "Click here to select a csv file.": "Klik hier om een csv file te selecteren.",
"Click here to select a py file.": "Klik hier om een py-bestand te selecteren.", "Click here to select a py file.": "Klik hier om een py-bestand te selecteren.",
@ -290,6 +291,7 @@
"Documentation": "Documentatie", "Documentation": "Documentatie",
"Documents": "Documenten", "Documents": "Documenten",
"does not make any external connections, and your data stays securely on your locally hosted server.": "maakt geen externe verbindingen, en je gegevens blijven veilig op je lokaal gehoste server.", "does not make any external connections, and your data stays securely on your locally hosted server.": "maakt geen externe verbindingen, en je gegevens blijven veilig op je lokaal gehoste server.",
"Domain Filter List": "",
"Don't have an account?": "Heb je geen account?", "Don't have an account?": "Heb je geen account?",
"don't install random functions from sources you don't trust.": "installeer geen willekeurige functies van bronnen die je niet vertrouwd", "don't install random functions from sources you don't trust.": "installeer geen willekeurige functies van bronnen die je niet vertrouwd",
"don't install random tools from sources you don't trust.": "installeer geen willekeurige gereedschappen van bronnen die je niet vertrouwd", "don't install random tools from sources you don't trust.": "installeer geen willekeurige gereedschappen van bronnen die je niet vertrouwd",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Voeg Chunk Overlap toe", "Enter Chunk Overlap": "Voeg Chunk Overlap toe",
"Enter Chunk Size": "Voeg Chunk Size toe", "Enter Chunk Size": "Voeg Chunk Size toe",
"Enter description": "Voer beschrijving in", "Enter description": "Voer beschrijving in",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Voer de Github Raw-URL in", "Enter Github Raw URL": "Voer de Github Raw-URL in",
"Enter Google PSE API Key": "Voer de Google PSE API-sleutel in", "Enter Google PSE API Key": "Voer de Google PSE API-sleutel in",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Kennis succesvol verwijderd", "Knowledge deleted successfully.": "Kennis succesvol verwijderd",
"Knowledge reset successfully.": "Kennis succesvol gereset", "Knowledge reset successfully.": "Kennis succesvol gereset",
"Knowledge updated successfully": "Kennis succesvol bijgewerkt", "Knowledge updated successfully": "Kennis succesvol bijgewerkt",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Label", "Label": "Label",
"Landing Page Mode": "Landingspaginamodus", "Landing Page Mode": "Landingspaginamodus",
"Language": "Taal", "Language": "Taal",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laat leeg om alle modellen van het \"{{URL}}/models\" endpoint toe te voegen", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Laat leeg om alle modellen van het \"{{URL}}/models\" endpoint toe te voegen",
"Leave empty to include all models or select specific models": "Laat leeg om alle modellen mee te nemen, of selecteer specifieke modellen", "Leave empty to include all models or select specific models": "Laat leeg om alle modellen mee te nemen, of selecteer specifieke modellen",
"Leave empty to use the default prompt, or enter a custom prompt": "Laat leeg om de standaard prompt te gebruiken, of selecteer een aangepaste prompt", "Leave empty to use the default prompt, or enter a custom prompt": "Laat leeg om de standaard prompt te gebruiken, of selecteer een aangepaste prompt",
"Leave model field empty to use the default model.": "",
"Light": "Licht", "Light": "Licht",
"Listening...": "Aan het luisteren...", "Listening...": "Aan het luisteren...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dit zal de kennisdatabase resetten en alle bestanden synchroniseren. Wilt u doorgaan?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Dit zal de kennisdatabase resetten en alle bestanden synchroniseren. Wilt u doorgaan?",
"Thorough explanation": "Gevorderde uitleg", "Thorough explanation": "Gevorderde uitleg",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Tika Server-URL vereist", "Tika Server URL required.": "Tika Server-URL vereist",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ", "Click here to": "ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ", "Click here to select": "ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ",
"Click here to select a csv file.": "CSV ਫਾਈਲ ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।", "Click here to select a csv file.": "CSV ਫਾਈਲ ਚੁਣਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ।",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "ਡਾਕੂਮੈਂਟ", "Documents": "ਡਾਕੂਮੈਂਟ",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ਕੋਈ ਬਾਹਰੀ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਬਣਾਉਂਦਾ, ਅਤੇ ਤੁਹਾਡਾ ਡਾਟਾ ਤੁਹਾਡੇ ਸਥਾਨਕ ਸਰਵਰ 'ਤੇ ਸੁਰੱਖਿਅਤ ਰਹਿੰਦਾ ਹੈ।", "does not make any external connections, and your data stays securely on your locally hosted server.": "ਕੋਈ ਬਾਹਰੀ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਬਣਾਉਂਦਾ, ਅਤੇ ਤੁਹਾਡਾ ਡਾਟਾ ਤੁਹਾਡੇ ਸਥਾਨਕ ਸਰਵਰ 'ਤੇ ਸੁਰੱਖਿਅਤ ਰਹਿੰਦਾ ਹੈ।",
"Domain Filter List": "",
"Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?", "Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "ਚੰਕ ਓਵਰਲੈਪ ਦਰਜ ਕਰੋ", "Enter Chunk Overlap": "ਚੰਕ ਓਵਰਲੈਪ ਦਰਜ ਕਰੋ",
"Enter Chunk Size": "ਚੰਕ ਆਕਾਰ ਦਰਜ ਕਰੋ", "Enter Chunk Size": "ਚੰਕ ਆਕਾਰ ਦਰਜ ਕਰੋ",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Github ਕੱਚਾ URL ਦਾਖਲ ਕਰੋ", "Enter Github Raw URL": "Github ਕੱਚਾ URL ਦਾਖਲ ਕਰੋ",
"Enter Google PSE API Key": "Google PSE API ਕੁੰਜੀ ਦਾਖਲ ਕਰੋ", "Enter Google PSE API Key": "Google PSE API ਕੁੰਜੀ ਦਾਖਲ ਕਰੋ",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "ਭਾਸ਼ਾ", "Language": "ਭਾਸ਼ਾ",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "ਹਲਕਾ", "Light": "ਹਲਕਾ",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Kliknij tutaj, żeby", "Click here to": "Kliknij tutaj, żeby",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Kliknij tutaj, aby wybrać", "Click here to select": "Kliknij tutaj, aby wybrać",
"Click here to select a csv file.": "Kliknij tutaj, żeby wybrać plik CSV", "Click here to select a csv file.": "Kliknij tutaj, żeby wybrać plik CSV",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "Dokumenty", "Documents": "Dokumenty",
"does not make any external connections, and your data stays securely on your locally hosted server.": "nie nawiązuje żadnych zewnętrznych połączeń, a Twoje dane pozostają bezpiecznie na Twoim lokalnie hostowanym serwerze.", "does not make any external connections, and your data stays securely on your locally hosted server.": "nie nawiązuje żadnych zewnętrznych połączeń, a Twoje dane pozostają bezpiecznie na Twoim lokalnie hostowanym serwerze.",
"Domain Filter List": "",
"Don't have an account?": "Nie masz konta?", "Don't have an account?": "Nie masz konta?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Wprowadź zakchodzenie bloku", "Enter Chunk Overlap": "Wprowadź zakchodzenie bloku",
"Enter Chunk Size": "Wprowadź rozmiar bloku", "Enter Chunk Size": "Wprowadź rozmiar bloku",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Wprowadź nieprzetworzony adres URL usługi Github", "Enter Github Raw URL": "Wprowadź nieprzetworzony adres URL usługi Github",
"Enter Google PSE API Key": "Wprowadź klucz API Google PSE", "Enter Google PSE API Key": "Wprowadź klucz API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Język", "Language": "Język",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Jasny", "Light": "Jasny",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Dokładne wyjaśnienie", "Thorough explanation": "Dokładne wyjaśnienie",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Clique aqui para", "Click here to": "Clique aqui para",
"Click here to download user import template file.": "Clique aqui para baixar o arquivo de modelo de importação de usuários.", "Click here to download user import template file.": "Clique aqui para baixar o arquivo de modelo de importação de usuários.",
"Click here to learn more about faster-whisper and see the available models.": "Clique aqui para aprender mais sobre Whisper e ver os modelos disponíveis.", "Click here to learn more about faster-whisper and see the available models.": "Clique aqui para aprender mais sobre Whisper e ver os modelos disponíveis.",
"Click here to see available models.": "",
"Click here to select": "Clique aqui para enviar", "Click here to select": "Clique aqui para enviar",
"Click here to select a csv file.": "Clique aqui para enviar um arquivo csv.", "Click here to select a csv file.": "Clique aqui para enviar um arquivo csv.",
"Click here to select a py file.": "Clique aqui para enviar um arquivo python.", "Click here to select a py file.": "Clique aqui para enviar um arquivo python.",
@ -290,6 +291,7 @@
"Documentation": "Documentação", "Documentation": "Documentação",
"Documents": "Documentos", "Documents": "Documentos",
"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz nenhuma conexão externa, e seus dados permanecem seguros no seu servidor local.", "does not make any external connections, and your data stays securely on your locally hosted server.": "não faz nenhuma conexão externa, e seus dados permanecem seguros no seu servidor local.",
"Domain Filter List": "",
"Don't have an account?": "Não tem uma conta?", "Don't have an account?": "Não tem uma conta?",
"don't install random functions from sources you don't trust.": "não instale funções aleatórias de fontes que você não confia.", "don't install random functions from sources you don't trust.": "não instale funções aleatórias de fontes que você não confia.",
"don't install random tools from sources you don't trust.": "não instale ferramentas aleatórias de fontes que você não confia.", "don't install random tools from sources you don't trust.": "não instale ferramentas aleatórias de fontes que você não confia.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Digite a Sobreposição de Chunk", "Enter Chunk Overlap": "Digite a Sobreposição de Chunk",
"Enter Chunk Size": "Digite o Tamanho do Chunk", "Enter Chunk Size": "Digite o Tamanho do Chunk",
"Enter description": "Digite a descrição", "Enter description": "Digite a descrição",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Digite a URL bruta do Github", "Enter Github Raw URL": "Digite a URL bruta do Github",
"Enter Google PSE API Key": "Digite a Chave API do Google PSE", "Enter Google PSE API Key": "Digite a Chave API do Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Conhecimento excluído com sucesso.", "Knowledge deleted successfully.": "Conhecimento excluído com sucesso.",
"Knowledge reset successfully.": "Conhecimento resetado com sucesso.", "Knowledge reset successfully.": "Conhecimento resetado com sucesso.",
"Knowledge updated successfully": "Conhecimento atualizado com sucesso", "Knowledge updated successfully": "Conhecimento atualizado com sucesso",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Rótulo", "Label": "Rótulo",
"Landing Page Mode": "Modo Landing Page", "Landing Page Mode": "Modo Landing Page",
"Language": "Idioma", "Language": "Idioma",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixe vazio para incluir todos os modelos do endpoint \"{{URL}}/models\"", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "Deixe vazio para incluir todos os modelos do endpoint \"{{URL}}/models\"",
"Leave empty to include all models or select specific models": "Deixe vazio para incluir todos os modelos ou selecione modelos especificos", "Leave empty to include all models or select specific models": "Deixe vazio para incluir todos os modelos ou selecione modelos especificos",
"Leave empty to use the default prompt, or enter a custom prompt": "Deixe vazio para usar o prompt padrão, ou insira um prompt personalizado", "Leave empty to use the default prompt, or enter a custom prompt": "Deixe vazio para usar o prompt padrão, ou insira um prompt personalizado",
"Leave model field empty to use the default model.": "",
"Light": "Claro", "Light": "Claro",
"Listening...": "Escutando...", "Listening...": "Escutando...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Esta ação resetará a base de conhecimento e sincronizará todos os arquivos. Deseja continuar?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Esta ação resetará a base de conhecimento e sincronizará todos os arquivos. Deseja continuar?",
"Thorough explanation": "Explicação detalhada", "Thorough explanation": "Explicação detalhada",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "URL do servidor Tika necessária.", "Tika Server URL required.": "URL do servidor Tika necessária.",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Clique aqui para", "Click here to": "Clique aqui para",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Clique aqui para selecionar", "Click here to select": "Clique aqui para selecionar",
"Click here to select a csv file.": "Clique aqui para selecionar um ficheiro csv.", "Click here to select a csv file.": "Clique aqui para selecionar um ficheiro csv.",
"Click here to select a py file.": "Clique aqui para selecionar um ficheiro py", "Click here to select a py file.": "Clique aqui para selecionar um ficheiro py",
@ -290,6 +291,7 @@
"Documentation": "Documentação", "Documentation": "Documentação",
"Documents": "Documentos", "Documents": "Documentos",
"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e os seus dados permanecem seguros no seu servidor alojado localmente.", "does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e os seus dados permanecem seguros no seu servidor alojado localmente.",
"Domain Filter List": "",
"Don't have an account?": "Não tem uma conta?", "Don't have an account?": "Não tem uma conta?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Escreva a Sobreposição de Fragmento", "Enter Chunk Overlap": "Escreva a Sobreposição de Fragmento",
"Enter Chunk Size": "Escreva o Tamanho do Fragmento", "Enter Chunk Size": "Escreva o Tamanho do Fragmento",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Escreva o URL cru do Github", "Enter Github Raw URL": "Escreva o URL cru do Github",
"Enter Google PSE API Key": "Escreva a chave da API PSE do Google", "Enter Google PSE API Key": "Escreva a chave da API PSE do Google",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Idioma", "Language": "Idioma",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Claro", "Light": "Claro",
"Listening...": "A escutar...", "Listening...": "A escutar...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Explicação Minuciosa", "Thorough explanation": "Explicação Minuciosa",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Apasă aici pentru", "Click here to": "Apasă aici pentru",
"Click here to download user import template file.": "Apasă aici pentru a descărca fișierul șablon de import utilizator.", "Click here to download user import template file.": "Apasă aici pentru a descărca fișierul șablon de import utilizator.",
"Click here to learn more about faster-whisper and see the available models.": "Faceți clic aici pentru a afla mai multe despre faster-whisper și pentru a vedea modelele disponibile.", "Click here to learn more about faster-whisper and see the available models.": "Faceți clic aici pentru a afla mai multe despre faster-whisper și pentru a vedea modelele disponibile.",
"Click here to see available models.": "",
"Click here to select": "Apasă aici pentru a selecta", "Click here to select": "Apasă aici pentru a selecta",
"Click here to select a csv file.": "Apasă aici pentru a selecta un fișier csv.", "Click here to select a csv file.": "Apasă aici pentru a selecta un fișier csv.",
"Click here to select a py file.": "Apasă aici pentru a selecta un fișier py.", "Click here to select a py file.": "Apasă aici pentru a selecta un fișier py.",
@ -290,6 +291,7 @@
"Documentation": "Documentație", "Documentation": "Documentație",
"Documents": "Documente", "Documents": "Documente",
"does not make any external connections, and your data stays securely on your locally hosted server.": "nu face nicio conexiune externă, iar datele tale rămân în siguranță pe serverul găzduit local.", "does not make any external connections, and your data stays securely on your locally hosted server.": "nu face nicio conexiune externă, iar datele tale rămân în siguranță pe serverul găzduit local.",
"Domain Filter List": "",
"Don't have an account?": "Nu ai un cont?", "Don't have an account?": "Nu ai un cont?",
"don't install random functions from sources you don't trust.": "nu instala funcții aleatorii din surse în care nu ai încredere.", "don't install random functions from sources you don't trust.": "nu instala funcții aleatorii din surse în care nu ai încredere.",
"don't install random tools from sources you don't trust.": "nu instala instrumente aleatorii din surse în care nu ai încredere.", "don't install random tools from sources you don't trust.": "nu instala instrumente aleatorii din surse în care nu ai încredere.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Introduceți Suprapunerea Blocului", "Enter Chunk Overlap": "Introduceți Suprapunerea Blocului",
"Enter Chunk Size": "Introduceți Dimensiunea Blocului", "Enter Chunk Size": "Introduceți Dimensiunea Blocului",
"Enter description": "Introduceți descrierea", "Enter description": "Introduceți descrierea",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Introduceți URL-ul Raw de pe Github", "Enter Github Raw URL": "Introduceți URL-ul Raw de pe Github",
"Enter Google PSE API Key": "Introduceți Cheia API Google PSE", "Enter Google PSE API Key": "Introduceți Cheia API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Cunoștințele au fost șterse cu succes.", "Knowledge deleted successfully.": "Cunoștințele au fost șterse cu succes.",
"Knowledge reset successfully.": "Resetarea cunoștințelor a fost efectuată cu succes.", "Knowledge reset successfully.": "Resetarea cunoștințelor a fost efectuată cu succes.",
"Knowledge updated successfully": "Cunoașterea a fost actualizată cu succes", "Knowledge updated successfully": "Cunoașterea a fost actualizată cu succes",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Modul Pagină de Aterizare", "Landing Page Mode": "Modul Pagină de Aterizare",
"Language": "Limbă", "Language": "Limbă",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"Leave empty to include all models or select specific models": "Lăsați gol pentru a include toate modelele sau selectați modele specifice", "Leave empty to include all models or select specific models": "Lăsați gol pentru a include toate modelele sau selectați modele specifice",
"Leave empty to use the default prompt, or enter a custom prompt": "Lăsați gol pentru a utiliza promptul implicit sau introduceți un prompt personalizat", "Leave empty to use the default prompt, or enter a custom prompt": "Lăsați gol pentru a utiliza promptul implicit sau introduceți un prompt personalizat",
"Leave model field empty to use the default model.": "",
"Light": "Luminos", "Light": "Luminos",
"Listening...": "Ascult...", "Listening...": "Ascult...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Aceasta va reseta baza de cunoștințe și va sincroniza toate fișierele. Doriți să continuați?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Aceasta va reseta baza de cunoștințe și va sincroniza toate fișierele. Doriți să continuați?",
"Thorough explanation": "Explicație detaliată", "Thorough explanation": "Explicație detaliată",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Este necesar URL-ul serverului Tika.", "Tika Server URL required.": "Este necesar URL-ul serverului Tika.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Нажмите здесь, чтобы", "Click here to": "Нажмите здесь, чтобы",
"Click here to download user import template file.": "Нажмите здесь, чтобы загрузить файл шаблона импорта пользователя", "Click here to download user import template file.": "Нажмите здесь, чтобы загрузить файл шаблона импорта пользователя",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Нажмите здесь, чтобы выбрать", "Click here to select": "Нажмите здесь, чтобы выбрать",
"Click here to select a csv file.": "Нажмите здесь, чтобы выбрать csv-файл.", "Click here to select a csv file.": "Нажмите здесь, чтобы выбрать csv-файл.",
"Click here to select a py file.": "Нажмите здесь, чтобы выбрать py-файл", "Click here to select a py file.": "Нажмите здесь, чтобы выбрать py-файл",
@ -290,6 +291,7 @@
"Documentation": "Документация", "Documentation": "Документация",
"Documents": "Документы", "Documents": "Документы",
"does not make any external connections, and your data stays securely on your locally hosted server.": "не устанавливает никаких внешних соединений, и ваши данные надежно хранятся на вашем локальном сервере.", "does not make any external connections, and your data stays securely on your locally hosted server.": "не устанавливает никаких внешних соединений, и ваши данные надежно хранятся на вашем локальном сервере.",
"Domain Filter List": "",
"Don't have an account?": "У вас нет аккаунта?", "Don't have an account?": "У вас нет аккаунта?",
"don't install random functions from sources you don't trust.": "не устанавливайте случайные функции из источников, которым вы не доверяете.", "don't install random functions from sources you don't trust.": "не устанавливайте случайные функции из источников, которым вы не доверяете.",
"don't install random tools from sources you don't trust.": "не устанавливайте случайные инструменты из источников, которым вы не доверяете.", "don't install random tools from sources you don't trust.": "не устанавливайте случайные инструменты из источников, которым вы не доверяете.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Введите перекрытие фрагмента", "Enter Chunk Overlap": "Введите перекрытие фрагмента",
"Enter Chunk Size": "Введите размер фрагмента", "Enter Chunk Size": "Введите размер фрагмента",
"Enter description": "Введите описание", "Enter description": "Введите описание",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Введите необработанный URL-адрес Github", "Enter Github Raw URL": "Введите необработанный URL-адрес Github",
"Enter Google PSE API Key": "Введите ключ API Google PSE", "Enter Google PSE API Key": "Введите ключ API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Знания успешно удалены.", "Knowledge deleted successfully.": "Знания успешно удалены.",
"Knowledge reset successfully.": "Знания успешно сброшены.", "Knowledge reset successfully.": "Знания успешно сброшены.",
"Knowledge updated successfully": "Знания успешно обновлены", "Knowledge updated successfully": "Знания успешно обновлены",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Режим Целевой Страницы", "Landing Page Mode": "Режим Целевой Страницы",
"Language": "Язык", "Language": "Язык",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Светлый", "Light": "Светлый",
"Listening...": "Слушаю...", "Listening...": "Слушаю...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Требуется URL-адрес сервера Tika.", "Tika Server URL required.": "Требуется URL-адрес сервера Tika.",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Kliknite tu na", "Click here to": "Kliknite tu na",
"Click here to download user import template file.": "Kliknite tu pre stiahnutie šablóny súboru na import užívateľov.", "Click here to download user import template file.": "Kliknite tu pre stiahnutie šablóny súboru na import užívateľov.",
"Click here to learn more about faster-whisper and see the available models.": "Kliknite sem a dozviete sa viac o faster-whisper a pozrite si dostupné modely.", "Click here to learn more about faster-whisper and see the available models.": "Kliknite sem a dozviete sa viac o faster-whisper a pozrite si dostupné modely.",
"Click here to see available models.": "",
"Click here to select": "Kliknite sem pre výber", "Click here to select": "Kliknite sem pre výber",
"Click here to select a csv file.": "Kliknite sem pre výber súboru typu csv.", "Click here to select a csv file.": "Kliknite sem pre výber súboru typu csv.",
"Click here to select a py file.": "Kliknite sem pre výber {{py}} súboru.", "Click here to select a py file.": "Kliknite sem pre výber {{py}} súboru.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentácia", "Documentation": "Dokumentácia",
"Documents": "Dokumenty", "Documents": "Dokumenty",
"does not make any external connections, and your data stays securely on your locally hosted server.": "nevytvára žiadne externé pripojenia a vaše dáta zostávajú bezpečne na vašom lokálnom serveri.", "does not make any external connections, and your data stays securely on your locally hosted server.": "nevytvára žiadne externé pripojenia a vaše dáta zostávajú bezpečne na vašom lokálnom serveri.",
"Domain Filter List": "",
"Don't have an account?": "Nemáte účet?", "Don't have an account?": "Nemáte účet?",
"don't install random functions from sources you don't trust.": "Neinštalujte náhodné funkcie zo zdrojov, ktorým nedôverujete.", "don't install random functions from sources you don't trust.": "Neinštalujte náhodné funkcie zo zdrojov, ktorým nedôverujete.",
"don't install random tools from sources you don't trust.": "Neinštalujte náhodné nástroje zo zdrojov, ktorým nedôverujete.", "don't install random tools from sources you don't trust.": "Neinštalujte náhodné nástroje zo zdrojov, ktorým nedôverujete.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Zadajte prekryv časti", "Enter Chunk Overlap": "Zadajte prekryv časti",
"Enter Chunk Size": "Zadajte veľkosť časti", "Enter Chunk Size": "Zadajte veľkosť časti",
"Enter description": "Zadajte popis", "Enter description": "Zadajte popis",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Zadajte URL adresu Github Raw", "Enter Github Raw URL": "Zadajte URL adresu Github Raw",
"Enter Google PSE API Key": "Zadajte kľúč rozhrania API Google PSE", "Enter Google PSE API Key": "Zadajte kľúč rozhrania API Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Znalosti boli úspešne odstránené.", "Knowledge deleted successfully.": "Znalosti boli úspešne odstránené.",
"Knowledge reset successfully.": "Úspešné obnovenie znalostí.", "Knowledge reset successfully.": "Úspešné obnovenie znalostí.",
"Knowledge updated successfully": "Znalosti úspešne aktualizované", "Knowledge updated successfully": "Znalosti úspešne aktualizované",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "Režim vstupnej stránky", "Landing Page Mode": "Režim vstupnej stránky",
"Language": "Jazyk", "Language": "Jazyk",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"Leave empty to include all models or select specific models": "Nechajte prázdne pre zahrnutie všetkých modelov alebo vyberte konkrétne modely.", "Leave empty to include all models or select specific models": "Nechajte prázdne pre zahrnutie všetkých modelov alebo vyberte konkrétne modely.",
"Leave empty to use the default prompt, or enter a custom prompt": "Nechajte prázdne pre použitie predvoleného podnetu, alebo zadajte vlastný podnet.", "Leave empty to use the default prompt, or enter a custom prompt": "Nechajte prázdne pre použitie predvoleného podnetu, alebo zadajte vlastný podnet.",
"Leave model field empty to use the default model.": "",
"Light": "Svetlo", "Light": "Svetlo",
"Listening...": "Počúvanie...", "Listening...": "Počúvanie...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostnú databázu a synchronizuje všetky súbory. Prajete si pokračovať?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Toto obnoví znalostnú databázu a synchronizuje všetky súbory. Prajete si pokračovať?",
"Thorough explanation": "Obsiahle vysvetlenie", "Thorough explanation": "Obsiahle vysvetlenie",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Je vyžadovaná URL adresa servera Tika.", "Tika Server URL required.": "Je vyžadovaná URL adresa servera Tika.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

View file

@ -163,6 +163,7 @@
"Click here to": "Кликните овде да", "Click here to": "Кликните овде да",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Кликните овде да изаберете", "Click here to select": "Кликните овде да изаберете",
"Click here to select a csv file.": "Кликните овде да изаберете csv датотеку.", "Click here to select a csv file.": "Кликните овде да изаберете csv датотеку.",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "Документација", "Documentation": "Документација",
"Documents": "Документи", "Documents": "Документи",
"does not make any external connections, and your data stays securely on your locally hosted server.": "не отвара никакве спољне везе и ваши подаци остају сигурно на вашем локално хостованом серверу.", "does not make any external connections, and your data stays securely on your locally hosted server.": "не отвара никакве спољне везе и ваши подаци остају сигурно на вашем локално хостованом серверу.",
"Domain Filter List": "",
"Don't have an account?": "Немате налог?", "Don't have an account?": "Немате налог?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Унесите преклапање делова", "Enter Chunk Overlap": "Унесите преклапање делова",
"Enter Chunk Size": "Унесите величину дела", "Enter Chunk Size": "Унесите величину дела",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Унесите Гитхуб Раw УРЛ адресу", "Enter Github Raw URL": "Унесите Гитхуб Раw УРЛ адресу",
"Enter Google PSE API Key": "Унесите Гоогле ПСЕ АПИ кључ", "Enter Google PSE API Key": "Унесите Гоогле ПСЕ АПИ кључ",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "Етикета", "Label": "Етикета",
"Landing Page Mode": "Режим почетне стране", "Landing Page Mode": "Режим почетне стране",
"Language": "Језик", "Language": "Језик",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Светла", "Light": "Светла",
"Listening...": "Слушам...", "Listening...": "Слушам...",
"Llama.cpp": "Llama.cpp", "Llama.cpp": "Llama.cpp",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Klicka här för att", "Click here to": "Klicka här för att",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "Klicka här för att välja", "Click here to select": "Klicka här för att välja",
"Click here to select a csv file.": "Klicka här för att välja en csv-fil.", "Click here to select a csv file.": "Klicka här för att välja en csv-fil.",
"Click here to select a py file.": "Klicka här för att välja en python-fil.", "Click here to select a py file.": "Klicka här för att välja en python-fil.",
@ -290,6 +291,7 @@
"Documentation": "Dokumentation", "Documentation": "Dokumentation",
"Documents": "Dokument", "Documents": "Dokument",
"does not make any external connections, and your data stays securely on your locally hosted server.": "gör inga externa anslutningar, och dina data förblir säkra på din lokalt värdade server.", "does not make any external connections, and your data stays securely on your locally hosted server.": "gör inga externa anslutningar, och dina data förblir säkra på din lokalt värdade server.",
"Domain Filter List": "",
"Don't have an account?": "Har du inget konto?", "Don't have an account?": "Har du inget konto?",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Ange chunköverlappning", "Enter Chunk Overlap": "Ange chunköverlappning",
"Enter Chunk Size": "Ange chunkstorlek", "Enter Chunk Size": "Ange chunkstorlek",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Ange Github Raw URL", "Enter Github Raw URL": "Ange Github Raw URL",
"Enter Google PSE API Key": "Ange Google PSE API-nyckel", "Enter Google PSE API Key": "Ange Google PSE API-nyckel",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Språk", "Language": "Språk",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "Ljus", "Light": "Ljus",
"Listening...": "Lyssnar...", "Listening...": "Lyssnar...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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": "Djupare förklaring", "Thorough explanation": "Djupare förklaring",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "คลิกที่นี่เพื่อ", "Click here to": "คลิกที่นี่เพื่อ",
"Click here to download user import template file.": "คลิกที่นี่เพื่อดาวน์โหลดไฟล์แม่แบบนำเข้าผู้ใช้", "Click here to download user import template file.": "คลิกที่นี่เพื่อดาวน์โหลดไฟล์แม่แบบนำเข้าผู้ใช้",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "คลิกที่นี่เพื่อเลือก", "Click here to select": "คลิกที่นี่เพื่อเลือก",
"Click here to select a csv file.": "คลิกที่นี่เพื่อเลือกไฟล์ csv", "Click here to select a csv file.": "คลิกที่นี่เพื่อเลือกไฟล์ csv",
"Click here to select a py file.": "คลิกที่นี่เพื่อเลือกไฟล์ py", "Click here to select a py file.": "คลิกที่นี่เพื่อเลือกไฟล์ py",
@ -290,6 +291,7 @@
"Documentation": "เอกสารประกอบ", "Documentation": "เอกสารประกอบ",
"Documents": "เอกสาร", "Documents": "เอกสาร",
"does not make any external connections, and your data stays securely on your locally hosted server.": "ไม่เชื่อมต่อภายนอกใดๆ และข้อมูลของคุณจะอยู่บนเซิร์ฟเวอร์ที่โฮสต์ในท้องถิ่นของคุณอย่างปลอดภัย", "does not make any external connections, and your data stays securely on your locally hosted server.": "ไม่เชื่อมต่อภายนอกใดๆ และข้อมูลของคุณจะอยู่บนเซิร์ฟเวอร์ที่โฮสต์ในท้องถิ่นของคุณอย่างปลอดภัย",
"Domain Filter List": "",
"Don't have an account?": "ยังไม่มีบัญชี?", "Don't have an account?": "ยังไม่มีบัญชี?",
"don't install random functions from sources you don't trust.": "อย่าติดตั้งฟังก์ชันแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ", "don't install random functions from sources you don't trust.": "อย่าติดตั้งฟังก์ชันแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ",
"don't install random tools from sources you don't trust.": "อย่าติดตั้งเครื่องมือแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ", "don't install random tools from sources you don't trust.": "อย่าติดตั้งเครื่องมือแบบสุ่มจากแหล่งที่คุณไม่ไว้วางใจ",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "ใส่การทับซ้อนส่วนข้อมูล", "Enter Chunk Overlap": "ใส่การทับซ้อนส่วนข้อมูล",
"Enter Chunk Size": "ใส่ขนาดส่วนข้อมูล", "Enter Chunk Size": "ใส่ขนาดส่วนข้อมูล",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "ใส่ URL ดิบของ Github", "Enter Github Raw URL": "ใส่ URL ดิบของ Github",
"Enter Google PSE API Key": "ใส่คีย์ API ของ Google PSE", "Enter Google PSE API Key": "ใส่คีย์ API ของ Google PSE",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "ภาษา", "Language": "ภาษา",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "แสง", "Light": "แสง",
"Listening...": "กำลังฟัง...", "Listening...": "กำลังฟัง...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "จำเป็นต้องมี URL ของเซิร์ฟเวอร์ Tika", "Tika Server URL required.": "จำเป็นต้องมี URL ของเซิร์ฟเวอร์ Tika",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "", "Click here to": "",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "",
"Click here to see available models.": "",
"Click here to select": "", "Click here to select": "",
"Click here to select a csv file.": "", "Click here to select a csv file.": "",
"Click here to select a py file.": "", "Click here to select a py file.": "",
@ -290,6 +291,7 @@
"Documentation": "", "Documentation": "",
"Documents": "", "Documents": "",
"does not make any external connections, and your data stays securely on your locally hosted server.": "", "does not make any external connections, and your data stays securely on your locally hosted server.": "",
"Domain Filter List": "",
"Don't have an account?": "", "Don't have an account?": "",
"don't install random functions from sources you don't trust.": "", "don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "", "don't install random tools from sources you don't trust.": "",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "", "Enter Chunk Overlap": "",
"Enter Chunk Size": "", "Enter Chunk Size": "",
"Enter description": "", "Enter description": "",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "", "Enter Github Raw URL": "",
"Enter Google PSE API Key": "", "Enter Google PSE API Key": "",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "", "Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "", "Knowledge reset successfully.": "",
"Knowledge updated successfully": "", "Knowledge updated successfully": "",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "", "Language": "",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"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.": "",
"Light": "", "Light": "",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,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}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "", "Tika Server URL required.": "",
"Tiktoken": "", "Tiktoken": "",

View file

@ -163,6 +163,7 @@
"Click here to": "Şunu yapmak için buraya tıklayın:", "Click here to": "Şunu yapmak için buraya tıklayın:",
"Click here to download user import template file.": "Kullanıcı içe aktarma şablon dosyasını indirmek için buraya tıklayın.", "Click here to download user import template file.": "Kullanıcı içe aktarma şablon dosyasını indirmek için buraya tıklayın.",
"Click here to learn more about faster-whisper and see the available models.": "faster-whisper hakkında daha fazla bilgi edinmek ve mevcut modelleri görmek için buraya tıklayın.", "Click here to learn more about faster-whisper and see the available models.": "faster-whisper hakkında daha fazla bilgi edinmek ve mevcut modelleri görmek için buraya tıklayın.",
"Click here to see available models.": "",
"Click here to select": "Seçmek için buraya tıklayın", "Click here to select": "Seçmek için buraya tıklayın",
"Click here to select a csv file.": "Bir CSV dosyası seçmek için buraya tıklayın.", "Click here to select a csv file.": "Bir CSV dosyası seçmek için buraya tıklayın.",
"Click here to select a py file.": "Bir py dosyası seçmek için buraya tıklayın.", "Click here to select a py file.": "Bir py dosyası seçmek için buraya tıklayın.",
@ -290,6 +291,7 @@
"Documentation": "Dökümantasyon", "Documentation": "Dökümantasyon",
"Documents": "Belgeler", "Documents": "Belgeler",
"does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.", "does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.",
"Domain Filter List": "",
"Don't have an account?": "Hesabınız yok mu?", "Don't have an account?": "Hesabınız yok mu?",
"don't install random functions from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele fonksiyonlar yüklemeyin.", "don't install random functions from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele fonksiyonlar yüklemeyin.",
"don't install random tools from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele araçlar yüklemeyin.", "don't install random tools from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele araçlar yüklemeyin.",
@ -349,6 +351,7 @@
"Enter Chunk Overlap": "Chunk Örtüşmesini Girin", "Enter Chunk Overlap": "Chunk Örtüşmesini Girin",
"Enter Chunk Size": "Chunk Boyutunu Girin", "Enter Chunk Size": "Chunk Boyutunu Girin",
"Enter description": "Açıklama girin", "Enter description": "Açıklama girin",
"Enter domains separated by commas (e.g., example.com,site.org)": "",
"Enter Exa API Key": "", "Enter Exa API Key": "",
"Enter Github Raw URL": "Github Raw URL'sini girin", "Enter Github Raw URL": "Github Raw URL'sini girin",
"Enter Google PSE API Key": "Google PSE API Anahtarını Girin", "Enter Google PSE API Key": "Google PSE API Anahtarını Girin",
@ -552,6 +555,8 @@
"Knowledge deleted successfully.": "Bilgi başarıyla silindi.", "Knowledge deleted successfully.": "Bilgi başarıyla silindi.",
"Knowledge reset successfully.": "Bilgi başarıyla sıfırlandı.", "Knowledge reset successfully.": "Bilgi başarıyla sıfırlandı.",
"Knowledge updated successfully": "Bilgi başarıyla güncellendi", "Knowledge updated successfully": "Bilgi başarıyla güncellendi",
"Kokoro.js (Browser)": "",
"Kokoro.js Dtype": "",
"Label": "", "Label": "",
"Landing Page Mode": "", "Landing Page Mode": "",
"Language": "Dil", "Language": "Dil",
@ -566,6 +571,7 @@
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "", "Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
"Leave empty to include all models or select specific models": "Tüm modelleri dahil etmek için boş bırakın veya belirli modelleri seçin", "Leave empty to include all models or select specific models": "Tüm modelleri dahil etmek için boş bırakın veya belirli modelleri seçin",
"Leave empty to use the default prompt, or enter a custom prompt": "Varsayılan promptu kullanmak için boş bırakın veya özel bir prompt girin", "Leave empty to use the default prompt, or enter a custom prompt": "Varsayılan promptu kullanmak için boş bırakın veya özel bir prompt girin",
"Leave model field empty to use the default model.": "",
"Light": "Açık", "Light": "Açık",
"Listening...": "Dinleniyor...", "Listening...": "Dinleniyor...",
"Llama.cpp": "", "Llama.cpp": "",
@ -944,6 +950,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Bu, bilgi tabanını sıfırlayacak ve tüm dosyaları senkronize edecek. Devam etmek istiyor musunuz?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Bu, bilgi tabanını sıfırlayacak ve tüm dosyaları senkronize edecek. Devam etmek istiyor musunuz?",
"Thorough explanation": "Kapsamlııklama", "Thorough explanation": "Kapsamlııklama",
"Thought for {{DURATION}}": "", "Thought for {{DURATION}}": "",
"Thought for {{DURATION}} seconds": "",
"Tika": "", "Tika": "",
"Tika Server URL required.": "Tika Sunucu URL'si gereklidir.", "Tika Server URL required.": "Tika Sunucu URL'si gereklidir.",
"Tiktoken": "Tiktoken", "Tiktoken": "Tiktoken",

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