Merge branch 'dev' into main

This commit is contained in:
seiran 2025-06-08 05:58:24 +08:00 committed by GitHub
commit e97394958e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
117 changed files with 2735 additions and 786 deletions

48
.gitattributes vendored
View file

@ -1 +1,49 @@
# TypeScript
*.ts text eol=lf
*.tsx text eol=lf
# JavaScript
*.js text eol=lf
*.jsx text eol=lf
*.mjs text eol=lf
*.cjs text eol=lf
# Svelte
*.svelte text eol=lf
# HTML/CSS
*.html text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.less text eol=lf
# Config files and JSON
*.json text eol=lf
*.jsonc text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.toml text eol=lf
# Shell scripts
*.sh text eol=lf *.sh text eol=lf
# Markdown & docs
*.md text eol=lf
*.mdx text eol=lf
*.txt text eol=lf
# Git-related
.gitattributes text eol=lf
.gitignore text eol=lf
# Prettier and other dotfiles
.prettierrc text eol=lf
.prettierignore text eol=lf
.eslintrc text eol=lf
.eslintignore text eol=lf
.stylelintrc text eol=lf
.editorconfig text eol=lf
# Misc
*.env text eol=lf
*.lock text eol=lf

View file

@ -14,16 +14,18 @@ env:
jobs: jobs:
build-main-image: build-main-image:
runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} runs-on: ${{ matrix.runner }}
permissions: permissions:
contents: read contents: read
packages: write packages: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: include:
- linux/amd64 - platform: linux/amd64
- linux/arm64 runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps: steps:
# GitHub Packages requires the entire repository name to be in lowercase # GitHub Packages requires the entire repository name to be in lowercase
@ -111,16 +113,18 @@ jobs:
retention-days: 1 retention-days: 1
build-cuda-image: build-cuda-image:
runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} runs-on: ${{ matrix.runner }}
permissions: permissions:
contents: read contents: read
packages: write packages: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: include:
- linux/amd64 - platform: linux/amd64
- linux/arm64 runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps: steps:
# GitHub Packages requires the entire repository name to be in lowercase # GitHub Packages requires the entire repository name to be in lowercase
@ -210,17 +214,122 @@ jobs:
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1
build-ollama-image: build-cuda126-image:
runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} runs-on: ${{ matrix.runner }}
permissions: permissions:
contents: read contents: read
packages: write packages: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: include:
- linux/amd64 - platform: linux/amd64
- linux/arm64 runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps:
# GitHub Packages requires the entire repository name to be in lowercase
# although the repository owner has a lowercase username, this prevents some people from running actions after forking
- name: Set repository and image name to lowercase
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV}
echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV}
env:
IMAGE_NAME: '${{ github.repository }}'
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker images (cuda126 tag)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.FULL_IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha,prefix=git-
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,enable=${{ github.ref == 'refs/heads/main' }},prefix=,suffix=,value=cuda126
flavor: |
latest=${{ github.ref == 'refs/heads/main' }}
suffix=-cuda126,onlatest=true
- name: Extract metadata for Docker cache
id: cache-meta
uses: docker/metadata-action@v5
with:
images: ${{ env.FULL_IMAGE_NAME }}
tags: |
type=ref,event=branch
${{ github.ref_type == 'tag' && 'type=raw,value=main' || '' }}
flavor: |
prefix=cache-cuda126-${{ matrix.platform }}-
latest=false
- name: Build Docker image (cuda126)
uses: docker/build-push-action@v5
id: build
with:
context: .
push: true
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }}
cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
build-args: |
BUILD_HASH=${{ github.sha }}
USE_CUDA=true
USE_CUDA_VER=cu126
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-cuda126-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
build-ollama-image:
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps: steps:
# GitHub Packages requires the entire repository name to be in lowercase # GitHub Packages requires the entire repository name to be in lowercase
@ -420,6 +529,62 @@ jobs:
run: | run: |
docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }}
merge-cuda126-images:
runs-on: ubuntu-latest
needs: [build-cuda126-image]
steps:
# GitHub Packages requires the entire repository name to be in lowercase
# although the repository owner has a lowercase username, this prevents some people from running actions after forking
- name: Set repository and image name to lowercase
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV}
echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV}
env:
IMAGE_NAME: '${{ github.repository }}'
- name: Download digests
uses: actions/download-artifact@v4
with:
pattern: digests-cuda126-*
path: /tmp/digests
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker images (default latest tag)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.FULL_IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha,prefix=git-
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,enable=${{ github.ref == 'refs/heads/main' }},prefix=,suffix=,value=cuda126
flavor: |
latest=${{ github.ref == 'refs/heads/main' }}
suffix=-cuda126,onlatest=true
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.FULL_IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ steps.meta.outputs.version }}
merge-ollama-images: merge-ollama-images:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build-ollama-image] needs: [build-ollama-image]

View file

@ -5,5 +5,6 @@
"printWidth": 100, "printWidth": 100,
"plugins": ["prettier-plugin-svelte"], "plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."], "pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }],
"endOfLine": "lf"
} }

View file

@ -79,7 +79,7 @@ Want to learn more about Open WebUI's features? Check out our [Open WebUI docume
<tr> <tr>
<td> <td>
<a href="https://warp.dev/open-webui" target="_blank"> <a href="https://warp.dev/open-webui" target="_blank">
<img src="https://docs.openwebui.com/sponsors/logos/warp.png" alt="n8n" style="width: 8rem; height: 8rem; border-radius: .75rem;" /> <img src="https://docs.openwebui.com/sponsors/logos/warp.png" alt="Warp" style="width: 8rem; height: 8rem; border-radius: .75rem;" />
</a> </a>
</td> </td>
<td> <td>

View file

@ -901,9 +901,7 @@ TOOL_SERVER_CONNECTIONS = PersistentConfig(
#################################### ####################################
WEBUI_URL = PersistentConfig( WEBUI_URL = PersistentConfig("WEBUI_URL", "webui.url", os.environ.get("WEBUI_URL", ""))
"WEBUI_URL", "webui.url", os.environ.get("WEBUI_URL", "http://localhost:3000")
)
ENABLE_SIGNUP = PersistentConfig( ENABLE_SIGNUP = PersistentConfig(
@ -1413,6 +1411,35 @@ Strictly return in JSON format:
{{MESSAGES:END:6}} {{MESSAGES:END:6}}
</chat_history>""" </chat_history>"""
FOLLOW_UP_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
"FOLLOW_UP_GENERATION_PROMPT_TEMPLATE",
"task.follow_up.prompt_template",
os.environ.get("FOLLOW_UP_GENERATION_PROMPT_TEMPLATE", ""),
)
DEFAULT_FOLLOW_UP_GENERATION_PROMPT_TEMPLATE = """### Task:
Suggest 3-5 relevant follow-up questions or prompts that the user might naturally ask next in this conversation as a **user**, based on the chat history, to help continue or deepen the discussion.
### Guidelines:
- Write all follow-up questions from the users point of view, directed to the assistant.
- Make questions concise, clear, and directly related to the discussed topic(s).
- Only suggest follow-ups that make sense given the chat content and do not repeat what was already covered.
- If the conversation is very short or not specific, suggest more general (but relevant) follow-ups the user might ask.
- Use the conversation's primary language; default to English if multilingual.
- Response must be a JSON array of strings, no extra text or formatting.
### Output:
JSON format: { "follow_ups": ["Question 1?", "Question 2?", "Question 3?"] }
### Chat History:
<chat_history>
{{MESSAGES:END:6}}
</chat_history>"""
ENABLE_FOLLOW_UP_GENERATION = PersistentConfig(
"ENABLE_FOLLOW_UP_GENERATION",
"task.follow_up.enable",
os.environ.get("ENABLE_FOLLOW_UP_GENERATION", "True").lower() == "true",
)
ENABLE_TAGS_GENERATION = PersistentConfig( ENABLE_TAGS_GENERATION = PersistentConfig(
"ENABLE_TAGS_GENERATION", "ENABLE_TAGS_GENERATION",
"task.tags.enable", "task.tags.enable",
@ -2444,6 +2471,18 @@ PERPLEXITY_API_KEY = PersistentConfig(
os.getenv("PERPLEXITY_API_KEY", ""), os.getenv("PERPLEXITY_API_KEY", ""),
) )
PERPLEXITY_MODEL = PersistentConfig(
"PERPLEXITY_MODEL",
"rag.web.search.perplexity_model",
os.getenv("PERPLEXITY_MODEL", "sonar"),
)
PERPLEXITY_SEARCH_CONTEXT_USAGE = PersistentConfig(
"PERPLEXITY_SEARCH_CONTEXT_USAGE",
"rag.web.search.perplexity_search_context_usage",
os.getenv("PERPLEXITY_SEARCH_CONTEXT_USAGE", "medium"),
)
SOUGOU_API_SID = PersistentConfig( SOUGOU_API_SID = PersistentConfig(
"SOUGOU_API_SID", "SOUGOU_API_SID",
"rag.web.search.sougou_api_sid", "rag.web.search.sougou_api_sid",

View file

@ -111,6 +111,7 @@ class TASKS(str, Enum):
DEFAULT = lambda task="": f"{task if task else 'generation'}" DEFAULT = lambda task="": f"{task if task else 'generation'}"
TITLE_GENERATION = "title_generation" TITLE_GENERATION = "title_generation"
FOLLOW_UP_GENERATION = "follow_up_generation"
TAGS_GENERATION = "tags_generation" TAGS_GENERATION = "tags_generation"
EMOJI_GENERATION = "emoji_generation" EMOJI_GENERATION = "emoji_generation"
QUERY_GENERATION = "query_generation" QUERY_GENERATION = "query_generation"

View file

@ -25,6 +25,7 @@ from open_webui.socket.main import (
) )
from open_webui.models.users import UserModel
from open_webui.models.functions import Functions from open_webui.models.functions import Functions
from open_webui.models.models import Models from open_webui.models.models import Models
@ -227,12 +228,7 @@ async def generate_function_chat_completion(
"__task__": __task__, "__task__": __task__,
"__task_body__": __task_body__, "__task_body__": __task_body__,
"__files__": files, "__files__": files,
"__user__": { "__user__": user.model_dump() if isinstance(user, UserModel) else {},
"id": user.id,
"email": user.email,
"name": user.name,
"role": user.role,
},
"__metadata__": metadata, "__metadata__": metadata,
"__request__": request, "__request__": request,
} }

View file

@ -37,7 +37,7 @@ from fastapi import (
from fastapi.openapi.docs import get_swagger_ui_html from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, RedirectResponse from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from starlette_compress import CompressMiddleware from starlette_compress import CompressMiddleware
@ -268,6 +268,8 @@ from open_webui.config import (
BRAVE_SEARCH_API_KEY, BRAVE_SEARCH_API_KEY,
EXA_API_KEY, EXA_API_KEY,
PERPLEXITY_API_KEY, PERPLEXITY_API_KEY,
PERPLEXITY_MODEL,
PERPLEXITY_SEARCH_CONTEXT_USAGE,
SOUGOU_API_SID, SOUGOU_API_SID,
SOUGOU_API_SK, SOUGOU_API_SK,
KAGI_SEARCH_API_KEY, KAGI_SEARCH_API_KEY,
@ -359,10 +361,12 @@ from open_webui.config import (
TASK_MODEL_EXTERNAL, TASK_MODEL_EXTERNAL,
ENABLE_TAGS_GENERATION, ENABLE_TAGS_GENERATION,
ENABLE_TITLE_GENERATION, ENABLE_TITLE_GENERATION,
ENABLE_FOLLOW_UP_GENERATION,
ENABLE_SEARCH_QUERY_GENERATION, ENABLE_SEARCH_QUERY_GENERATION,
ENABLE_RETRIEVAL_QUERY_GENERATION, ENABLE_RETRIEVAL_QUERY_GENERATION,
ENABLE_AUTOCOMPLETE_GENERATION, ENABLE_AUTOCOMPLETE_GENERATION,
TITLE_GENERATION_PROMPT_TEMPLATE, TITLE_GENERATION_PROMPT_TEMPLATE,
FOLLOW_UP_GENERATION_PROMPT_TEMPLATE,
TAGS_GENERATION_PROMPT_TEMPLATE, TAGS_GENERATION_PROMPT_TEMPLATE,
IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE,
TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
@ -411,6 +415,7 @@ from open_webui.utils.chat import (
chat_completed as chat_completed_handler, chat_completed as chat_completed_handler,
chat_action as chat_action_handler, chat_action as chat_action_handler,
) )
from open_webui.utils.embeddings import generate_embeddings
from open_webui.utils.middleware import process_chat_payload, process_chat_response from open_webui.utils.middleware import process_chat_payload, process_chat_response
from open_webui.utils.access_control import has_access from open_webui.utils.access_control import has_access
@ -771,6 +776,8 @@ app.state.config.BING_SEARCH_V7_ENDPOINT = BING_SEARCH_V7_ENDPOINT
app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY
app.state.config.EXA_API_KEY = EXA_API_KEY app.state.config.EXA_API_KEY = EXA_API_KEY
app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY
app.state.config.PERPLEXITY_MODEL = PERPLEXITY_MODEL
app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = PERPLEXITY_SEARCH_CONTEXT_USAGE
app.state.config.SOUGOU_API_SID = SOUGOU_API_SID app.state.config.SOUGOU_API_SID = SOUGOU_API_SID
app.state.config.SOUGOU_API_SK = SOUGOU_API_SK app.state.config.SOUGOU_API_SK = SOUGOU_API_SK
app.state.config.EXTERNAL_WEB_SEARCH_URL = EXTERNAL_WEB_SEARCH_URL app.state.config.EXTERNAL_WEB_SEARCH_URL = EXTERNAL_WEB_SEARCH_URL
@ -959,6 +966,7 @@ app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION = ENABLE_RETRIEVAL_QUERY_GENE
app.state.config.ENABLE_AUTOCOMPLETE_GENERATION = ENABLE_AUTOCOMPLETE_GENERATION app.state.config.ENABLE_AUTOCOMPLETE_GENERATION = ENABLE_AUTOCOMPLETE_GENERATION
app.state.config.ENABLE_TAGS_GENERATION = ENABLE_TAGS_GENERATION app.state.config.ENABLE_TAGS_GENERATION = ENABLE_TAGS_GENERATION
app.state.config.ENABLE_TITLE_GENERATION = ENABLE_TITLE_GENERATION app.state.config.ENABLE_TITLE_GENERATION = ENABLE_TITLE_GENERATION
app.state.config.ENABLE_FOLLOW_UP_GENERATION = ENABLE_FOLLOW_UP_GENERATION
app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = TITLE_GENERATION_PROMPT_TEMPLATE app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = TITLE_GENERATION_PROMPT_TEMPLATE
@ -966,6 +974,9 @@ app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE = TAGS_GENERATION_PROMPT_TEMPLA
app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = ( app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = (
IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
) )
app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE = (
FOLLOW_UP_GENERATION_PROMPT_TEMPLATE
)
app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = ( app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = (
TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE
@ -1197,6 +1208,37 @@ async def get_base_models(request: Request, user=Depends(get_admin_user)):
return {"data": models} return {"data": models}
##################################
# Embeddings
##################################
@app.post("/api/embeddings")
async def embeddings(
request: Request, form_data: dict, user=Depends(get_verified_user)
):
"""
OpenAI-compatible embeddings endpoint.
This handler:
- Performs user/model checks and dispatches to the correct backend.
- Supports OpenAI, Ollama, arena models, pipelines, and any compatible provider.
Args:
request (Request): Request context.
form_data (dict): OpenAI-like payload (e.g., {"model": "...", "input": [...]})
user (UserModel): Authenticated user.
Returns:
dict: OpenAI-compatible embeddings response.
"""
# Make sure models are loaded in app state
if not request.app.state.MODELS:
await get_all_models(request, user=user)
# Use generic dispatcher in utils.embeddings
return await generate_embeddings(request, form_data, user)
@app.post("/api/chat/completions") @app.post("/api/chat/completions")
async def chat_completion( async def chat_completion(
request: Request, request: Request,
@ -1628,7 +1670,20 @@ async def healthcheck_with_db():
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
app.mount("/cache", StaticFiles(directory=CACHE_DIR), name="cache")
@app.get("/cache/{path:path}")
async def serve_cache_file(
path: str,
user=Depends(get_verified_user),
):
file_path = os.path.abspath(os.path.join(CACHE_DIR, path))
# prevent path traversal
if not file_path.startswith(os.path.abspath(CACHE_DIR)):
raise HTTPException(status_code=404, detail="File not found")
if not os.path.isfile(file_path):
raise HTTPException(status_code=404, detail="File not found")
return FileResponse(file_path)
def swagger_ui_html(*args, **kwargs): def swagger_ui_html(*args, **kwargs):

View file

@ -95,6 +95,7 @@ class UserRoleUpdateForm(BaseModel):
class UserUpdateForm(BaseModel): class UserUpdateForm(BaseModel):
role: str
name: str name: str
email: str email: str
profile_image_url: str profile_image_url: str

View file

@ -76,7 +76,6 @@ known_source_ext = [
"swift", "swift",
"vue", "vue",
"svelte", "svelte",
"msg",
"ex", "ex",
"exs", "exs",
"erl", "erl",
@ -147,15 +146,12 @@ class DoclingLoader:
) )
} }
params = { params = {"image_export_mode": "placeholder", "table_mode": "accurate"}
"image_export_mode": "placeholder",
"table_mode": "accurate",
}
if self.params: if self.params:
if self.params.get("do_picture_classification"): if self.params.get("do_picture_description"):
params["do_picture_classification"] = self.params.get( params["do_picture_description"] = self.params.get(
"do_picture_classification" "do_picture_description"
) )
if self.params.get("ocr_engine") and self.params.get("ocr_lang"): if self.params.get("ocr_engine") and self.params.get("ocr_lang"):
@ -292,7 +288,7 @@ class Loader:
params={ params={
"ocr_engine": self.kwargs.get("DOCLING_OCR_ENGINE"), "ocr_engine": self.kwargs.get("DOCLING_OCR_ENGINE"),
"ocr_lang": self.kwargs.get("DOCLING_OCR_LANG"), "ocr_lang": self.kwargs.get("DOCLING_OCR_LANG"),
"do_picture_classification": self.kwargs.get( "do_picture_description": self.kwargs.get(
"DOCLING_DO_PICTURE_DESCRIPTION" "DOCLING_DO_PICTURE_DESCRIPTION"
), ),
}, },

View file

@ -20,6 +20,14 @@ class MistralLoader:
""" """
Enhanced Mistral OCR loader with both sync and async support. Enhanced Mistral OCR loader with both sync and async support.
Loads documents by processing them through the Mistral OCR API. Loads documents by processing them through the Mistral OCR API.
Performance Optimizations:
- Differentiated timeouts for different operations
- Intelligent retry logic with exponential backoff
- Memory-efficient file streaming for large files
- Connection pooling and keepalive optimization
- Semaphore-based concurrency control for batch processing
- Enhanced error handling with retryable error classification
""" """
BASE_API_URL = "https://api.mistral.ai/v1" BASE_API_URL = "https://api.mistral.ai/v1"
@ -53,17 +61,40 @@ class MistralLoader:
self.max_retries = max_retries self.max_retries = max_retries
self.debug = enable_debug_logging self.debug = enable_debug_logging
# Pre-compute file info for performance # PERFORMANCE OPTIMIZATION: Differentiated timeouts for different operations
# This prevents long-running OCR operations from affecting quick operations
# and improves user experience by failing fast on operations that should be quick
self.upload_timeout = min(
timeout, 120
) # Cap upload at 2 minutes - prevents hanging on large files
self.url_timeout = (
30 # URL requests should be fast - fail quickly if API is slow
)
self.ocr_timeout = (
timeout # OCR can take the full timeout - this is the heavy operation
)
self.cleanup_timeout = (
30 # Cleanup should be quick - don't hang on file deletion
)
# PERFORMANCE OPTIMIZATION: Pre-compute file info to avoid repeated filesystem calls
# This avoids multiple os.path.basename() and os.path.getsize() calls during processing
self.file_name = os.path.basename(file_path) self.file_name = os.path.basename(file_path)
self.file_size = os.path.getsize(file_path) self.file_size = os.path.getsize(file_path)
# ENHANCEMENT: Added User-Agent for better API tracking and debugging
self.headers = { self.headers = {
"Authorization": f"Bearer {self.api_key}", "Authorization": f"Bearer {self.api_key}",
"User-Agent": "OpenWebUI-MistralLoader/2.0", "User-Agent": "OpenWebUI-MistralLoader/2.0", # Helps API provider track usage
} }
def _debug_log(self, message: str, *args) -> None: def _debug_log(self, message: str, *args) -> None:
"""Conditional debug logging for performance.""" """
PERFORMANCE OPTIMIZATION: Conditional debug logging for performance.
Only processes debug messages when debug mode is enabled, avoiding
string formatting overhead in production environments.
"""
if self.debug: if self.debug:
log.debug(message, *args) log.debug(message, *args)
@ -115,53 +146,118 @@ class MistralLoader:
log.error(f"Unexpected error processing response: {e}") log.error(f"Unexpected error processing response: {e}")
raise raise
def _is_retryable_error(self, error: Exception) -> bool:
"""
ENHANCEMENT: Intelligent error classification for retry logic.
Determines if an error is retryable based on its type and status code.
This prevents wasting time retrying errors that will never succeed
(like authentication errors) while ensuring transient errors are retried.
Retryable errors:
- Network connection errors (temporary network issues)
- Timeouts (server might be temporarily overloaded)
- Server errors (5xx status codes - server-side issues)
- Rate limiting (429 status - temporary throttling)
Non-retryable errors:
- Authentication errors (401, 403 - won't fix with retry)
- Bad request errors (400 - malformed request)
- Not found errors (404 - resource doesn't exist)
"""
if isinstance(error, requests.exceptions.ConnectionError):
return True # Network issues are usually temporary
if isinstance(error, requests.exceptions.Timeout):
return True # Timeouts might resolve on retry
if isinstance(error, requests.exceptions.HTTPError):
# Only retry on server errors (5xx) or rate limits (429)
if hasattr(error, "response") and error.response is not None:
status_code = error.response.status_code
return status_code >= 500 or status_code == 429
return False
if isinstance(
error, (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError)
):
return True # Async network/timeout errors are retryable
if isinstance(error, aiohttp.ClientResponseError):
return error.status >= 500 or error.status == 429
return False # All other errors are non-retryable
def _retry_request_sync(self, request_func, *args, **kwargs): def _retry_request_sync(self, request_func, *args, **kwargs):
"""Synchronous retry logic with exponential backoff.""" """
ENHANCEMENT: Synchronous retry logic with intelligent error classification.
Uses exponential backoff with jitter to avoid thundering herd problems.
The wait time increases exponentially but is capped at 30 seconds to
prevent excessive delays. Only retries errors that are likely to succeed
on subsequent attempts.
"""
for attempt in range(self.max_retries): for attempt in range(self.max_retries):
try: try:
return request_func(*args, **kwargs) return request_func(*args, **kwargs)
except (requests.exceptions.RequestException, Exception) as e: except Exception as e:
if attempt == self.max_retries - 1: if attempt == self.max_retries - 1 or not self._is_retryable_error(e):
raise raise
wait_time = (2**attempt) + 0.5 # PERFORMANCE OPTIMIZATION: Exponential backoff with cap
# Prevents overwhelming the server while ensuring reasonable retry delays
wait_time = min((2**attempt) + 0.5, 30) # Cap at 30 seconds
log.warning( log.warning(
f"Request failed (attempt {attempt + 1}/{self.max_retries}): {e}. Retrying in {wait_time}s..." f"Retryable error (attempt {attempt + 1}/{self.max_retries}): {e}. "
f"Retrying in {wait_time}s..."
) )
time.sleep(wait_time) time.sleep(wait_time)
async def _retry_request_async(self, request_func, *args, **kwargs): async def _retry_request_async(self, request_func, *args, **kwargs):
"""Async retry logic with exponential backoff.""" """
ENHANCEMENT: Async retry logic with intelligent error classification.
Async version of retry logic that doesn't block the event loop during
wait periods. Uses the same exponential backoff strategy as sync version.
"""
for attempt in range(self.max_retries): for attempt in range(self.max_retries):
try: try:
return await request_func(*args, **kwargs) return await request_func(*args, **kwargs)
except (aiohttp.ClientError, asyncio.TimeoutError) as e: except Exception as e:
if attempt == self.max_retries - 1: if attempt == self.max_retries - 1 or not self._is_retryable_error(e):
raise raise
wait_time = (2**attempt) + 0.5 # PERFORMANCE OPTIMIZATION: Non-blocking exponential backoff
wait_time = min((2**attempt) + 0.5, 30) # Cap at 30 seconds
log.warning( log.warning(
f"Request failed (attempt {attempt + 1}/{self.max_retries}): {e}. Retrying in {wait_time}s..." f"Retryable error (attempt {attempt + 1}/{self.max_retries}): {e}. "
f"Retrying in {wait_time}s..."
) )
await asyncio.sleep(wait_time) await asyncio.sleep(wait_time) # Non-blocking wait
def _upload_file(self) -> str: def _upload_file(self) -> str:
"""Uploads the file to Mistral for OCR processing (sync version).""" """
PERFORMANCE OPTIMIZATION: Enhanced file upload with streaming consideration.
Uploads the file to Mistral for OCR processing (sync version).
Uses context manager for file handling to ensure proper resource cleanup.
Although streaming is not enabled for this endpoint, the file is opened
in a context manager to minimize memory usage duration.
"""
log.info("Uploading file to Mistral API") log.info("Uploading file to Mistral API")
url = f"{self.BASE_API_URL}/files" url = f"{self.BASE_API_URL}/files"
file_name = os.path.basename(self.file_path)
def upload_request(): def upload_request():
# MEMORY OPTIMIZATION: Use context manager to minimize file handle lifetime
# This ensures the file is closed immediately after reading, reducing memory usage
with open(self.file_path, "rb") as f: with open(self.file_path, "rb") as f:
files = {"file": (file_name, f, "application/pdf")} files = {"file": (self.file_name, f, "application/pdf")}
data = {"purpose": "ocr"} data = {"purpose": "ocr"}
# NOTE: stream=False is required for this endpoint
# The Mistral API doesn't support chunked uploads for this endpoint
response = requests.post( response = requests.post(
url, url,
headers=self.headers, headers=self.headers,
files=files, files=files,
data=data, data=data,
timeout=self.timeout, timeout=self.upload_timeout, # Use specialized upload timeout
stream=False, # Keep as False for this endpoint
) )
return self._handle_response(response) return self._handle_response(response)
@ -209,7 +305,7 @@ class MistralLoader:
url, url,
data=writer, data=writer,
headers=self.headers, headers=self.headers,
timeout=aiohttp.ClientTimeout(total=self.timeout), timeout=aiohttp.ClientTimeout(total=self.upload_timeout),
) as response: ) as response:
return await self._handle_response_async(response) return await self._handle_response_async(response)
@ -231,7 +327,7 @@ class MistralLoader:
def url_request(): def url_request():
response = requests.get( response = requests.get(
url, headers=signed_url_headers, params=params, timeout=self.timeout url, headers=signed_url_headers, params=params, timeout=self.url_timeout
) )
return self._handle_response(response) return self._handle_response(response)
@ -261,7 +357,7 @@ class MistralLoader:
url, url,
headers=headers, headers=headers,
params=params, params=params,
timeout=aiohttp.ClientTimeout(total=self.timeout), timeout=aiohttp.ClientTimeout(total=self.url_timeout),
) as response: ) as response:
return await self._handle_response_async(response) return await self._handle_response_async(response)
@ -294,7 +390,7 @@ class MistralLoader:
def ocr_request(): def ocr_request():
response = requests.post( response = requests.post(
url, headers=ocr_headers, json=payload, timeout=self.timeout url, headers=ocr_headers, json=payload, timeout=self.ocr_timeout
) )
return self._handle_response(response) return self._handle_response(response)
@ -336,7 +432,7 @@ class MistralLoader:
url, url,
json=payload, json=payload,
headers=headers, headers=headers,
timeout=aiohttp.ClientTimeout(total=self.timeout), timeout=aiohttp.ClientTimeout(total=self.ocr_timeout),
) as response: ) as response:
ocr_response = await self._handle_response_async(response) ocr_response = await self._handle_response_async(response)
@ -353,7 +449,9 @@ class MistralLoader:
url = f"{self.BASE_API_URL}/files/{file_id}" url = f"{self.BASE_API_URL}/files/{file_id}"
try: try:
response = requests.delete(url, headers=self.headers, timeout=30) response = requests.delete(
url, headers=self.headers, timeout=self.cleanup_timeout
)
delete_response = self._handle_response(response) delete_response = self._handle_response(response)
log.info(f"File deleted successfully: {delete_response}") log.info(f"File deleted successfully: {delete_response}")
except Exception as e: except Exception as e:
@ -372,7 +470,7 @@ class MistralLoader:
url=f"{self.BASE_API_URL}/files/{file_id}", url=f"{self.BASE_API_URL}/files/{file_id}",
headers=self.headers, headers=self.headers,
timeout=aiohttp.ClientTimeout( timeout=aiohttp.ClientTimeout(
total=30 total=self.cleanup_timeout
), # Shorter timeout for cleanup ), # Shorter timeout for cleanup
) as response: ) as response:
return await self._handle_response_async(response) return await self._handle_response_async(response)
@ -388,29 +486,39 @@ class MistralLoader:
async def _get_session(self): async def _get_session(self):
"""Context manager for HTTP session with optimized settings.""" """Context manager for HTTP session with optimized settings."""
connector = aiohttp.TCPConnector( connector = aiohttp.TCPConnector(
limit=10, # Total connection limit limit=20, # Increased total connection limit for better throughput
limit_per_host=5, # Per-host connection limit limit_per_host=10, # Increased per-host limit for API endpoints
ttl_dns_cache=300, # DNS cache TTL ttl_dns_cache=600, # Longer DNS cache TTL (10 minutes)
use_dns_cache=True, use_dns_cache=True,
keepalive_timeout=30, keepalive_timeout=60, # Increased keepalive for connection reuse
enable_cleanup_closed=True, enable_cleanup_closed=True,
force_close=False, # Allow connection reuse
resolver=aiohttp.AsyncResolver(), # Use async DNS resolver
)
timeout = aiohttp.ClientTimeout(
total=self.timeout,
connect=30, # Connection timeout
sock_read=60, # Socket read timeout
) )
async with aiohttp.ClientSession( async with aiohttp.ClientSession(
connector=connector, connector=connector,
timeout=aiohttp.ClientTimeout(total=self.timeout), timeout=timeout,
headers={"User-Agent": "OpenWebUI-MistralLoader/2.0"}, headers={"User-Agent": "OpenWebUI-MistralLoader/2.0"},
raise_for_status=False, # We handle status codes manually
) as session: ) as session:
yield session yield session
def _process_results(self, ocr_response: Dict[str, Any]) -> List[Document]: def _process_results(self, ocr_response: Dict[str, Any]) -> List[Document]:
"""Process OCR results into Document objects with enhanced metadata.""" """Process OCR results into Document objects with enhanced metadata and memory efficiency."""
pages_data = ocr_response.get("pages") pages_data = ocr_response.get("pages")
if not pages_data: if not pages_data:
log.warning("No pages found in OCR response.") log.warning("No pages found in OCR response.")
return [ return [
Document( Document(
page_content="No text content found", metadata={"error": "no_pages"} page_content="No text content found",
metadata={"error": "no_pages", "file_name": self.file_name},
) )
] ]
@ -418,41 +526,44 @@ class MistralLoader:
total_pages = len(pages_data) total_pages = len(pages_data)
skipped_pages = 0 skipped_pages = 0
# Process pages in a memory-efficient way
for page_data in pages_data: for page_data in pages_data:
page_content = page_data.get("markdown") page_content = page_data.get("markdown")
page_index = page_data.get("index") # API uses 0-based index page_index = page_data.get("index") # API uses 0-based index
if page_content is not None and page_index is not None: if page_content is None or page_index is None:
# Clean up content efficiently skipped_pages += 1
cleaned_content = ( self._debug_log(
page_content.strip() f"Skipping page due to missing 'markdown' or 'index'. Data keys: {list(page_data.keys())}"
if isinstance(page_content, str)
else str(page_content)
) )
continue
if cleaned_content: # Only add non-empty pages # Clean up content efficiently with early exit for empty content
if isinstance(page_content, str):
cleaned_content = page_content.strip()
else:
cleaned_content = str(page_content).strip()
if not cleaned_content:
skipped_pages += 1
self._debug_log(f"Skipping empty page {page_index}")
continue
# Create document with optimized metadata
documents.append( documents.append(
Document( Document(
page_content=cleaned_content, page_content=cleaned_content,
metadata={ metadata={
"page": page_index, # 0-based index from API "page": page_index, # 0-based index from API
"page_label": page_index "page_label": page_index + 1, # 1-based label for convenience
+ 1, # 1-based label for convenience
"total_pages": total_pages, "total_pages": total_pages,
"file_name": self.file_name, "file_name": self.file_name,
"file_size": self.file_size, "file_size": self.file_size,
"processing_engine": "mistral-ocr", "processing_engine": "mistral-ocr",
"content_length": len(cleaned_content),
}, },
) )
) )
else:
skipped_pages += 1
self._debug_log(f"Skipping empty page {page_index}")
else:
skipped_pages += 1
self._debug_log(
f"Skipping page due to missing 'markdown' or 'index'. Data: {page_data}"
)
if skipped_pages > 0: if skipped_pages > 0:
log.info( log.info(
@ -467,7 +578,11 @@ class MistralLoader:
return [ return [
Document( Document(
page_content="No valid text content found in document", page_content="No valid text content found in document",
metadata={"error": "no_valid_pages", "total_pages": total_pages}, metadata={
"error": "no_valid_pages",
"total_pages": total_pages,
"file_name": self.file_name,
},
) )
] ]
@ -585,12 +700,14 @@ class MistralLoader:
@staticmethod @staticmethod
async def load_multiple_async( async def load_multiple_async(
loaders: List["MistralLoader"], loaders: List["MistralLoader"],
max_concurrent: int = 5, # Limit concurrent requests
) -> List[List[Document]]: ) -> List[List[Document]]:
""" """
Process multiple files concurrently for maximum performance. Process multiple files concurrently with controlled concurrency.
Args: Args:
loaders: List of MistralLoader instances loaders: List of MistralLoader instances
max_concurrent: Maximum number of concurrent requests
Returns: Returns:
List of document lists, one for each loader List of document lists, one for each loader
@ -598,11 +715,20 @@ class MistralLoader:
if not loaders: if not loaders:
return [] return []
log.info(f"Starting concurrent processing of {len(loaders)} files") log.info(
f"Starting concurrent processing of {len(loaders)} files with max {max_concurrent} concurrent"
)
start_time = time.time() start_time = time.time()
# Process all files concurrently # Use semaphore to control concurrency
tasks = [loader.load_async() for loader in loaders] semaphore = asyncio.Semaphore(max_concurrent)
async def process_with_semaphore(loader: "MistralLoader") -> List[Document]:
async with semaphore:
return await loader.load_async()
# Process all files with controlled concurrency
tasks = [process_with_semaphore(loader) for loader in loaders]
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(*tasks, return_exceptions=True)
# Handle any exceptions in results # Handle any exceptions in results
@ -624,10 +750,18 @@ class MistralLoader:
else: else:
processed_results.append(result) processed_results.append(result)
# MONITORING: Log comprehensive batch processing statistics
total_time = time.time() - start_time total_time = time.time() - start_time
total_docs = sum(len(docs) for docs in processed_results) total_docs = sum(len(docs) for docs in processed_results)
success_count = sum(
1 for result in results if not isinstance(result, Exception)
)
failure_count = len(results) - success_count
log.info( log.info(
f"Batch processing completed in {total_time:.2f}s, produced {total_docs} total documents" f"Batch processing completed in {total_time:.2f}s: "
f"{success_count} files succeeded, {failure_count} files failed, "
f"produced {total_docs} total documents"
) )
return processed_results return processed_results

View file

@ -3,10 +3,19 @@ import logging
import time # for measuring elapsed time import time # for measuring elapsed time
from pinecone import Pinecone, ServerlessSpec from pinecone import Pinecone, ServerlessSpec
# Add gRPC support for better performance (Pinecone best practice)
try:
from pinecone.grpc import PineconeGRPC
GRPC_AVAILABLE = True
except ImportError:
GRPC_AVAILABLE = False
import asyncio # for async upserts import asyncio # for async upserts
import functools # for partial binding in async tasks import functools # for partial binding in async tasks
import concurrent.futures # for parallel batch upserts import concurrent.futures # for parallel batch upserts
import random # for jitter in retry backoff
from open_webui.retrieval.vector.main import ( from open_webui.retrieval.vector.main import (
VectorDBBase, VectorDBBase,
@ -47,7 +56,24 @@ class PineconeClient(VectorDBBase):
self.cloud = PINECONE_CLOUD self.cloud = PINECONE_CLOUD
# Initialize Pinecone client for improved performance # Initialize Pinecone client for improved performance
self.client = Pinecone(api_key=self.api_key) if GRPC_AVAILABLE:
# Use gRPC client for better performance (Pinecone recommendation)
self.client = PineconeGRPC(
api_key=self.api_key,
pool_threads=20, # Improved connection pool size
timeout=30, # Reasonable timeout for operations
)
self.using_grpc = True
log.info("Using Pinecone gRPC client for optimal performance")
else:
# Fallback to HTTP client with enhanced connection pooling
self.client = Pinecone(
api_key=self.api_key,
pool_threads=20, # Improved connection pool size
timeout=30, # Reasonable timeout for operations
)
self.using_grpc = False
log.info("Using Pinecone HTTP client (gRPC not available)")
# Persistent executor for batch operations # Persistent executor for batch operations
self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=5) self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
@ -91,12 +117,53 @@ class PineconeClient(VectorDBBase):
log.info(f"Using existing Pinecone index '{self.index_name}'") log.info(f"Using existing Pinecone index '{self.index_name}'")
# Connect to the index # Connect to the index
self.index = self.client.Index(self.index_name) self.index = self.client.Index(
self.index_name,
pool_threads=20, # Enhanced connection pool for index operations
)
except Exception as e: except Exception as e:
log.error(f"Failed to initialize Pinecone index: {e}") log.error(f"Failed to initialize Pinecone index: {e}")
raise RuntimeError(f"Failed to initialize Pinecone index: {e}") raise RuntimeError(f"Failed to initialize Pinecone index: {e}")
def _retry_pinecone_operation(self, operation_func, max_retries=3):
"""Retry Pinecone operations with exponential backoff for rate limits and network issues."""
for attempt in range(max_retries):
try:
return operation_func()
except Exception as e:
error_str = str(e).lower()
# Check if it's a retryable error (rate limits, network issues, timeouts)
is_retryable = any(
keyword in error_str
for keyword in [
"rate limit",
"quota",
"timeout",
"network",
"connection",
"unavailable",
"internal error",
"429",
"500",
"502",
"503",
"504",
]
)
if not is_retryable or attempt == max_retries - 1:
# Don't retry for non-retryable errors or on final attempt
raise
# Exponential backoff with jitter
delay = (2**attempt) + random.uniform(0, 1)
log.warning(
f"Pinecone operation failed (attempt {attempt + 1}/{max_retries}), "
f"retrying in {delay:.2f}s: {e}"
)
time.sleep(delay)
def _create_points( def _create_points(
self, items: List[VectorItem], collection_name_with_prefix: str self, items: List[VectorItem], collection_name_with_prefix: str
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
@ -223,7 +290,8 @@ class PineconeClient(VectorDBBase):
elapsed = time.time() - start_time elapsed = time.time() - start_time
log.debug(f"Insert of {len(points)} vectors took {elapsed:.2f} seconds") log.debug(f"Insert of {len(points)} vectors took {elapsed:.2f} seconds")
log.info( log.info(
f"Successfully inserted {len(points)} vectors in parallel batches into '{collection_name_with_prefix}'" f"Successfully inserted {len(points)} vectors in parallel batches "
f"into '{collection_name_with_prefix}'"
) )
def upsert(self, collection_name: str, items: List[VectorItem]) -> None: def upsert(self, collection_name: str, items: List[VectorItem]) -> None:
@ -254,7 +322,8 @@ class PineconeClient(VectorDBBase):
elapsed = time.time() - start_time elapsed = time.time() - start_time
log.debug(f"Upsert of {len(points)} vectors took {elapsed:.2f} seconds") log.debug(f"Upsert of {len(points)} vectors took {elapsed:.2f} seconds")
log.info( log.info(
f"Successfully upserted {len(points)} vectors in parallel batches into '{collection_name_with_prefix}'" f"Successfully upserted {len(points)} vectors in parallel batches "
f"into '{collection_name_with_prefix}'"
) )
async def insert_async(self, collection_name: str, items: List[VectorItem]) -> None: async def insert_async(self, collection_name: str, items: List[VectorItem]) -> None:
@ -285,7 +354,8 @@ class PineconeClient(VectorDBBase):
log.error(f"Error in async insert batch: {result}") log.error(f"Error in async insert batch: {result}")
raise result raise result
log.info( log.info(
f"Successfully async inserted {len(points)} vectors in batches into '{collection_name_with_prefix}'" f"Successfully async inserted {len(points)} vectors in batches "
f"into '{collection_name_with_prefix}'"
) )
async def upsert_async(self, collection_name: str, items: List[VectorItem]) -> None: async def upsert_async(self, collection_name: str, items: List[VectorItem]) -> None:
@ -316,7 +386,8 @@ class PineconeClient(VectorDBBase):
log.error(f"Error in async upsert batch: {result}") log.error(f"Error in async upsert batch: {result}")
raise result raise result
log.info( log.info(
f"Successfully async upserted {len(points)} vectors in batches into '{collection_name_with_prefix}'" f"Successfully async upserted {len(points)} vectors in batches "
f"into '{collection_name_with_prefix}'"
) )
def search( def search(
@ -457,10 +528,12 @@ class PineconeClient(VectorDBBase):
# This is a limitation of Pinecone - be careful with ID uniqueness # This is a limitation of Pinecone - be careful with ID uniqueness
self.index.delete(ids=batch_ids) self.index.delete(ids=batch_ids)
log.debug( log.debug(
f"Deleted batch of {len(batch_ids)} vectors by ID from '{collection_name_with_prefix}'" f"Deleted batch of {len(batch_ids)} vectors by ID "
f"from '{collection_name_with_prefix}'"
) )
log.info( log.info(
f"Successfully deleted {len(ids)} vectors by ID from '{collection_name_with_prefix}'" f"Successfully deleted {len(ids)} vectors by ID "
f"from '{collection_name_with_prefix}'"
) )
elif filter: elif filter:

View file

@ -1,10 +1,20 @@
import logging import logging
from typing import Optional, List from typing import Optional, Literal
import requests import requests
from open_webui.retrieval.web.main import SearchResult, get_filtered_results from open_webui.retrieval.web.main import SearchResult, get_filtered_results
from open_webui.env import SRC_LOG_LEVELS from open_webui.env import SRC_LOG_LEVELS
MODELS = Literal[
"sonar",
"sonar-pro",
"sonar-reasoning",
"sonar-reasoning-pro",
"sonar-deep-research",
]
SEARCH_CONTEXT_USAGE_LEVELS = Literal["low", "medium", "high"]
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["RAG"]) log.setLevel(SRC_LOG_LEVELS["RAG"])
@ -14,6 +24,8 @@ def search_perplexity(
query: str, query: str,
count: int, count: int,
filter_list: Optional[list[str]] = None, filter_list: Optional[list[str]] = None,
model: MODELS = "sonar",
search_context_usage: SEARCH_CONTEXT_USAGE_LEVELS = "medium",
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using Perplexity API and return the results as a list of SearchResult objects. """Search using Perplexity API and return the results as a list of SearchResult objects.
@ -21,6 +33,9 @@ def search_perplexity(
api_key (str): A Perplexity API key api_key (str): A Perplexity API key
query (str): The query to search for query (str): The query to search for
count (int): Maximum number of results to return count (int): Maximum number of results to return
filter_list (Optional[list[str]]): List of domains to filter results
model (str): The Perplexity model to use (sonar, sonar-pro)
search_context_usage (str): Search context usage level (low, medium, high)
""" """
@ -33,7 +48,7 @@ def search_perplexity(
# Create payload for the API call # Create payload for the API call
payload = { payload = {
"model": "sonar", "model": model,
"messages": [ "messages": [
{ {
"role": "system", "role": "system",
@ -43,6 +58,9 @@ def search_perplexity(
], ],
"temperature": 0.2, # Lower temperature for more factual responses "temperature": 0.2, # Lower temperature for more factual responses
"stream": False, "stream": False,
"web_search_options": {
"search_context_usage": search_context_usage,
},
} }
headers = { headers = {

View file

@ -124,9 +124,8 @@ async def get_note_by_id(request: Request, id: str, user=Depends(get_verified_us
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
) )
if ( if user.role != "admin" or (
user.role != "admin" user.id != note.user_id
and user.id != note.user_id
and not has_access(user.id, type="read", access_control=note.access_control) and not has_access(user.id, type="read", access_control=note.access_control)
): ):
raise HTTPException( raise HTTPException(
@ -159,9 +158,8 @@ async def update_note_by_id(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
) )
if ( if user.role != "admin" or (
user.role != "admin" user.id != note.user_id
and user.id != note.user_id
and not has_access(user.id, type="write", access_control=note.access_control) and not has_access(user.id, type="write", access_control=note.access_control)
): ):
raise HTTPException( raise HTTPException(
@ -199,9 +197,8 @@ async def delete_note_by_id(request: Request, id: str, user=Depends(get_verified
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
) )
if ( if user.role != "admin" or (
user.role != "admin" user.id != note.user_id
and user.id != note.user_id
and not has_access(user.id, type="write", access_control=note.access_control) and not has_access(user.id, type="write", access_control=note.access_control)
): ):
raise HTTPException( raise HTTPException(

View file

@ -887,6 +887,88 @@ async def generate_chat_completion(
await session.close() await session.close()
async def embeddings(request: Request, form_data: dict, user):
"""
Calls the embeddings endpoint for OpenAI-compatible providers.
Args:
request (Request): The FastAPI request context.
form_data (dict): OpenAI-compatible embeddings payload.
user (UserModel): The authenticated user.
Returns:
dict: OpenAI-compatible embeddings response.
"""
idx = 0
# Prepare payload/body
body = json.dumps(form_data)
# Find correct backend url/key based on model
await get_all_models(request, user=user)
model_id = form_data.get("model")
models = request.app.state.OPENAI_MODELS
if model_id in models:
idx = models[model_id]["urlIdx"]
url = request.app.state.config.OPENAI_API_BASE_URLS[idx]
key = request.app.state.config.OPENAI_API_KEYS[idx]
r = None
session = None
streaming = False
try:
session = aiohttp.ClientSession(trust_env=True)
r = await session.request(
method="POST",
url=f"{url}/embeddings",
data=body,
headers={
"Authorization": f"Bearer {key}",
"Content-Type": "application/json",
**(
{
"X-OpenWebUI-User-Name": user.name,
"X-OpenWebUI-User-Id": user.id,
"X-OpenWebUI-User-Email": user.email,
"X-OpenWebUI-User-Role": user.role,
}
if ENABLE_FORWARD_USER_INFO_HEADERS and user
else {}
),
},
)
r.raise_for_status()
if "text/event-stream" in r.headers.get("Content-Type", ""):
streaming = True
return StreamingResponse(
r.content,
status_code=r.status,
headers=dict(r.headers),
background=BackgroundTask(
cleanup_response, response=r, session=session
),
)
else:
response_data = await r.json()
return response_data
except Exception as e:
log.exception(e)
detail = None
if r is not None:
try:
res = await r.json()
if "error" in res:
detail = f"External: {res['error']['message'] if 'message' in res['error'] else res['error']}"
except Exception:
detail = f"External: {e}"
raise HTTPException(
status_code=r.status if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)
finally:
if not streaming and session:
if r:
r.close()
await session.close()
@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"]) @router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy(path: str, request: Request, user=Depends(get_verified_user)): async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
""" """

View file

@ -467,6 +467,8 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
"BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
"EXA_API_KEY": request.app.state.config.EXA_API_KEY, "EXA_API_KEY": request.app.state.config.EXA_API_KEY,
"PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY,
"PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL,
"PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE,
"SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID,
"SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK,
"WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE,
@ -520,6 +522,8 @@ class WebConfig(BaseModel):
BING_SEARCH_V7_SUBSCRIPTION_KEY: Optional[str] = None BING_SEARCH_V7_SUBSCRIPTION_KEY: Optional[str] = None
EXA_API_KEY: Optional[str] = None EXA_API_KEY: Optional[str] = None
PERPLEXITY_API_KEY: Optional[str] = None PERPLEXITY_API_KEY: Optional[str] = None
PERPLEXITY_MODEL: Optional[str] = None
PERPLEXITY_SEARCH_CONTEXT_USAGE: Optional[str] = None
SOUGOU_API_SID: Optional[str] = None SOUGOU_API_SID: Optional[str] = None
SOUGOU_API_SK: Optional[str] = None SOUGOU_API_SK: Optional[str] = None
WEB_LOADER_ENGINE: Optional[str] = None WEB_LOADER_ENGINE: Optional[str] = None
@ -907,6 +911,10 @@ async def update_rag_config(
) )
request.app.state.config.EXA_API_KEY = form_data.web.EXA_API_KEY request.app.state.config.EXA_API_KEY = form_data.web.EXA_API_KEY
request.app.state.config.PERPLEXITY_API_KEY = form_data.web.PERPLEXITY_API_KEY request.app.state.config.PERPLEXITY_API_KEY = form_data.web.PERPLEXITY_API_KEY
request.app.state.config.PERPLEXITY_MODEL = form_data.web.PERPLEXITY_MODEL
request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = (
form_data.web.PERPLEXITY_SEARCH_CONTEXT_USAGE
)
request.app.state.config.SOUGOU_API_SID = form_data.web.SOUGOU_API_SID request.app.state.config.SOUGOU_API_SID = form_data.web.SOUGOU_API_SID
request.app.state.config.SOUGOU_API_SK = form_data.web.SOUGOU_API_SK request.app.state.config.SOUGOU_API_SK = form_data.web.SOUGOU_API_SK
@ -1030,6 +1038,8 @@ async def update_rag_config(
"BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, "BING_SEARCH_V7_SUBSCRIPTION_KEY": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
"EXA_API_KEY": request.app.state.config.EXA_API_KEY, "EXA_API_KEY": request.app.state.config.EXA_API_KEY,
"PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY,
"PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL,
"PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE,
"SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID,
"SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK,
"WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE,
@ -1740,19 +1750,14 @@ def search_web(request: Request, engine: str, query: str) -> list[SearchResult]:
request.app.state.config.WEB_SEARCH_RESULT_COUNT, request.app.state.config.WEB_SEARCH_RESULT_COUNT,
request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST,
) )
elif engine == "exa":
return search_exa(
request.app.state.config.EXA_API_KEY,
query,
request.app.state.config.WEB_SEARCH_RESULT_COUNT,
request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST,
)
elif engine == "perplexity": elif engine == "perplexity":
return search_perplexity( return search_perplexity(
request.app.state.config.PERPLEXITY_API_KEY, request.app.state.config.PERPLEXITY_API_KEY,
query, query,
request.app.state.config.WEB_SEARCH_RESULT_COUNT, request.app.state.config.WEB_SEARCH_RESULT_COUNT,
request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST,
model=request.app.state.config.PERPLEXITY_MODEL,
search_context_usage=request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE,
) )
elif engine == "sougou": elif engine == "sougou":
if ( if (

View file

@ -9,6 +9,7 @@ import re
from open_webui.utils.chat import generate_chat_completion from open_webui.utils.chat import generate_chat_completion
from open_webui.utils.task import ( from open_webui.utils.task import (
title_generation_template, title_generation_template,
follow_up_generation_template,
query_generation_template, query_generation_template,
image_prompt_generation_template, image_prompt_generation_template,
autocomplete_generation_template, autocomplete_generation_template,
@ -25,6 +26,7 @@ from open_webui.utils.task import get_task_model_id
from open_webui.config import ( from open_webui.config import (
DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE, DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE,
DEFAULT_FOLLOW_UP_GENERATION_PROMPT_TEMPLATE,
DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE, DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE,
DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE,
DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE, DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE,
@ -58,6 +60,8 @@ async def get_task_config(request: Request, user=Depends(get_verified_user)):
"ENABLE_AUTOCOMPLETE_GENERATION": request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION, "ENABLE_AUTOCOMPLETE_GENERATION": request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION,
"AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH, "AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH,
"TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE, "TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE,
"FOLLOW_UP_GENERATION_PROMPT_TEMPLATE": request.app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE,
"ENABLE_FOLLOW_UP_GENERATION": request.app.state.config.ENABLE_FOLLOW_UP_GENERATION,
"ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION, "ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION,
"ENABLE_TITLE_GENERATION": request.app.state.config.ENABLE_TITLE_GENERATION, "ENABLE_TITLE_GENERATION": request.app.state.config.ENABLE_TITLE_GENERATION,
"ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION, "ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION,
@ -76,6 +80,8 @@ class TaskConfigForm(BaseModel):
ENABLE_AUTOCOMPLETE_GENERATION: bool ENABLE_AUTOCOMPLETE_GENERATION: bool
AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH: int AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH: int
TAGS_GENERATION_PROMPT_TEMPLATE: str TAGS_GENERATION_PROMPT_TEMPLATE: str
FOLLOW_UP_GENERATION_PROMPT_TEMPLATE: str
ENABLE_FOLLOW_UP_GENERATION: bool
ENABLE_TAGS_GENERATION: bool ENABLE_TAGS_GENERATION: bool
ENABLE_SEARCH_QUERY_GENERATION: bool ENABLE_SEARCH_QUERY_GENERATION: bool
ENABLE_RETRIEVAL_QUERY_GENERATION: bool ENABLE_RETRIEVAL_QUERY_GENERATION: bool
@ -94,6 +100,13 @@ async def update_task_config(
form_data.TITLE_GENERATION_PROMPT_TEMPLATE form_data.TITLE_GENERATION_PROMPT_TEMPLATE
) )
request.app.state.config.ENABLE_FOLLOW_UP_GENERATION = (
form_data.ENABLE_FOLLOW_UP_GENERATION
)
request.app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE = (
form_data.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE
)
request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = ( request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = (
form_data.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE form_data.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
) )
@ -133,6 +146,8 @@ async def update_task_config(
"AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH, "AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH,
"TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE, "TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE,
"ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION, "ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION,
"ENABLE_FOLLOW_UP_GENERATION": request.app.state.config.ENABLE_FOLLOW_UP_GENERATION,
"FOLLOW_UP_GENERATION_PROMPT_TEMPLATE": request.app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE,
"ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION, "ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION,
"ENABLE_RETRIEVAL_QUERY_GENERATION": request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION, "ENABLE_RETRIEVAL_QUERY_GENERATION": request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION,
"QUERY_GENERATION_PROMPT_TEMPLATE": request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE, "QUERY_GENERATION_PROMPT_TEMPLATE": request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE,
@ -231,6 +246,86 @@ async def generate_title(
) )
@router.post("/follow_up/completions")
async def generate_follow_ups(
request: Request, form_data: dict, user=Depends(get_verified_user)
):
if not request.app.state.config.ENABLE_FOLLOW_UP_GENERATION:
return JSONResponse(
status_code=status.HTTP_200_OK,
content={"detail": "Follow-up generation is disabled"},
)
if getattr(request.state, "direct", False) and hasattr(request.state, "model"):
models = {
request.state.model["id"]: request.state.model,
}
else:
models = request.app.state.MODELS
model_id = form_data["model"]
if model_id not in models:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Model not found",
)
# Check if the user has a custom task model
# If the user has a custom task model, use that model
task_model_id = get_task_model_id(
model_id,
request.app.state.config.TASK_MODEL,
request.app.state.config.TASK_MODEL_EXTERNAL,
models,
)
log.debug(
f"generating chat title using model {task_model_id} for user {user.email} "
)
if request.app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE != "":
template = request.app.state.config.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE
else:
template = DEFAULT_FOLLOW_UP_GENERATION_PROMPT_TEMPLATE
content = follow_up_generation_template(
template,
form_data["messages"],
{
"name": user.name,
"location": user.info.get("location") if user.info else None,
},
)
payload = {
"model": task_model_id,
"messages": [{"role": "user", "content": content}],
"stream": False,
"metadata": {
**(request.state.metadata if hasattr(request.state, "metadata") else {}),
"task": str(TASKS.FOLLOW_UP_GENERATION),
"task_body": form_data,
"chat_id": form_data.get("chat_id", None),
},
}
# Process the payload through the pipeline
try:
payload = await process_pipeline_inlet_filter(request, payload, user, models)
except Exception as e:
raise e
try:
return await generate_chat_completion(request, form_data=payload, user=user)
except Exception as e:
log.error("Exception occurred", exc_info=True)
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={"detail": "An internal error has occurred."},
)
@router.post("/tags/completions") @router.post("/tags/completions")
async def generate_chat_tags( async def generate_chat_tags(
request: Request, form_data: dict, user=Depends(get_verified_user) request: Request, form_data: dict, user=Depends(get_verified_user)

View file

@ -165,22 +165,6 @@ async def update_default_user_permissions(
return request.app.state.config.USER_PERMISSIONS return request.app.state.config.USER_PERMISSIONS
############################
# UpdateUserRole
############################
@router.post("/update/role", response_model=Optional[UserModel])
async def update_user_role(form_data: UserRoleUpdateForm, user=Depends(get_admin_user)):
if user.id != form_data.id and form_data.id != Users.get_first_user().id:
return Users.update_user_role_by_id(form_data.id, form_data.role)
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=ERROR_MESSAGES.ACTION_PROHIBITED,
)
############################ ############################
# GetUserSettingsBySessionUser # GetUserSettingsBySessionUser
############################ ############################
@ -333,11 +317,22 @@ async def update_user_by_id(
# Prevent modification of the primary admin user by other admins # Prevent modification of the primary admin user by other admins
try: try:
first_user = Users.get_first_user() first_user = Users.get_first_user()
if first_user and user_id == first_user.id and session_user.id != user_id: if first_user:
if user_id == first_user.id:
if session_user.id != user_id:
# If the user trying to update is the primary admin, and they are not the primary admin themselves
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, status_code=status.HTTP_403_FORBIDDEN,
detail=ERROR_MESSAGES.ACTION_PROHIBITED, detail=ERROR_MESSAGES.ACTION_PROHIBITED,
) )
if form_data.role != "admin":
# If the primary admin is trying to change their own role, prevent it
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=ERROR_MESSAGES.ACTION_PROHIBITED,
)
except Exception as e: except Exception as e:
log.error(f"Error checking primary admin status: {e}") log.error(f"Error checking primary admin status: {e}")
raise HTTPException( raise HTTPException(
@ -365,6 +360,7 @@ async def update_user_by_id(
updated_user = Users.update_user_by_id( updated_user = Users.update_user_by_id(
user_id, user_id,
{ {
"role": form_data.role,
"name": form_data.name, "name": form_data.name,
"email": form_data.email.lower(), "email": form_data.email.lower(),
"profile_image_url": form_data.profile_image_url, "profile_image_url": form_data.profile_image_url,

View file

@ -320,12 +320,7 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
extra_params = { extra_params = {
"__event_emitter__": get_event_emitter(metadata), "__event_emitter__": get_event_emitter(metadata),
"__event_call__": get_event_call(metadata), "__event_call__": get_event_call(metadata),
"__user__": { "__user__": user.model_dump() if isinstance(user, UserModel) else {},
"id": user.id,
"email": user.email,
"name": user.name,
"role": user.role,
},
"__metadata__": metadata, "__metadata__": metadata,
"__request__": request, "__request__": request,
"__model__": model, "__model__": model,
@ -424,12 +419,7 @@ async def chat_action(request: Request, action_id: str, form_data: dict, user: A
params[key] = value params[key] = value
if "__user__" in sig.parameters: if "__user__" in sig.parameters:
__user__ = { __user__ = (user.model_dump() if isinstance(user, UserModel) else {},)
"id": user.id,
"email": user.email,
"name": user.name,
"role": user.role,
}
try: try:
if hasattr(function_module, "UserValves"): if hasattr(function_module, "UserValves"):

View file

@ -0,0 +1,90 @@
import random
import logging
import sys
from fastapi import Request
from open_webui.models.users import UserModel
from open_webui.models.models import Models
from open_webui.utils.models import check_model_access
from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL
from open_webui.routers.openai import embeddings as openai_embeddings
from open_webui.routers.ollama import (
embeddings as ollama_embeddings,
GenerateEmbeddingsForm,
)
from open_webui.utils.payload import convert_embedding_payload_openai_to_ollama
from open_webui.utils.response import convert_embedding_response_ollama_to_openai
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MAIN"])
async def generate_embeddings(
request: Request,
form_data: dict,
user: UserModel,
bypass_filter: bool = False,
):
"""
Dispatch and handle embeddings generation based on the model type (OpenAI, Ollama).
Args:
request (Request): The FastAPI request context.
form_data (dict): The input data sent to the endpoint.
user (UserModel): The authenticated user.
bypass_filter (bool): If True, disables access filtering (default False).
Returns:
dict: The embeddings response, following OpenAI API compatibility.
"""
if BYPASS_MODEL_ACCESS_CONTROL:
bypass_filter = True
# Attach extra metadata from request.state if present
if hasattr(request.state, "metadata"):
if "metadata" not in form_data:
form_data["metadata"] = request.state.metadata
else:
form_data["metadata"] = {
**form_data["metadata"],
**request.state.metadata,
}
# If "direct" flag present, use only that model
if getattr(request.state, "direct", False) and hasattr(request.state, "model"):
models = {
request.state.model["id"]: request.state.model,
}
else:
models = request.app.state.MODELS
model_id = form_data.get("model")
if model_id not in models:
raise Exception("Model not found")
model = models[model_id]
# Access filtering
if not getattr(request.state, "direct", False):
if not bypass_filter and user.role == "user":
check_model_access(user, model)
# Ollama backend
if model.get("owned_by") == "ollama":
ollama_payload = convert_embedding_payload_openai_to_ollama(form_data)
response = await ollama_embeddings(
request=request,
form_data=GenerateEmbeddingsForm(**ollama_payload),
user=user,
)
return convert_embedding_response_ollama_to_openai(response)
# Default: OpenAI or compatible backend
return await openai_embeddings(
request=request,
form_data=form_data,
user=user,
)

View file

@ -32,6 +32,7 @@ from open_webui.socket.main import (
from open_webui.routers.tasks import ( from open_webui.routers.tasks import (
generate_queries, generate_queries,
generate_title, generate_title,
generate_follow_ups,
generate_image_prompt, generate_image_prompt,
generate_chat_tags, generate_chat_tags,
) )
@ -726,12 +727,7 @@ async def process_chat_payload(request, form_data, user, metadata, model):
extra_params = { extra_params = {
"__event_emitter__": event_emitter, "__event_emitter__": event_emitter,
"__event_call__": event_call, "__event_call__": event_call,
"__user__": { "__user__": user.model_dump() if isinstance(user, UserModel) else {},
"id": user.id,
"email": user.email,
"name": user.name,
"role": user.role,
},
"__metadata__": metadata, "__metadata__": metadata,
"__request__": request, "__request__": request,
"__model__": model, "__model__": model,
@ -1048,6 +1044,59 @@ async def process_chat_response(
) )
if tasks and messages: if tasks and messages:
if (
TASKS.FOLLOW_UP_GENERATION in tasks
and tasks[TASKS.FOLLOW_UP_GENERATION]
):
res = await generate_follow_ups(
request,
{
"model": message["model"],
"messages": messages,
"message_id": metadata["message_id"],
"chat_id": metadata["chat_id"],
},
user,
)
if res and isinstance(res, dict):
if len(res.get("choices", [])) == 1:
follow_ups_string = (
res.get("choices", [])[0]
.get("message", {})
.get("content", "")
)
else:
follow_ups_string = ""
follow_ups_string = follow_ups_string[
follow_ups_string.find("{") : follow_ups_string.rfind("}")
+ 1
]
try:
follow_ups = json.loads(follow_ups_string).get(
"follow_ups", []
)
Chats.upsert_message_to_chat_by_id_and_message_id(
metadata["chat_id"],
metadata["message_id"],
{
"followUps": follow_ups,
},
)
await event_emitter(
{
"type": "chat:message:follow_ups",
"data": {
"follow_ups": follow_ups,
},
}
)
except Exception as e:
pass
if TASKS.TITLE_GENERATION in tasks: if TASKS.TITLE_GENERATION in tasks:
if tasks[TASKS.TITLE_GENERATION]: if tasks[TASKS.TITLE_GENERATION]:
res = await generate_title( res = await generate_title(
@ -1273,12 +1322,7 @@ async def process_chat_response(
extra_params = { extra_params = {
"__event_emitter__": event_emitter, "__event_emitter__": event_emitter,
"__event_call__": event_caller, "__event_call__": event_caller,
"__user__": { "__user__": user.model_dump() if isinstance(user, UserModel) else {},
"id": user.id,
"email": user.email,
"name": user.name,
"role": user.role,
},
"__metadata__": metadata, "__metadata__": metadata,
"__request__": request, "__request__": request,
"__model__": model, "__model__": model,

View file

@ -538,7 +538,7 @@ class OAuthManager:
# Redirect back to the frontend with the JWT token # Redirect back to the frontend with the JWT token
redirect_base_url = request.app.state.config.WEBUI_URL or request.base_url redirect_base_url = request.app.state.config.WEBUI_URL or request.base_url
if redirect_base_url.endswith("/"): if isinstance(redirect_base_url, str) and redirect_base_url.endswith("/"):
redirect_base_url = redirect_base_url[:-1] redirect_base_url = redirect_base_url[:-1]
redirect_url = f"{redirect_base_url}/auth#token={jwt_token}" redirect_url = f"{redirect_base_url}/auth#token={jwt_token}"

View file

@ -329,3 +329,32 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict:
ollama_payload["format"] = format ollama_payload["format"] = format
return ollama_payload return ollama_payload
def convert_embedding_payload_openai_to_ollama(openai_payload: dict) -> dict:
"""
Convert an embeddings request payload from OpenAI format to Ollama format.
Args:
openai_payload (dict): The original payload designed for OpenAI API usage.
Returns:
dict: A payload compatible with the Ollama API embeddings endpoint.
"""
ollama_payload = {"model": openai_payload.get("model")}
input_value = openai_payload.get("input")
# Ollama expects 'input' as a list, and 'prompt' as a single string.
if isinstance(input_value, list):
ollama_payload["input"] = input_value
ollama_payload["prompt"] = "\n".join(str(x) for x in input_value)
else:
ollama_payload["input"] = [input_value]
ollama_payload["prompt"] = str(input_value)
# Optionally forward other fields if present
for optional_key in ("options", "truncate", "keep_alive"):
if optional_key in openai_payload:
ollama_payload[optional_key] = openai_payload[optional_key]
return ollama_payload

View file

@ -125,3 +125,64 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
yield line yield line
yield "data: [DONE]\n\n" yield "data: [DONE]\n\n"
def convert_embedding_response_ollama_to_openai(response) -> dict:
"""
Convert the response from Ollama embeddings endpoint to the OpenAI-compatible format.
Args:
response (dict): The response from the Ollama API,
e.g. {"embedding": [...], "model": "..."}
or {"embeddings": [{"embedding": [...], "index": 0}, ...], "model": "..."}
Returns:
dict: Response adapted to OpenAI's embeddings API format.
e.g. {
"object": "list",
"data": [
{"object": "embedding", "embedding": [...], "index": 0},
...
],
"model": "...",
}
"""
# Ollama batch-style output
if isinstance(response, dict) and "embeddings" in response:
openai_data = []
for i, emb in enumerate(response["embeddings"]):
openai_data.append(
{
"object": "embedding",
"embedding": emb.get("embedding"),
"index": emb.get("index", i),
}
)
return {
"object": "list",
"data": openai_data,
"model": response.get("model"),
}
# Ollama single output
elif isinstance(response, dict) and "embedding" in response:
return {
"object": "list",
"data": [
{
"object": "embedding",
"embedding": response["embedding"],
"index": 0,
}
],
"model": response.get("model"),
}
# Already OpenAI-compatible?
elif (
isinstance(response, dict)
and "data" in response
and isinstance(response["data"], list)
):
return response
# Fallback: return as is if unrecognized
return response

View file

@ -207,6 +207,24 @@ def title_generation_template(
return template return template
def follow_up_generation_template(
template: str, messages: list[dict], user: Optional[dict] = None
) -> str:
prompt = get_last_user_message(messages)
template = replace_prompt_variable(template, prompt)
template = replace_messages_variable(template, messages)
template = prompt_template(
template,
**(
{"user_name": user.get("name"), "user_location": user.get("location")}
if user
else {}
),
)
return template
def tags_generation_template( def tags_generation_template(
template: str, messages: list[dict], user: Optional[dict] = None template: str, messages: list[dict], user: Optional[dict] = None
) -> str: ) -> str:

View file

@ -1,5 +1,5 @@
fastapi==0.115.7 fastapi==0.115.7
uvicorn[standard]==0.34.0 uvicorn[standard]==0.34.2
pydantic==2.10.6 pydantic==2.10.6
python-multipart==0.0.20 python-multipart==0.0.20
@ -76,13 +76,13 @@ pandas==2.2.3
openpyxl==3.1.5 openpyxl==3.1.5
pyxlsb==1.0.10 pyxlsb==1.0.10
xlrd==2.0.1 xlrd==2.0.1
validators==0.34.0 validators==0.35.0
psutil psutil
sentencepiece sentencepiece
soundfile==0.13.1 soundfile==0.13.1
azure-ai-documentintelligence==1.0.0 azure-ai-documentintelligence==1.0.2
pillow==11.1.0 pillow==11.2.1
opencv-python-headless==4.11.0.86 opencv-python-headless==4.11.0.86
rapidocr-onnxruntime==1.4.4 rapidocr-onnxruntime==1.4.4
rank-bm25==0.2.2 rank-bm25==0.2.2

8
package-lock.json generated
View file

@ -51,7 +51,7 @@
"idb": "^7.1.1", "idb": "^7.1.1",
"js-sha256": "^0.10.1", "js-sha256": "^0.10.1",
"jspdf": "^3.0.0", "jspdf": "^3.0.0",
"katex": "^0.16.21", "katex": "^0.16.22",
"kokoro-js": "^1.1.1", "kokoro-js": "^1.1.1",
"marked": "^9.1.0", "marked": "^9.1.0",
"mermaid": "^11.6.0", "mermaid": "^11.6.0",
@ -7930,9 +7930,9 @@
} }
}, },
"node_modules/katex": { "node_modules/katex": {
"version": "0.16.21", "version": "0.16.22",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz",
"integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==",
"funding": [ "funding": [
"https://opencollective.com/katex", "https://opencollective.com/katex",
"https://github.com/sponsors/katex" "https://github.com/sponsors/katex"

View file

@ -95,7 +95,7 @@
"idb": "^7.1.1", "idb": "^7.1.1",
"js-sha256": "^0.10.1", "js-sha256": "^0.10.1",
"jspdf": "^3.0.0", "jspdf": "^3.0.0",
"katex": "^0.16.21", "katex": "^0.16.22",
"kokoro-js": "^1.1.1", "kokoro-js": "^1.1.1",
"marked": "^9.1.0", "marked": "^9.1.0",
"mermaid": "^11.6.0", "mermaid": "^11.6.0",

View file

@ -44,6 +44,10 @@ code {
font-family: 'InstrumentSerif', sans-serif; font-family: 'InstrumentSerif', sans-serif;
} }
.marked a {
@apply underline;
}
math { math {
margin-top: 1rem; margin-top: 1rem;
} }

View file

@ -336,7 +336,7 @@ export const userSignOut = async () => {
}) })
.then(async (res) => { .then(async (res) => {
if (!res.ok) throw await res.json(); if (!res.ok) throw await res.json();
return res; return res.json();
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);

View file

@ -612,6 +612,78 @@ export const generateTitle = async (
} }
}; };
export const generateFollowUps = async (
token: string = '',
model: string,
messages: string,
chat_id?: string
) => {
let error = null;
const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/follow_ups/completions`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
},
body: JSON.stringify({
model: model,
messages: messages,
...(chat_id && { chat_id: chat_id })
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
console.error(err);
if ('detail' in err) {
error = err.detail;
}
return null;
});
if (error) {
throw error;
}
try {
// Step 1: Safely extract the response string
const response = res?.choices[0]?.message?.content ?? '';
// Step 2: Attempt to fix common JSON format issues like single quotes
const sanitizedResponse = response.replace(/['`]/g, '"'); // Convert single quotes to double quotes for valid JSON
// Step 3: Find the relevant JSON block within the response
const jsonStartIndex = sanitizedResponse.indexOf('{');
const jsonEndIndex = sanitizedResponse.lastIndexOf('}');
// Step 4: Check if we found a valid JSON block (with both `{` and `}`)
if (jsonStartIndex !== -1 && jsonEndIndex !== -1) {
const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1);
// Step 5: Parse the JSON block
const parsed = JSON.parse(jsonResponse);
// Step 6: If there's a "follow_ups" key, return the follow_ups array; otherwise, return an empty array
if (parsed && parsed.follow_ups) {
return Array.isArray(parsed.follow_ups) ? parsed.follow_ups : [];
} else {
return [];
}
}
// If no valid JSON block found, return an empty array
return [];
} catch (e) {
// Catch and safely return empty array on any parsing errors
console.error('Failed to parse response: ', e);
return [];
}
};
export const generateTags = async ( export const generateTags = async (
token: string = '', token: string = '',
model: string, model: string,

View file

@ -393,6 +393,7 @@ export const updateUserById = async (token: string, userId: string, user: UserUp
}, },
body: JSON.stringify({ body: JSON.stringify({
profile_image_url: user.profile_image_url, profile_image_url: user.profile_image_url,
role: user.role,
email: user.email, email: user.email,
name: user.name, name: user.name,
password: user.password !== '' ? user.password : undefined password: user.password !== '' ? user.password : undefined

View file

@ -49,6 +49,9 @@
let loading = false; let loading = false;
const verifyOllamaHandler = async () => { const verifyOllamaHandler = async () => {
// remove trailing slash from url
url = url.replace(/\/$/, '');
const res = await verifyOllamaConnection(localStorage.token, { const res = await verifyOllamaConnection(localStorage.token, {
url, url,
key key
@ -62,6 +65,9 @@
}; };
const verifyOpenAIHandler = async () => { const verifyOpenAIHandler = async () => {
// remove trailing slash from url
url = url.replace(/\/$/, '');
const res = await verifyOpenAIConnection( const res = await verifyOpenAIConnection(
localStorage.token, localStorage.token,
{ {

View file

@ -1,6 +1,8 @@
<script> <script>
import { getContext, tick, onMount } from 'svelte'; import { getContext, tick, onMount } from 'svelte';
import { toast } from 'svelte-sonner'; import { goto } from '$app/navigation';
import { page } from '$app/stores';
import Leaderboard from './Evaluations/Leaderboard.svelte'; import Leaderboard from './Evaluations/Leaderboard.svelte';
import Feedbacks from './Evaluations/Feedbacks.svelte'; import Feedbacks from './Evaluations/Feedbacks.svelte';
@ -8,7 +10,24 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
let selectedTab = 'leaderboard'; let selectedTab;
$: {
const pathParts = $page.url.pathname.split('/');
const tabFromPath = pathParts[pathParts.length - 1];
selectedTab = ['leaderboard', 'feedbacks'].includes(tabFromPath) ? tabFromPath : 'leaderboard';
}
$: if (selectedTab) {
// scroll to selectedTab
scrollToTab(selectedTab);
}
const scrollToTab = (tabId) => {
const tabElement = document.getElementById(tabId);
if (tabElement) {
tabElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
}
};
let loaded = false; let loaded = false;
let feedbacks = []; let feedbacks = [];
@ -27,6 +46,9 @@
} }
}); });
} }
// Scroll to the selected tab on mount
scrollToTab(selectedTab);
}); });
</script> </script>
@ -37,12 +59,13 @@
class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none" class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none"
> >
<button <button
id="leaderboard"
class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab ===
'leaderboard' 'leaderboard'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'leaderboard'; goto('/admin/evaluations/leaderboard');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -63,12 +86,13 @@
</button> </button>
<button <button
id="feedbacks"
class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab ===
'feedbacks' 'feedbacks'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'feedbacks'; goto('/admin/evaluations/feedbacks');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">

View file

@ -1,5 +1,7 @@
<script> <script>
import { getContext, tick, onMount } from 'svelte'; import { getContext, tick, onMount } from 'svelte';
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { config } from '$lib/stores'; import { config } from '$lib/stores';
@ -26,6 +28,41 @@
let selectedTab = 'general'; let selectedTab = 'general';
// Get current tab from URL pathname, default to 'general'
$: {
const pathParts = $page.url.pathname.split('/');
const tabFromPath = pathParts[pathParts.length - 1];
selectedTab = [
'general',
'connections',
'models',
'evaluations',
'tools',
'documents',
'web',
'code-execution',
'interface',
'audio',
'images',
'pipelines',
'db'
].includes(tabFromPath)
? tabFromPath
: 'general';
}
$: if (selectedTab) {
// scroll to selectedTab
scrollToTab(selectedTab);
}
const scrollToTab = (tabId) => {
const tabElement = document.getElementById(tabId);
if (tabElement) {
tabElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
}
};
onMount(() => { onMount(() => {
const containerElement = document.getElementById('admin-settings-tabs-container'); const containerElement = document.getElementById('admin-settings-tabs-container');
@ -37,6 +74,9 @@
} }
}); });
} }
// Scroll to the selected tab on mount
scrollToTab(selectedTab);
}); });
</script> </script>
@ -46,12 +86,13 @@
class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none" class="tabs flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none"
> >
<button <button
id="general"
class="px-0.5 py-1 min-w-fit rounded-lg flex-1 lg:flex-none flex text-right transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg flex-1 lg:flex-none flex text-right transition {selectedTab ===
'general' 'general'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'general'; goto('/admin/settings/general');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -72,12 +113,13 @@
</button> </button>
<button <button
id="connections"
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 ===
'connections' 'connections'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'connections'; goto('/admin/settings/connections');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -96,12 +138,13 @@
</button> </button>
<button <button
id="models"
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 ===
'models' 'models'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'models'; goto('/admin/settings/models');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -122,12 +165,13 @@
</button> </button>
<button <button
id="evaluations"
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 ===
'evaluations' 'evaluations'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'evaluations'; goto('/admin/settings/evaluations');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -137,12 +181,13 @@
</button> </button>
<button <button
id="tools"
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 ===
'tools' 'tools'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'tools'; goto('/admin/settings/tools');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -163,12 +208,13 @@
</button> </button>
<button <button
id="documents"
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 ===
'documents' 'documents'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'documents'; goto('/admin/settings/documents');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -193,12 +239,13 @@
</button> </button>
<button <button
id="web"
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 ===
'web' 'web'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'web'; goto('/admin/settings/web');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -217,12 +264,13 @@
</button> </button>
<button <button
id="code-execution"
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 ===
'code-execution' 'code-execution'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'code-execution'; goto('/admin/settings/code-execution');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -243,12 +291,13 @@
</button> </button>
<button <button
id="interface"
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 ===
'interface' 'interface'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'interface'; goto('/admin/settings/interface');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -269,12 +318,13 @@
</button> </button>
<button <button
id="audio"
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 ===
'audio' 'audio'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'audio'; goto('/admin/settings/audio');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -296,12 +346,13 @@
</button> </button>
<button <button
id="images"
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 ===
'images' 'images'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'images'; goto('/admin/settings/images');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -322,12 +373,13 @@
</button> </button>
<button <button
id="pipelines"
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 ===
'pipelines' 'pipelines'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'pipelines'; goto('/admin/settings/pipelines');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -352,12 +404,13 @@
</button> </button>
<button <button
id="db"
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 ===
'db' 'db'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'db'; goto('/admin/settings/db');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">

View file

@ -31,6 +31,8 @@
TASK_MODEL_EXTERNAL: '', TASK_MODEL_EXTERNAL: '',
ENABLE_TITLE_GENERATION: true, ENABLE_TITLE_GENERATION: true,
TITLE_GENERATION_PROMPT_TEMPLATE: '', TITLE_GENERATION_PROMPT_TEMPLATE: '',
ENABLE_FOLLOW_UP_GENERATION: true,
FOLLOW_UP_GENERATION_PROMPT_TEMPLATE: '',
IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE: '', IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE: '',
ENABLE_AUTOCOMPLETE_GENERATION: true, ENABLE_AUTOCOMPLETE_GENERATION: true,
AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH: -1, AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH: -1,
@ -235,6 +237,32 @@
</div> </div>
{/if} {/if}
<div class="mb-2.5 flex w-full items-center justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Follow Up Generation')}
</div>
<Switch bind:state={taskConfig.ENABLE_FOLLOW_UP_GENERATION} />
</div>
{#if taskConfig.ENABLE_FOLLOW_UP_GENERATION}
<div class="mb-2.5">
<div class=" mb-1 text-xs font-medium">{$i18n.t('Follow Up Generation Prompt')}</div>
<Tooltip
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
placement="top-start"
>
<Textarea
bind:value={taskConfig.FOLLOW_UP_GENERATION_PROMPT_TEMPLATE}
placeholder={$i18n.t(
'Leave empty to use the default prompt, or enter a custom prompt'
)}
/>
</Tooltip>
</div>
{/if}
<div class="mb-2.5 flex w-full items-center justify-between"> <div class="mb-2.5 flex w-full items-center justify-between">
<div class=" self-center text-xs font-medium"> <div class=" self-center text-xs font-medium">
{$i18n.t('Tags Generation')} {$i18n.t('Tags Generation')}

View file

@ -446,6 +446,7 @@
</div> </div>
</div> </div>
{:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity'} {:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity'}
<div class="mb-2.5 flex w-full flex-col">
<div> <div>
<div class=" self-center text-xs font-medium mb-1"> <div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Perplexity API Key')} {$i18n.t('Perplexity API Key')}
@ -456,6 +457,44 @@
bind:value={webConfig.PERPLEXITY_API_KEY} bind:value={webConfig.PERPLEXITY_API_KEY}
/> />
</div> </div>
</div>
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class="self-center text-xs font-medium mb-1">
{$i18n.t('Perplexity Model')}
</div>
<input
list="perplexity-model-list"
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
bind:value={webConfig.PERPLEXITY_MODEL}
/>
<datalist id="perplexity-model-list">
<option value="sonar">Sonar</option>
<option value="sonar-pro">Sonar Pro</option>
<option value="sonar-reasoning">Sonar Reasoning</option>
<option value="sonar-reasoning-pro">Sonar Reasoning Pro</option>
<option value="sonar-deep-research">Sonar Deep Research</option>
</datalist>
</div>
</div>
<div class="mb-2.5 flex w-full flex-col">
<div>
<div class=" self-center text-xs font-medium mb-1">
{$i18n.t('Perplexity Search Context Usage')}
</div>
<select
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
bind:value={webConfig.PERPLEXITY_SEARCH_CONTEXT_USAGE}
>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
</div>
</div>
{:else if webConfig.WEB_SEARCH_ENGINE === 'sougou'} {:else if webConfig.WEB_SEARCH_ENGINE === 'sougou'}
<div class="mb-2.5 flex w-full flex-col"> <div class="mb-2.5 flex w-full flex-col">
<div> <div>

View file

@ -4,13 +4,32 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { user } from '$lib/stores'; import { user } from '$lib/stores';
import { page } from '$app/stores';
import UserList from './Users/UserList.svelte'; import UserList from './Users/UserList.svelte';
import Groups from './Users/Groups.svelte'; import Groups from './Users/Groups.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
let selectedTab = 'overview'; let selectedTab;
$: {
const pathParts = $page.url.pathname.split('/');
const tabFromPath = pathParts[pathParts.length - 1];
selectedTab = ['overview', 'groups'].includes(tabFromPath) ? tabFromPath : 'overview';
}
$: if (selectedTab) {
// scroll to selectedTab
scrollToTab(selectedTab);
}
const scrollToTab = (tabId) => {
const tabElement = document.getElementById(tabId);
if (tabElement) {
tabElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
}
};
let loaded = false; let loaded = false;
onMount(async () => { onMount(async () => {
@ -30,6 +49,9 @@
} }
}); });
} }
// Scroll to the selected tab on mount
scrollToTab(selectedTab);
}); });
</script> </script>
@ -39,12 +61,13 @@
class=" flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none" class=" flex flex-row overflow-x-auto gap-2.5 max-w-full lg:gap-1 lg:flex-col lg:flex-none lg:w-40 dark:text-gray-200 text-sm font-medium text-left scrollbar-none"
> >
<button <button
id="overview"
class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab ===
'overview' 'overview'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'overview'; goto('/admin/users/overview');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">
@ -63,12 +86,13 @@
</button> </button>
<button <button
id="groups"
class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab === class="px-0.5 py-1 min-w-fit rounded-lg lg:flex-none flex text-right transition {selectedTab ===
'groups' 'groups'
? '' ? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}" : ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={() => { on:click={() => {
selectedTab = 'groups'; goto('/admin/users/groups');
}} }}
> >
<div class=" self-center mr-2"> <div class=" self-center mr-2">

View file

@ -52,27 +52,6 @@
let showUserChatsModal = false; let showUserChatsModal = false;
let showEditUserModal = false; let showEditUserModal = false;
let showUpdateRoleModal = false;
const onUpdateRole = (user) => {
if (user.role === 'user') {
updateRoleHandler(user.id, 'admin');
} else if (user.role === 'pending') {
updateRoleHandler(user.id, 'user');
} else {
updateRoleHandler(user.id, 'pending');
}
};
const updateRoleHandler = async (id, role) => {
const res = await updateUserRole(localStorage.token, id, role).catch((error) => {
toast.error(`${error}`);
return null;
});
if (res) {
getUserList();
}
};
const deleteUserHandler = async (id) => { const deleteUserHandler = async (id) => {
const res = await deleteUserById(localStorage.token, id).catch((error) => { const res = await deleteUserById(localStorage.token, id).catch((error) => {
@ -133,21 +112,6 @@
}} }}
/> />
<RoleUpdateConfirmDialog
bind:show={showUpdateRoleModal}
on:confirm={() => {
onUpdateRole(selectedUser);
}}
message={$i18n.t(`Are you sure you want to update this user\'s role to **{{ROLE}}**?`, {
ROLE:
selectedUser?.role === 'user'
? 'admin'
: selectedUser?.role === 'pending'
? 'user'
: 'pending'
})}
/>
{#key selectedUser} {#key selectedUser}
<EditUserModal <EditUserModal
bind:show={showEditUserModal} bind:show={showEditUserModal}
@ -415,7 +379,7 @@
class=" translate-y-0.5" class=" translate-y-0.5"
on:click={() => { on:click={() => {
selectedUser = user; selectedUser = user;
showUpdateRoleModal = true; showEditUserModal = !showEditUserModal;
}} }}
> >
<Badge <Badge

View file

@ -19,6 +19,7 @@
let _user = { let _user = {
profile_image_url: '', profile_image_url: '',
role: 'pending',
name: '', name: '',
email: '', email: '',
password: '' password: ''
@ -95,6 +96,23 @@
<div class=" px-5 pt-3 pb-5"> <div class=" px-5 pt-3 pb-5">
<div class=" flex flex-col space-y-1.5"> <div class=" flex flex-col space-y-1.5">
<div class="flex flex-col w-full">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Role')}</div>
<div class="flex-1">
<select
class="w-full rounded-sm text-sm bg-transparent disabled:text-gray-500 dark:disabled:text-gray-500 outline-hidden"
bind:value={_user.role}
disabled={_user.id == sessionUser.id}
required
>
<option value="admin">{$i18n.t('Admin')}</option>
<option value="user">{$i18n.t('User')}</option>
<option value="pending">{$i18n.t('Pending')}</option>
</select>
</div>
</div>
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div> <div class=" mb-1 text-xs text-gray-500">{$i18n.t('Email')}</div>

View file

@ -239,6 +239,8 @@
}; };
const showMessage = async (message) => { const showMessage = async (message) => {
await tick();
const _chatId = JSON.parse(JSON.stringify($chatId)); const _chatId = JSON.parse(JSON.stringify($chatId));
let _messageId = JSON.parse(JSON.stringify(message.id)); let _messageId = JSON.parse(JSON.stringify(message.id));
@ -298,6 +300,12 @@
message.content = data.content; message.content = data.content;
} else if (type === 'chat:message:files' || type === 'files') { } else if (type === 'chat:message:files' || type === 'files') {
message.files = data.files; message.files = data.files;
} else if (type === 'chat:message:follow_ups') {
message.followUps = data.follow_ups;
if (autoScroll) {
scrollToBottom('smooth');
}
} else if (type === 'chat:title') { } else if (type === 'chat:title') {
chatTitle.set(data); chatTitle.set(data);
currentChatPage.set(1); currentChatPage.set(1);
@ -774,6 +782,7 @@
autoScroll = true; autoScroll = true;
resetInput();
await chatId.set(''); await chatId.set('');
await chatTitle.set(''); await chatTitle.set('');
@ -911,10 +920,13 @@
} }
}; };
const scrollToBottom = async () => { const scrollToBottom = async (behavior = 'auto') => {
await tick(); await tick();
if (messagesContainerElement) { if (messagesContainerElement) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight; messagesContainerElement.scrollTo({
top: messagesContainerElement.scrollHeight,
behavior
});
} }
}; };
const chatCompletedHandler = async (chatId, modelId, responseMessageId, messages) => { const chatCompletedHandler = async (chatId, modelId, responseMessageId, messages) => {
@ -1676,6 +1688,7 @@
chat_id: $chatId, chat_id: $chatId,
id: responseMessageId, id: responseMessageId,
background_tasks: {
...(!$temporaryChatEnabled && ...(!$temporaryChatEnabled &&
(messages.length == 1 || (messages.length == 1 ||
(messages.length == 2 && (messages.length == 2 &&
@ -1683,12 +1696,12 @@
messages.at(1)?.role === 'user')) && messages.at(1)?.role === 'user')) &&
(selectedModels[0] === model.id || atSelectedModel !== undefined) (selectedModels[0] === model.id || atSelectedModel !== undefined)
? { ? {
background_tasks: {
title_generation: $settings?.title?.auto ?? true, title_generation: $settings?.title?.auto ?? true,
tags_generation: $settings?.autoTags ?? true tags_generation: $settings?.autoTags ?? true
} }
}
: {}), : {}),
follow_up_generation: $settings?.autoFollowUps ?? true
},
...(stream && (model.info?.meta?.capabilities?.usage ?? false) ...(stream && (model.info?.meta?.capabilities?.usage ?? false)
? { ? {
@ -2072,7 +2085,7 @@
</div> </div>
</div> </div>
<div class=" pb-[1rem]"> <div class=" pb-2">
<MessageInput <MessageInput
{history} {history}
{taskIds} {taskIds}

View file

@ -1,5 +1,9 @@
<script lang="ts"> <script lang="ts">
import DOMPurify from 'dompurify';
import { marked } from 'marked';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { createPicker, getAuthToken } from '$lib/utils/google-drive-picker'; import { createPicker, getAuthToken } from '$lib/utils/google-drive-picker';
import { pickAndDownloadFile } from '$lib/utils/onedrive-file-picker'; import { pickAndDownloadFile } from '$lib/utils/onedrive-file-picker';
@ -595,7 +599,7 @@
/> />
{:else} {:else}
<form <form
class="w-full flex gap-1.5" class="w-full flex flex-col gap-1.5"
on:submit|preventDefault={() => { on:submit|preventDefault={() => {
// check if selectedModels support image input // check if selectedModels support image input
dispatch('submit', prompt); dispatch('submit', prompt);
@ -1520,6 +1524,14 @@
</div> </div>
</div> </div>
</div> </div>
{#if $config?.license_metadata?.input_footer}
<div class=" text-xs text-gray-500 text-center line-clamp-1 marked">
{@html DOMPurify.sanitize(marked($config?.license_metadata?.input_footer))}
</div>
{:else}
<div class="mb-1" />
{/if}
</form> </form>
{/if} {/if}
</div> </div>

View file

@ -205,8 +205,10 @@
return; return;
} }
const mineTypes = ['audio/webm; codecs=opus', 'audio/mp4'];
mediaRecorder = new MediaRecorder(stream, { mediaRecorder = new MediaRecorder(stream, {
mimeType: 'audio/webm; codecs=opus' mimeType: mineTypes.find((type) => MediaRecorder.isTypeSupported(type))
}); });
mediaRecorder.onstart = () => { mediaRecorder.onstart = () => {

View file

@ -28,7 +28,7 @@
<!-- svelte-ignore a11y-media-has-caption --> <!-- svelte-ignore a11y-media-has-caption -->
<video <video
class="w-full my-2" class="w-full my-2"
src={videoSrc} src={videoSrc.replaceAll('&amp;', '&')}
title="Video player" title="Video player"
frameborder="0" frameborder="0"
referrerpolicy="strict-origin-when-cross-origin" referrerpolicy="strict-origin-when-cross-origin"

View file

@ -15,7 +15,7 @@
src.startsWith('/') src.startsWith('/')
? src ? src
: `/user.png`} : `/user.png`}
class=" {className} object-cover rounded-full -translate-y-[1px]" class=" {className} object-cover rounded-full"
alt="profile" alt="profile"
draggable="false" draggable="false"
/> />

View file

@ -48,6 +48,9 @@
import ContentRenderer from './ContentRenderer.svelte'; import ContentRenderer from './ContentRenderer.svelte';
import { KokoroWorker } from '$lib/workers/KokoroWorker'; import { KokoroWorker } from '$lib/workers/KokoroWorker';
import FileItem from '$lib/components/common/FileItem.svelte'; import FileItem from '$lib/components/common/FileItem.svelte';
import FollowUps from './ResponseMessage/FollowUps.svelte';
import { fade } from 'svelte/transition';
import { flyAndScale } from '$lib/utils/transitions';
interface MessageType { interface MessageType {
id: string; id: string;
@ -606,7 +609,7 @@
/> />
</div> </div>
<div class="flex-auto w-0 pl-1 relative"> <div class="flex-auto w-0 pl-1 relative -translate-y-0.5">
<Name> <Name>
<Tooltip content={model?.name ?? message.model} placement="top-start"> <Tooltip content={model?.name ?? message.model} placement="top-start">
<span class="line-clamp-1 text-black dark:text-white"> <span class="line-clamp-1 text-black dark:text-white">
@ -866,12 +869,14 @@
{#if siblings.length > 1} {#if siblings.length > 1}
<div class="flex self-center min-w-fit" dir="ltr"> <div class="flex self-center min-w-fit" dir="ltr">
<button <button
aria-label={$i18n.t('Previous message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition" class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
on:click={() => { on:click={() => {
showPreviousMessage(message); showPreviousMessage(message);
}} }}
> >
<svg <svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -937,10 +942,12 @@
on:click={() => { on:click={() => {
showNextMessage(message); showNextMessage(message);
}} }}
aria-label={$i18n.t('Next message')}
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
aria-hidden="true"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke="currentColor" stroke="currentColor"
stroke-width="2.5" stroke-width="2.5"
@ -961,6 +968,7 @@
{#if $user?.role === 'user' ? ($user?.permissions?.chat?.edit ?? true) : true} {#if $user?.role === 'user' ? ($user?.permissions?.chat?.edit ?? true) : true}
<Tooltip content={$i18n.t('Edit')} placement="bottom"> <Tooltip content={$i18n.t('Edit')} placement="bottom">
<button <button
aria-label={$i18n.t('Edit')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
@ -973,6 +981,7 @@
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="2.3" stroke-width="2.3"
aria-hidden="true"
stroke="currentColor" stroke="currentColor"
class="w-4 h-4" class="w-4 h-4"
> >
@ -989,6 +998,7 @@
<Tooltip content={$i18n.t('Copy')} placement="bottom"> <Tooltip content={$i18n.t('Copy')} placement="bottom">
<button <button
aria-label={$i18n.t('Copy')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition copy-response-button" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition copy-response-button"
@ -999,6 +1009,7 @@
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
aria-hidden="true"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="2.3" stroke-width="2.3"
stroke="currentColor" stroke="currentColor"
@ -1016,6 +1027,7 @@
{#if $user?.role === 'admin' || ($user?.permissions?.chat?.tts ?? true)} {#if $user?.role === 'admin' || ($user?.permissions?.chat?.tts ?? true)}
<Tooltip content={$i18n.t('Read Aloud')} placement="bottom"> <Tooltip content={$i18n.t('Read Aloud')} placement="bottom">
<button <button
aria-label={$i18n.t('Read Aloud')}
id="speak-button-{message.id}" id="speak-button-{message.id}"
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
@ -1031,6 +1043,7 @@
class=" w-4 h-4" class=" w-4 h-4"
fill="currentColor" fill="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<style> <style>
@ -1063,6 +1076,7 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
aria-hidden="true"
stroke-width="2.3" stroke-width="2.3"
stroke="currentColor" stroke="currentColor"
class="w-4 h-4" class="w-4 h-4"
@ -1078,6 +1092,7 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
aria-hidden="true"
stroke-width="2.3" stroke-width="2.3"
stroke="currentColor" stroke="currentColor"
class="w-4 h-4" class="w-4 h-4"
@ -1096,6 +1111,7 @@
{#if $config?.features.enable_image_generation && ($user?.role === 'admin' || $user?.permissions?.features?.image_generation) && !readOnly} {#if $config?.features.enable_image_generation && ($user?.role === 'admin' || $user?.permissions?.features?.image_generation) && !readOnly}
<Tooltip content={$i18n.t('Generate Image')} placement="bottom"> <Tooltip content={$i18n.t('Generate Image')} placement="bottom">
<button <button
aria-label={$i18n.t('Generate Image')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
@ -1107,6 +1123,7 @@
> >
{#if generatingImage} {#if generatingImage}
<svg <svg
aria-hidden="true"
class=" w-4 h-4" class=" w-4 h-4"
fill="currentColor" fill="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -1141,6 +1158,7 @@
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
aria-hidden="true"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="2.3" stroke-width="2.3"
stroke="currentColor" stroke="currentColor"
@ -1173,6 +1191,7 @@
placement="bottom" placement="bottom"
> >
<button <button
aria-hidden="true"
class=" {isLastMessage class=" {isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition whitespace-pre-wrap" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
@ -1182,6 +1201,7 @@
id="info-{message.id}" id="info-{message.id}"
> >
<svg <svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -1203,6 +1223,7 @@
{#if !$temporaryChatEnabled && ($config?.features.enable_message_rating ?? true)} {#if !$temporaryChatEnabled && ($config?.features.enable_message_rating ?? true)}
<Tooltip content={$i18n.t('Good Response')} placement="bottom"> <Tooltip content={$i18n.t('Good Response')} placement="bottom">
<button <button
aria-label={$i18n.t('Good Response')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {( : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
@ -1221,6 +1242,7 @@
}} }}
> >
<svg <svg
aria-hidden="true"
stroke="currentColor" stroke="currentColor"
fill="none" fill="none"
stroke-width="2.3" stroke-width="2.3"
@ -1239,6 +1261,7 @@
<Tooltip content={$i18n.t('Bad Response')} placement="bottom"> <Tooltip content={$i18n.t('Bad Response')} placement="bottom">
<button <button
aria-label={$i18n.t('Bad Response')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {( : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
@ -1257,6 +1280,7 @@
}} }}
> >
<svg <svg
aria-hidden="true"
stroke="currentColor" stroke="currentColor"
fill="none" fill="none"
stroke-width="2.3" stroke-width="2.3"
@ -1277,6 +1301,7 @@
{#if isLastMessage} {#if isLastMessage}
<Tooltip content={$i18n.t('Continue Response')} placement="bottom"> <Tooltip content={$i18n.t('Continue Response')} placement="bottom">
<button <button
aria-label={$i18n.t('Continue Response')}
type="button" type="button"
id="continue-response-button" id="continue-response-button"
class="{isLastMessage class="{isLastMessage
@ -1287,6 +1312,7 @@
}} }}
> >
<svg <svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -1312,6 +1338,7 @@
<Tooltip content={$i18n.t('Regenerate')} placement="bottom"> <Tooltip content={$i18n.t('Regenerate')} placement="bottom">
<button <button
type="button" type="button"
aria-label={$i18n.t('Regenerate')}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition regenerate-response-button" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition regenerate-response-button"
@ -1337,6 +1364,7 @@
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="2.3" stroke-width="2.3"
aria-hidden="true"
stroke="currentColor" stroke="currentColor"
class="w-4 h-4" class="w-4 h-4"
> >
@ -1353,6 +1381,7 @@
<Tooltip content={$i18n.t('Delete')} placement="bottom"> <Tooltip content={$i18n.t('Delete')} placement="bottom">
<button <button
type="button" type="button"
aria-label={$i18n.t('Delete')}
id="delete-response-button" id="delete-response-button"
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
@ -1367,6 +1396,7 @@
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="2" stroke-width="2"
stroke="currentColor" stroke="currentColor"
aria-hidden="true"
class="w-4 h-4" class="w-4 h-4"
> >
<path <path
@ -1384,6 +1414,7 @@
<Tooltip content={action.name} placement="bottom"> <Tooltip content={action.name} placement="bottom">
<button <button
type="button" type="button"
aria-label={action.name}
class="{isLastMessage class="{isLastMessage
? 'visible' ? 'visible'
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition" : 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
@ -1425,6 +1456,17 @@
}} }}
/> />
{/if} {/if}
{#if isLastMessage && message.done && !readOnly && (message?.followUps ?? []).length > 0}
<div class="mt-2.5" in:fade={{ duration: 100 }}>
<FollowUps
followUps={message?.followUps}
onClick={(prompt) => {
submitMessage(message?.id, prompt);
}}
/>
</div>
{/if}
{/if} {/if}
</div> </div>

View file

@ -0,0 +1,36 @@
<script lang="ts">
import ArrowTurnDownRight from '$lib/components/icons/ArrowTurnDownRight.svelte';
import { onMount, tick, getContext } from 'svelte';
const i18n = getContext('i18n');
export let followUps: string[] = [];
export let onClick: (followUp: string) => void = () => {};
</script>
<div class="mt-4">
<div class="text-sm font-medium">
{$i18n.t('Follow up')}
</div>
<div class="flex flex-col text-left gap-1 mt-1.5">
{#each followUps as followUp, idx (idx)}
<button
class=" mr-2 py-1.5 bg-transparent text-left text-sm flex items-center gap-2 px-1.5 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white transition"
on:click={() => onClick(followUp)}
title={followUp}
aria-label={followUp}
>
<ArrowTurnDownRight className="size-3.5" />
<div class="line-clamp-1">
{followUp}
</div>
</button>
{#if idx < followUps.length - 1}
<hr class="border-gray-100 dark:border-gray-850" />
{/if}
{/each}
</div>
</div>

View file

@ -17,6 +17,7 @@
// Addons // Addons
let titleAutoGenerate = true; let titleAutoGenerate = true;
let autoFollowUps = true;
let autoTags = true; let autoTags = true;
let responseAutoCopy = false; let responseAutoCopy = false;
@ -197,6 +198,11 @@
}); });
}; };
const toggleAutoFollowUps = async () => {
autoFollowUps = !autoFollowUps;
saveSettings({ autoFollowUps });
};
const toggleAutoTags = async () => { const toggleAutoTags = async () => {
autoTags = !autoTags; autoTags = !autoTags;
saveSettings({ autoTags }); saveSettings({ autoTags });
@ -287,6 +293,7 @@
onMount(async () => { onMount(async () => {
titleAutoGenerate = $settings?.title?.auto ?? true; titleAutoGenerate = $settings?.title?.auto ?? true;
autoTags = $settings.autoTags ?? true; autoTags = $settings.autoTags ?? true;
autoFollowUps = $settings.autoFollowUps ?? true;
highContrastMode = $settings.highContrastMode ?? false; highContrastMode = $settings.highContrastMode ?? false;
@ -619,6 +626,26 @@
</div> </div>
</div> </div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Follow-Up Auto-Generation')}</div>
<button
class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => {
toggleAutoFollowUps();
}}
type="button"
>
{#if autoFollowUps === true}
<span class="ml-2 self-center">{$i18n.t('On')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
{/if}
</button>
</div>
</div>
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Chat Tags Auto-Generation')}</div> <div class=" self-center text-xs">{$i18n.t('Chat Tags Auto-Generation')}</div>

View file

@ -34,93 +34,160 @@
id: 'general', id: 'general',
title: 'General', title: 'General',
keywords: [ keywords: [
'general', 'advancedparams',
'theme', 'advancedparameters',
'language', 'advanced params',
'notifications', 'advanced parameters',
'system',
'systemprompt',
'prompt',
'advanced',
'settings',
'defaultsettings',
'configuration', 'configuration',
'systemsettings',
'notificationsettings',
'systempromptconfig',
'languageoptions',
'defaultparameters', 'defaultparameters',
'systemparameters' 'default parameters',
'defaultsettings',
'default settings',
'general',
'keepalive',
'keep alive',
'languages',
'notifications',
'requestmode',
'request mode',
'systemparameters',
'system parameters',
'systemprompt',
'system prompt',
'systemsettings',
'system settings',
'theme',
'translate',
'webuisettings',
'webui settings'
] ]
}, },
{ {
id: 'interface', id: 'interface',
title: 'Interface', title: 'Interface',
keywords: [ keywords: [
'defaultmodel', 'allow user location',
'selectmodel', 'allow voice interruption in call',
'ui', 'allowuserlocation',
'userinterface', 'allowvoiceinterruptionincall',
'display', 'always collapse codeblocks',
'layout', 'always collapse code blocks',
'design', 'always expand details',
'landingpage', 'always on web search',
'landingpagemode', 'always play notification sound',
'default', 'alwayscollapsecodeblocks',
'chat', 'alwaysexpanddetails',
'chatbubble', 'alwaysonwebsearch',
'chatui', 'alwaysplaynotificationsound',
'username', 'android',
'showusername',
'displayusername',
'widescreen',
'widescreenmode',
'fullscreen',
'expandmode',
'chatdirection',
'lefttoright',
'ltr',
'righttoleft',
'rtl',
'notifications',
'toast',
'toastnotifications',
'largechunks',
'streamlargechunks',
'scroll',
'scrollonbranchchange',
'scrollbehavior',
'richtext',
'richtextinput',
'background',
'chatbackground',
'chatbackgroundimage',
'backgroundimage',
'uploadbackground',
'resetbackground',
'titleautogen',
'titleautogeneration',
'autotitle',
'chattags',
'auto chat tags', 'auto chat tags',
'responseautocopy', 'auto copy response to clipboard',
'clipboard', 'auto title',
'location', 'autochattags',
'userlocation', 'autocopyresponsetoclipboard',
'userlocationaccess', 'autotitle',
'haptic', 'beta',
'hapticfeedback',
'vibration',
'voice',
'voicecontrol',
'voiceinterruption',
'call', 'call',
'emojis', 'chat background image',
'displayemoji', 'chat bubble ui',
'save', 'chat direction',
'chat tags autogen',
'chat tags autogeneration',
'chat ui',
'chatbackgroundimage',
'chatbubbleui',
'chatdirection',
'chat tags autogeneration',
'chattagsautogeneration',
'chatui',
'copy formatted text',
'copyformattedtext',
'default model',
'defaultmodel',
'design',
'detect artifacts automatically',
'detectartifactsautomatically',
'display emoji in call',
'display username',
'displayemojiincall',
'displayusername',
'enter key behavior',
'enterkeybehavior',
'expand mode',
'expandmode',
'file',
'followup autogeneration',
'followupautogeneration',
'fullscreen',
'fullwidthmode',
'full width mode',
'haptic feedback',
'hapticfeedback',
'high contrast mode',
'highcontrastmode',
'iframe sandbox allow forms',
'iframe sandbox allow same origin',
'iframesandboxallowforms',
'iframesandboxallowsameorigin',
'imagecompression',
'image compression',
'imagemaxcompressionsize',
'image max compression size',
'interface customization',
'interface options', 'interface options',
'interfacecustomization', 'interfacecustomization',
'alwaysonwebsearch' 'interfaceoptions',
'landing page mode',
'landingpagemode',
'layout',
'left to right',
'left-to-right',
'lefttoright',
'ltr',
'paste large text as file',
'pastelargetextasfile',
'reset background',
'resetbackground',
'response auto copy',
'responseautocopy',
'rich text input for chat',
'richtextinputforchat',
'right to left',
'right-to-left',
'righttoleft',
'rtl',
'scroll behavior',
'scroll on branch change',
'scrollbehavior',
'scrollonbranchchange',
'select model',
'selectmodel',
'settings',
'show username',
'showusername',
'stream large chunks',
'streamlargechunks',
'stylized pdf export',
'stylizedpdfexport',
'title autogeneration',
'titleautogeneration',
'toast notifications for new updates',
'toastnotificationsfornewupdates',
'upload background',
'uploadbackground',
'user interface',
'user location access',
'userinterface',
'userlocationaccess',
'vibration',
'voice control',
'voicecontrol',
'widescreen mode',
'widescreenmode',
'whatsnew',
'whats new',
'websearchinchat',
'web search in chat'
] ]
}, },
...($user?.role === 'admin' || ...($user?.role === 'admin' ||
@ -129,7 +196,15 @@
{ {
id: 'connections', id: 'connections',
title: 'Connections', title: 'Connections',
keywords: [] keywords: [
'addconnection',
'add connection',
'manageconnections',
'manage connections',
'manage direct connections',
'managedirectconnections',
'settings'
]
} }
] ]
: []), : []),
@ -140,7 +215,15 @@
{ {
id: 'tools', id: 'tools',
title: 'Tools', title: 'Tools',
keywords: [] keywords: [
'addconnection',
'add connection',
'managetools',
'manage tools',
'manage tool servers',
'managetoolservers',
'settings'
]
} }
] ]
: []), : []),
@ -149,159 +232,233 @@
id: 'personalization', id: 'personalization',
title: 'Personalization', title: 'Personalization',
keywords: [ keywords: [
'personalization', 'account preferences',
'memory', 'account settings',
'personalize', 'accountpreferences',
'preferences', 'accountsettings',
'profile',
'personalsettings',
'custom settings', 'custom settings',
'customsettings',
'experimental',
'memories',
'memory',
'personalization',
'personalize',
'personal settings',
'personalsettings',
'profile',
'user preferences', 'user preferences',
'accountpreferences' 'userpreferences'
] ]
}, },
{ {
id: 'audio', id: 'audio',
title: 'Audio', title: 'Audio',
keywords: [ keywords: [
'audio', 'audio config',
'sound',
'soundsettings',
'audio control', 'audio control',
'volume', 'audio features',
'speech', 'audio input',
'speechrecognition',
'stt',
'speechtotext',
'tts',
'texttospeech',
'playback',
'playbackspeed',
'voiceplayback',
'speechplayback',
'audio output', 'audio output',
'speechengine',
'voicecontrol',
'audio playback', 'audio playback',
'transcription',
'autotranscribe',
'autosend',
'speechsettings',
'audio voice', 'audio voice',
'voiceoptions', 'audioconfig',
'setvoice', 'audiocontrol',
'audiofeatures',
'audioinput',
'audiooutput',
'audioplayback',
'audiovoice',
'auto playback response',
'autoplaybackresponse',
'auto transcribe',
'autotranscribe',
'instant auto send after voice transcription',
'instantautosendaftervoicetranscription',
'language',
'non local voices',
'nonlocalvoices', 'nonlocalvoices',
'save settings', 'save settings',
'audioconfig', 'savesettings',
'set voice',
'setvoice',
'sound settings',
'soundsettings',
'speech config', 'speech config',
'voicerecognition',
'speechsynthesis',
'speech mode', 'speech mode',
'voicespeed', 'speech playback speed',
'speech rate', 'speech rate',
'speech recognition',
'speech settings',
'speech speed', 'speech speed',
'audioinput', 'speech synthesis',
'audiofeatures', 'speech to text engine',
'voicemodes' 'speechconfig',
'speechmode',
'speechplaybackspeed',
'speechrate',
'speechrecognition',
'speechsettings',
'speechspeed',
'speechsynthesis',
'speechtotextengine',
'speedch playback rate',
'speedchplaybackrate',
'stt settings',
'sttsettings',
'text to speech engine',
'text to speech',
'textospeechengine',
'texttospeech',
'texttospeechvoice',
'text to speech voice',
'voice control',
'voice modes',
'voice options',
'voice playback',
'voice recognition',
'voice speed',
'voicecontrol',
'voicemodes',
'voiceoptions',
'voiceplayback',
'voicerecognition',
'voicespeed',
'volume'
] ]
}, },
{ {
id: 'chats', id: 'chats',
title: 'Chats', title: 'Chats',
keywords: [ keywords: [
'chat', 'archive all chats',
'messages', 'archive chats',
'conversations', 'archiveallchats',
'chatsettings', 'archivechats',
'history', 'archived chats',
'archivedchats',
'chat activity',
'chat history', 'chat history',
'chat settings',
'chatactivity',
'chathistory',
'chatsettings',
'conversation activity',
'conversation history',
'conversationactivity',
'conversationhistory',
'conversations',
'convos',
'delete all chats',
'delete chats',
'deleteallchats',
'deletechats',
'export chats',
'exportchats',
'import chats',
'importchats',
'message activity',
'message archive',
'message history', 'message history',
'messagearchive', 'messagearchive',
'convo', 'messagehistory'
'chats',
'conversationhistory',
'exportmessages',
'chatactivity'
] ]
}, },
{ {
id: 'account', id: 'account',
title: 'Account', title: 'Account',
keywords: [ keywords: [
'account', 'account preferences',
'profile',
'security',
'privacy',
'settings',
'login',
'useraccount',
'userdata',
'api',
'apikey',
'userprofile',
'profiledetails',
'account settings', 'account settings',
'accountpreferences', 'accountpreferences',
'accountsettings',
'api keys',
'apikeys',
'change password',
'changepassword',
'jwt token',
'jwttoken',
'login',
'new password',
'newpassword',
'notification webhook url',
'notificationwebhookurl',
'personal settings',
'personalsettings',
'privacy settings',
'privacysettings',
'profileavatar',
'profile avatar',
'profile details',
'profile image',
'profile picture',
'profiledetails',
'profileimage',
'profilepicture',
'security settings', 'security settings',
'privacysettings' 'securitysettings',
] 'update account',
}, 'update password',
{ 'updateaccount',
id: 'admin', 'updatepassword',
title: 'Admin', 'user account',
keywords: [ 'user data',
'admin', 'user preferences',
'administrator', 'user profile',
'adminsettings', 'useraccount',
'adminpanel', 'userdata',
'systemadmin', 'username',
'administratoraccess', 'userpreferences',
'systemcontrol', 'userprofile',
'manage', 'webhook url',
'management', 'webhookurl'
'admincontrols',
'adminfeatures',
'usercontrol',
'arenamodel',
'evaluations',
'websearch',
'database',
'pipelines',
'images',
'audio',
'documents',
'rag',
'models',
'ollama',
'openai',
'users'
] ]
}, },
{ {
id: 'about', id: 'about',
title: 'About', title: 'About',
keywords: [ keywords: [
'about', 'about app',
'info', 'about me',
'information', 'about open webui',
'version', 'about page',
'documentation',
'help',
'support',
'details',
'about us', 'about us',
'softwareinfo', 'aboutapp',
'timothyjaeryangbaek', 'aboutme',
'openwebui', 'aboutopenwebui',
'aboutpage',
'aboutus',
'check for updates',
'checkforupdates',
'contact',
'copyright',
'details',
'discord',
'documentation',
'github',
'help',
'information',
'license',
'redistributions',
'release', 'release',
'updates', 'see whats new',
'seewhatsnew',
'settings',
'software info',
'softwareinfo',
'support',
'terms and conditions',
'terms of use',
'termsandconditions',
'termsofuse',
'timothy jae ryang baek',
'timothy j baek',
'timothyjaeryangbaek',
'timothyjbaek',
'twitter',
'update info',
'updateinfo', 'updateinfo',
'version info', 'version info',
'aboutapp', 'versioninfo'
'terms',
'termsandconditions',
'contact',
'aboutpage'
] ]
} }
]; ];
@ -405,7 +562,7 @@
<div class="flex flex-col md:flex-row w-full px-4 pt-1 pb-4 md:space-x-4"> <div class="flex flex-col md:flex-row w-full px-4 pt-1 pb-4 md:space-x-4">
<div <div
id="settings-tabs-container" id="settings-tabs-container"
class="tabs flex flex-row overflow-x-auto gap-2.5 md:gap-1 md:flex-col flex-1 md:flex-none md:w-40 dark:text-gray-200 text-sm font-medium text-left mb-1 md:mb-0 -translate-y-1" class="tabs flex flex-row overflow-x-auto gap-2.5 md:gap-1 md:flex-col flex-1 md:flex-none md:w-40 md:min-h-[32rem] md:max-h-[32rem] dark:text-gray-200 text-sm font-medium text-left mb-1 md:mb-0 -translate-y-1"
> >
<div class="hidden md:flex w-full rounded-xl -mb-1 px-0.5 gap-2" id="settings-search"> <div class="hidden md:flex w-full rounded-xl -mb-1 px-0.5 gap-2" id="settings-search">
<div class="self-center rounded-l-xl bg-transparent"> <div class="self-center rounded-l-xl bg-transparent">
@ -647,13 +804,17 @@
</div> </div>
<div class=" self-center">{$i18n.t('About')}</div> <div class=" self-center">{$i18n.t('About')}</div>
</button> </button>
{:else if tabId === 'admin'} {/if}
{/each}
{:else}
<div class="text-center text-gray-500 mt-4">
{$i18n.t('No results found')}
</div>
{/if}
{#if $user?.role === 'admin'} {#if $user?.role === 'admin'}
<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 text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white mt-auto"
'admin'
? ''
: ' text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'}"
on:click={async () => { on:click={async () => {
await goto('/admin/settings'); await goto('/admin/settings');
show = false; show = false;
@ -676,13 +837,6 @@
<div class=" self-center">{$i18n.t('Admin Settings')}</div> <div class=" self-center">{$i18n.t('Admin Settings')}</div>
</button> </button>
{/if} {/if}
{/if}
{/each}
{:else}
<div class="text-center text-gray-500 mt-4">
{$i18n.t('No results found')}
</div>
{/if}
</div> </div>
<div class="flex-1 md:min-h-[32rem] max-h-[32rem]"> <div class="flex-1 md:min-h-[32rem] max-h-[32rem]">
{#if selectedTab === 'general'} {#if selectedTab === 'general'}
@ -763,6 +917,7 @@
} }
input[type='number'] { input[type='number'] {
appearance: textfield;
-moz-appearance: textfield; /* Firefox */ -moz-appearance: textfield; /* Firefox */
} }
</style> </style>

View file

@ -13,6 +13,9 @@
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
async function loadLocale(locales) { async function loadLocale(locales) {
if (!locales || !Array.isArray(locales)) {
return;
}
for (const locale of locales) { for (const locale of locales) {
try { try {
dayjs.locale(locale); dayjs.locale(locale);

View file

@ -33,7 +33,9 @@
}); });
onDestroy(() => { onDestroy(() => {
if (observer) {
observer.disconnect(); observer.disconnect();
}
if (intervalId) { if (intervalId) {
clearInterval(intervalId); clearInterval(intervalId);

View file

@ -2,10 +2,8 @@
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import { onDestroy } from 'svelte'; import { onDestroy } from 'svelte';
import { marked } from 'marked';
import tippy from 'tippy.js'; import tippy from 'tippy.js';
import { roundArrow } from 'tippy.js';
export let placement = 'top'; export let placement = 'top';
export let content = `I'm a tooltip!`; export let content = `I'm a tooltip!`;
@ -47,6 +45,6 @@
}); });
</script> </script>
<div bind:this={tooltipElement} aria-label={DOMPurify.sanitize(content)} class={className}> <div bind:this={tooltipElement} class={className}>
<slot /> <slot />
</div> </div>

View file

@ -0,0 +1,12 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class={className}>
<path
fill-rule="evenodd"
d="M2.75 2a.75.75 0 0 1 .75.75v6.5h7.94l-.97-.97a.75.75 0 0 1 1.06-1.06l2.25 2.25a.75.75 0 0 1 0 1.06l-2.25 2.25a.75.75 0 1 1-1.06-1.06l.97-.97H2.75A.75.75 0 0 1 2 10V2.75A.75.75 0 0 1 2.75 2Z"
clip-rule="evenodd"
/>
</svg>

View file

@ -785,7 +785,7 @@
<div <div
class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900" class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900"
> >
{#each $pinnedChats as chat, idx} {#each $pinnedChats as chat, idx (`pinned-chat-${chat?.id ?? idx}`)}
<ChatItem <ChatItem
className="" className=""
id={chat.id} id={chat.id}
@ -831,7 +831,7 @@
<div class=" flex-1 flex flex-col overflow-y-auto scrollbar-hidden"> <div class=" flex-1 flex flex-col overflow-y-auto scrollbar-hidden">
<div class="pt-1.5"> <div class="pt-1.5">
{#if $chats} {#if $chats}
{#each $chats as chat, idx} {#each $chats as chat, idx (`chat-${chat?.id ?? idx}`)}
{#if idx === 0 || (idx > 0 && chat.time_range !== $chats[idx - 1].time_range)} {#if idx === 0 || (idx > 0 && chat.time_range !== $chats[idx - 1].time_range)}
<div <div
class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium {idx === class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium {idx ===

View file

@ -204,9 +204,10 @@
const chatTitleInputKeydownHandler = (e) => { const chatTitleInputKeydownHandler = (e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
e.preventDefault(); e.preventDefault();
editChatTitle(id, chatTitle); setTimeout(() => {
confirmEdit = false; const input = document.getElementById(`chat-title-input-${id}`);
chatTitle = ''; if (input) input.blur();
}, 0);
} else if (e.key === 'Escape') { } else if (e.key === 'Escape') {
e.preventDefault(); e.preventDefault();
confirmEdit = false; confirmEdit = false;

View file

@ -22,7 +22,7 @@
import ChevronRight from '../icons/ChevronRight.svelte'; import ChevronRight from '../icons/ChevronRight.svelte';
import Spinner from '../common/Spinner.svelte'; import Spinner from '../common/Spinner.svelte';
import Tooltip from '../common/Tooltip.svelte'; import Tooltip from '../common/Tooltip.svelte';
import { capitalizeFirstLetter } from '$lib/utils'; import { capitalizeFirstLetter, slugify } from '$lib/utils';
import XMark from '../icons/XMark.svelte'; import XMark from '../icons/XMark.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
@ -68,7 +68,15 @@
}; };
const cloneHandler = async (prompt) => { const cloneHandler = async (prompt) => {
sessionStorage.prompt = JSON.stringify(prompt); const clonedPrompt = { ...prompt };
clonedPrompt.title = `${clonedPrompt.title} (Clone)`;
const baseCommand = clonedPrompt.command.startsWith('/')
? clonedPrompt.command.substring(1)
: clonedPrompt.command;
clonedPrompt.command = slugify(`${baseCommand} clone`);
sessionStorage.prompt = JSON.stringify(clonedPrompt);
goto('/workspace/prompts/create'); goto('/workspace/prompts/create');
}; };

View file

@ -13,6 +13,7 @@
export let onSubmit: Function; export let onSubmit: Function;
export let edit = false; export let edit = false;
export let prompt = null; export let prompt = null;
export let clone = false;
const i18n = getContext('i18n'); const i18n = getContext('i18n');

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "هل أنت متأكد ؟", "Are you sure?": "هل أنت متأكد ؟",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "اتبعت التعليمات على أكمل وجه", "Followed instructions perfectly": "اتبعت التعليمات على أكمل وجه",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "كلمة المرور الجديدة", "New Password": "كلمة المرور الجديدة",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ملف (.pdf)", "PDF document (.pdf)": "PDF ملف (.pdf)",
"PDF Extract Images (OCR)": "PDF أستخرج الصور (OCR)", "PDF Extract Images (OCR)": "PDF أستخرج الصور (OCR)",
"pending": "قيد الانتظار", "pending": "قيد الانتظار",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "{{error}} تم رفض الإذن عند الوصول إلى الميكروفون ", "Permission denied when accessing microphone: {{error}}": "{{error}} تم رفض الإذن عند الوصول إلى الميكروفون ",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "التخصيص", "Personalization": "التخصيص",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "أخر 30 يوم", "Previous 30 days": "أخر 30 يوم",
"Previous 7 days": "أخر 7 أيام", "Previous 7 days": "أخر 7 أيام",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "صورة الملف الشخصي", "Profile Image": "صورة الملف الشخصي",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "هل أنت متأكد من رغبتك في حذف هذه القناة؟", "Are you sure you want to delete this channel?": "هل أنت متأكد من رغبتك في حذف هذه القناة؟",
"Are you sure you want to delete this message?": "هل أنت متأكد من رغبتك في حذف هذه الرسالة؟", "Are you sure you want to delete this message?": "هل أنت متأكد من رغبتك في حذف هذه الرسالة؟",
"Are you sure you want to unarchive all archived chats?": "هل أنت متأكد من رغبتك في إلغاء أرشفة جميع المحادثات المؤرشفة؟", "Are you sure you want to unarchive all archived chats?": "هل أنت متأكد من رغبتك في إلغاء أرشفة جميع المحادثات المؤرشفة؟",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "هل أنت متأكد؟", "Are you sure?": "هل أنت متأكد؟",
"Arena Models": "نماذج الساحة", "Arena Models": "نماذج الساحة",
"Artifacts": "القطع الأثرية", "Artifacts": "القطع الأثرية",
@ -611,6 +610,10 @@
"Folder deleted successfully": "تم حذف المجلد بنجاح", "Folder deleted successfully": "تم حذف المجلد بنجاح",
"Folder name cannot be empty.": "لا يمكن أن يكون اسم المجلد فارغًا.", "Folder name cannot be empty.": "لا يمكن أن يكون اسم المجلد فارغًا.",
"Folder name updated successfully": "تم تحديث اسم المجلد بنجاح", "Folder name updated successfully": "تم تحديث اسم المجلد بنجاح",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "اتبعت التعليمات على أكمل وجه", "Followed instructions perfectly": "اتبعت التعليمات على أكمل وجه",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "كلمة المرور الجديدة", "New Password": "كلمة المرور الجديدة",
"New Tool": "", "New Tool": "",
"new-channel": "قناة جديدة", "new-channel": "قناة جديدة",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ملف (.pdf)", "PDF document (.pdf)": "PDF ملف (.pdf)",
"PDF Extract Images (OCR)": "PDF أستخرج الصور (OCR)", "PDF Extract Images (OCR)": "PDF أستخرج الصور (OCR)",
"pending": "قيد الانتظار", "pending": "قيد الانتظار",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "تم رفض الإذن عند محاولة الوصول إلى أجهزة الوسائط", "Permission denied when accessing media devices": "تم رفض الإذن عند محاولة الوصول إلى أجهزة الوسائط",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "{{error}} تم رفض الإذن عند الوصول إلى الميكروفون ", "Permission denied when accessing microphone: {{error}}": "{{error}} تم رفض الإذن عند الوصول إلى الميكروفون ",
"Permissions": "الأذونات", "Permissions": "الأذونات",
"Perplexity API Key": "مفتاح API لـ Perplexity", "Perplexity API Key": "مفتاح API لـ Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "التخصيص", "Personalization": "التخصيص",
"Pin": "تثبيت", "Pin": "تثبيت",
"Pinned": "مثبت", "Pinned": "مثبت",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "أخر 30 يوم", "Previous 30 days": "أخر 30 يوم",
"Previous 7 days": "أخر 7 أيام", "Previous 7 days": "أخر 7 أيام",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "صورة الملف الشخصي", "Profile Image": "صورة الملف الشخصي",
"Prompt": "التوجيه", "Prompt": "التوجيه",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Сигурни ли сте, че искате да изтриете този канал?", "Are you sure you want to delete this channel?": "Сигурни ли сте, че искате да изтриете този канал?",
"Are you sure you want to delete this message?": "Сигурни ли сте, че искате да изтриете това съобщение?", "Are you sure you want to delete this message?": "Сигурни ли сте, че искате да изтриете това съобщение?",
"Are you sure you want to unarchive all archived chats?": "Сигурни ли сте, че искате да разархивирате всички архивирани чатове?", "Are you sure you want to unarchive all archived chats?": "Сигурни ли сте, че искате да разархивирате всички архивирани чатове?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Сигурни ли сте?", "Are you sure?": "Сигурни ли сте?",
"Arena Models": "Арена Модели", "Arena Models": "Арена Модели",
"Artifacts": "Артефакти", "Artifacts": "Артефакти",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Папката е изтрита успешно", "Folder deleted successfully": "Папката е изтрита успешно",
"Folder name cannot be empty.": "Името на папката не може да бъде празно.", "Folder name cannot be empty.": "Името на папката не може да бъде празно.",
"Folder name updated successfully": "Името на папката е актуализирано успешно", "Folder name updated successfully": "Името на папката е актуализирано успешно",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Следвайте инструкциите перфектно", "Followed instructions perfectly": "Следвайте инструкциите перфектно",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Нова парола", "New Password": "Нова парола",
"New Tool": "", "New Tool": "",
"new-channel": "нов-канал", "new-channel": "нов-канал",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "Без съдържание", "No content": "Без съдържание",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF документ (.pdf)", "PDF document (.pdf)": "PDF документ (.pdf)",
"PDF Extract Images (OCR)": "Извличане на изображения от PDF (OCR)", "PDF Extract Images (OCR)": "Извличане на изображения от PDF (OCR)",
"pending": "в очакване", "pending": "в очакване",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Отказан достъп при опит за достъп до медийни устройства", "Permission denied when accessing media devices": "Отказан достъп при опит за достъп до медийни устройства",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Отказан достъп при опит за достъп до микрофона: {{error}}", "Permission denied when accessing microphone: {{error}}": "Отказан достъп при опит за достъп до микрофона: {{error}}",
"Permissions": "Разрешения", "Permissions": "Разрешения",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Персонализация", "Personalization": "Персонализация",
"Pin": "Закачи", "Pin": "Закачи",
"Pinned": "Закачено", "Pinned": "Закачено",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Предишните 30 дни", "Previous 30 days": "Предишните 30 дни",
"Previous 7 days": "Предишните 7 дни", "Previous 7 days": "Предишните 7 дни",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Профилна снимка", "Profile Image": "Профилна снимка",
"Prompt": "Промпт", "Prompt": "Промпт",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "আপনি নিশ্চিত?", "Are you sure?": "আপনি নিশ্চিত?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "নির্দেশাবলী নিখুঁতভাবে অনুসরণ করা হয়েছে", "Followed instructions perfectly": "নির্দেশাবলী নিখুঁতভাবে অনুসরণ করা হয়েছে",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "নতুন পাসওয়ার্ড", "New Password": "নতুন পাসওয়ার্ড",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ডকুমেন্ট (.pdf)", "PDF document (.pdf)": "PDF ডকুমেন্ট (.pdf)",
"PDF Extract Images (OCR)": "পিডিএফ এর ছবি থেকে লেখা বের করুন (OCR)", "PDF Extract Images (OCR)": "পিডিএফ এর ছবি থেকে লেখা বের করুন (OCR)",
"pending": "অপেক্ষমান", "pending": "অপেক্ষমান",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "মাইক্রোফোন ব্যবহারের অনুমতি পাওয়া যায়নি: {{error}}", "Permission denied when accessing microphone: {{error}}": "মাইক্রোফোন ব্যবহারের অনুমতি পাওয়া যায়নি: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "ডিজিটাল বাংলা", "Personalization": "ডিজিটাল বাংলা",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "পূর্ব ৩০ দিন", "Previous 30 days": "পূর্ব ৩০ দিন",
"Previous 7 days": "পূর্ব দিন", "Previous 7 days": "পূর্ব দিন",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "প্রোফাইল ইমেজ", "Profile Image": "প্রোফাইল ইমেজ",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "ཁྱེད་ཀྱིས་བགྲོ་གླེང་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།", "Are you sure you want to delete this channel?": "ཁྱེད་ཀྱིས་བགྲོ་གླེང་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།",
"Are you sure you want to delete this message?": "འཕྲིན་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།", "Are you sure you want to delete this message?": "འཕྲིན་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།",
"Are you sure you want to unarchive all archived chats?": "ཁྱེད་ཀྱིས་ཡིག་མཛོད་དུ་བཞག་པའི་ཁ་བརྡ་ཡོངས་རྫོགས་ཕྱིར་འདོན་འདོད་ངེས་ཡིན་ནམ།", "Are you sure you want to unarchive all archived chats?": "ཁྱེད་ཀྱིས་ཡིག་མཛོད་དུ་བཞག་པའི་ཁ་བརྡ་ཡོངས་རྫོགས་ཕྱིར་འདོན་འདོད་ངེས་ཡིན་ནམ།",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "ཁྱོད་ངེས་པ་ཡིན་ནམ།", "Are you sure?": "ཁྱོད་ངེས་པ་ཡིན་ནམ།",
"Arena Models": "Arena དཔེ་དབྱིབས།", "Arena Models": "Arena དཔེ་དབྱིབས།",
"Artifacts": "རྫས་རྟེན།", "Artifacts": "རྫས་རྟེན།",
@ -611,6 +610,10 @@
"Folder deleted successfully": "ཡིག་སྣོད་ལེགས་པར་བསུབས་ཟིན།", "Folder deleted successfully": "ཡིག་སྣོད་ལེགས་པར་བསུབས་ཟིན།",
"Folder name cannot be empty.": "ཡིག་སྣོད་ཀྱི་མིང་སྟོང་པ་ཡིན་མི་ཆོག", "Folder name cannot be empty.": "ཡིག་སྣོད་ཀྱི་མིང་སྟོང་པ་ཡིན་མི་ཆོག",
"Folder name updated successfully": "ཡིག་སྣོད་ཀྱི་མིང་ལེགས་པར་གསར་སྒྱུར་བྱས་ཟིན།", "Folder name updated successfully": "ཡིག་སྣོད་ཀྱི་མིང་ལེགས་པར་གསར་སྒྱུར་བྱས་ཟིན།",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "ལམ་སྟོན་ཡང་དག་པར་བསྒྲུབས།", "Followed instructions perfectly": "ལམ་སྟོན་ཡང་དག་པར་བསྒྲུབས།",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "གསང་གྲངས་གསར་པ།", "New Password": "གསང་གྲངས་གསར་པ།",
"New Tool": "", "New Tool": "",
"new-channel": "བགྲོ་གླེང་གསར་པ།", "new-channel": "བགྲོ་གླེང་གསར་པ།",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ཡིག་ཆ། (.pdf)", "PDF document (.pdf)": "PDF ཡིག་ཆ། (.pdf)",
"PDF Extract Images (OCR)": "PDF པར་འདོན་སྤེལ། (OCR)", "PDF Extract Images (OCR)": "PDF པར་འདོན་སྤེལ། (OCR)",
"pending": "སྒུག་བཞིན་པ།", "pending": "སྒུག་བཞིན་པ།",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "བརྒྱུད་ལམ་སྒྲིག་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།", "Permission denied when accessing media devices": "བརྒྱུད་ལམ་སྒྲིག་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "སྐད་སྒྲ་འཛིན་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།: {{error}}", "Permission denied when accessing microphone: {{error}}": "སྐད་སྒྲ་འཛིན་ཆས་འཛུལ་སྤྱོད་སྐབས་དབང་ཚད་ཁས་མ་བླངས།: {{error}}",
"Permissions": "དབང་ཚད།", "Permissions": "དབང་ཚད།",
"Perplexity API Key": "Perplexity API ལྡེ་མིག", "Perplexity API Key": "Perplexity API ལྡེ་མིག",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "སྒེར་སྤྱོད་ཅན།", "Personalization": "སྒེར་སྤྱོད་ཅན།",
"Pin": "གདབ་པ།", "Pin": "གདབ་པ།",
"Pinned": "གདབ་ཟིན།", "Pinned": "གདབ་ཟིན།",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "ཉིན་ ༣༠ སྔོན་མ།", "Previous 30 days": "ཉིན་ ༣༠ སྔོན་མ།",
"Previous 7 days": "ཉིན་ ༧ སྔོན་མ།", "Previous 7 days": "ཉིན་ ༧ སྔོན་མ།",
"Previous message": "",
"Private": "སྒེར།", "Private": "སྒེར།",
"Profile Image": "སྤྱི་ཐག་པར།", "Profile Image": "སྤྱི་ཐག་པར།",
"Prompt": "འགུལ་སློང་།", "Prompt": "འགུལ་སློང་།",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Estàs segur que vols eliminar aquest canal?", "Are you sure you want to delete this channel?": "Estàs segur que vols eliminar aquest canal?",
"Are you sure you want to delete this message?": "Estàs segur que vols eliminar aquest missatge?", "Are you sure you want to delete this message?": "Estàs segur que vols eliminar aquest missatge?",
"Are you sure you want to unarchive all archived chats?": "Estàs segur que vols desarxivar tots els xats arxivats?", "Are you sure you want to unarchive all archived chats?": "Estàs segur que vols desarxivar tots els xats arxivats?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "Estàs segur que vols actualitzar el rol de l'usuari a **{{ROLE}}**?",
"Are you sure?": "Estàs segur?", "Are you sure?": "Estàs segur?",
"Arena Models": "Models de l'Arena", "Arena Models": "Models de l'Arena",
"Artifacts": "Artefactes", "Artifacts": "Artefactes",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Carpeta eliminada correctament", "Folder deleted successfully": "Carpeta eliminada correctament",
"Folder name cannot be empty.": "El nom de la carpeta no pot ser buit.", "Folder name cannot be empty.": "El nom de la carpeta no pot ser buit.",
"Folder name updated successfully": "Nom de la carpeta actualitzat correctament", "Folder name updated successfully": "Nom de la carpeta actualitzat correctament",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "S'han seguit les instruccions perfectament", "Followed instructions perfectly": "S'han seguit les instruccions perfectament",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nova contrasenya", "New Password": "Nova contrasenya",
"New Tool": "", "New Tool": "",
"new-channel": "nou-canal", "new-channel": "nou-canal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "No hi ha contingut", "No content": "No hi ha contingut",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Document PDF (.pdf)", "PDF document (.pdf)": "Document PDF (.pdf)",
"PDF Extract Images (OCR)": "Extreu imatges del PDF (OCR)", "PDF Extract Images (OCR)": "Extreu imatges del PDF (OCR)",
"pending": "pendent", "pending": "pendent",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Permís denegat en accedir a dispositius multimèdia", "Permission denied when accessing media devices": "Permís denegat en accedir a dispositius multimèdia",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}", "Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}",
"Permissions": "Permisos", "Permissions": "Permisos",
"Perplexity API Key": "Clau API de Perplexity", "Perplexity API Key": "Clau API de Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalització", "Personalization": "Personalització",
"Pin": "Fixar", "Pin": "Fixar",
"Pinned": "Fixat", "Pinned": "Fixat",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 dies anteriors", "Previous 30 days": "30 dies anteriors",
"Previous 7 days": "7 dies anteriors", "Previous 7 days": "7 dies anteriors",
"Previous message": "",
"Private": "Privat", "Private": "Privat",
"Profile Image": "Imatge de perfil", "Profile Image": "Imatge de perfil",
"Prompt": "Indicació", "Prompt": "Indicació",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Sigurado ka ?", "Are you sure?": "Sigurado ka ?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "", "Followed instructions perfectly": "",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Bag-ong Password", "New Password": "Bag-ong Password",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "", "PDF document (.pdf)": "",
"PDF Extract Images (OCR)": "PDF Image Extraction (OCR)", "PDF Extract Images (OCR)": "PDF Image Extraction (OCR)",
"pending": "gipugngan", "pending": "gipugngan",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Gidili ang pagtugot sa dihang nag-access sa mikropono: {{error}}", "Permission denied when accessing microphone: {{error}}": "Gidili ang pagtugot sa dihang nag-access sa mikropono: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "", "Personalization": "",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "", "Previous 30 days": "",
"Previous 7 days": "", "Previous 7 days": "",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "", "Profile Image": "",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Jste si jistý?", "Are you sure?": "Jste si jistý?",
"Arena Models": "Arena modely", "Arena Models": "Arena modely",
"Artifacts": "Artefakty", "Artifacts": "Artefakty",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Složka byla úspěšně smazána", "Folder deleted successfully": "Složka byla úspěšně smazána",
"Folder name cannot be empty.": "Název složky nesmí být prázdný.", "Folder name cannot be empty.": "Název složky nesmí být prázdný.",
"Folder name updated successfully": "Název složky byl úspěšně aktualizován.", "Folder name updated successfully": "Název složky byl úspěšně aktualizován.",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Dodržel pokyny dokonale.", "Followed instructions perfectly": "Dodržel pokyny dokonale.",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nové heslo", "New Password": "Nové heslo",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokument (.pdf)", "PDF document (.pdf)": "PDF dokument (.pdf)",
"PDF Extract Images (OCR)": "Extrahování obrázků z PDF (OCR)", "PDF Extract Images (OCR)": "Extrahování obrázků z PDF (OCR)",
"pending": "čeká na vyřízení", "pending": "čeká na vyřízení",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Odmítnutí povolení při přístupu k mediálním zařízením", "Permission denied when accessing media devices": "Odmítnutí povolení při přístupu k mediálním zařízením",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Oprávnění zamítnuto při přístupu k mikrofonu: {{error}}", "Permission denied when accessing microphone: {{error}}": "Oprávnění zamítnuto při přístupu k mikrofonu: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizace", "Personalization": "Personalizace",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Předchozích 30 dnů", "Previous 30 days": "Předchozích 30 dnů",
"Previous 7 days": "Předchozích 7 dní", "Previous 7 days": "Předchozích 7 dní",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profilový obrázek", "Profile Image": "Profilový obrázek",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Er du sikker på du vil slette denne kanal?", "Are you sure you want to delete this channel?": "Er du sikker på du vil slette denne kanal?",
"Are you sure you want to delete this message?": "Er du sikker på du vil slette denne besked?", "Are you sure you want to delete this message?": "Er du sikker på du vil slette denne besked?",
"Are you sure you want to unarchive all archived chats?": "Er du sikker på du vil fjerne alle arkiverede chats?", "Are you sure you want to unarchive all archived chats?": "Er du sikker på du vil fjerne alle arkiverede chats?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Er du sikker?", "Are you sure?": "Er du sikker?",
"Arena Models": "Arena Modeller", "Arena Models": "Arena Modeller",
"Artifacts": "Artifakter", "Artifacts": "Artifakter",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Mappe fjernet.", "Folder deleted successfully": "Mappe fjernet.",
"Folder name cannot be empty.": "Mappenavn kan ikke være tom.", "Folder name cannot be empty.": "Mappenavn kan ikke være tom.",
"Folder name updated successfully": "Mappenavn opdateret.", "Folder name updated successfully": "Mappenavn opdateret.",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Fulgte instruktionerne perfekt", "Followed instructions perfectly": "Fulgte instruktionerne perfekt",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Ny adgangskode", "New Password": "Ny adgangskode",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "Næste besked",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "Intet indhold", "No content": "Intet indhold",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF-dokument (.pdf)", "PDF document (.pdf)": "PDF-dokument (.pdf)",
"PDF Extract Images (OCR)": "Udtræk billeder fra PDF (OCR)", "PDF Extract Images (OCR)": "Udtræk billeder fra PDF (OCR)",
"pending": "afventer", "pending": "afventer",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Tilladelse nægtet ved adgang til medieenheder", "Permission denied when accessing media devices": "Tilladelse nægtet ved adgang til medieenheder",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Tilladelse nægtet ved adgang til mikrofon: {{error}}", "Permission denied when accessing microphone: {{error}}": "Tilladelse nægtet ved adgang til mikrofon: {{error}}",
"Permissions": "Tilladelser", "Permissions": "Tilladelser",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalisering", "Personalization": "Personalisering",
"Pin": "Fastgør", "Pin": "Fastgør",
"Pinned": "Fastgjort", "Pinned": "Fastgjort",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Seneste 30 dage", "Previous 30 days": "Seneste 30 dage",
"Previous 7 days": "Seneste 7 dage", "Previous 7 days": "Seneste 7 dage",
"Previous message": "Forrige besked",
"Private": "Privat", "Private": "Privat",
"Profile Image": "Profilbillede", "Profile Image": "Profilbillede",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Sind Sie sicher, dass Sie diesen Kanal löschen möchten?", "Are you sure you want to delete this channel?": "Sind Sie sicher, dass Sie diesen Kanal löschen möchten?",
"Are you sure you want to delete this message?": "Sind Sie sicher, dass Sie diese Nachricht löschen möchten?", "Are you sure you want to delete this message?": "Sind Sie sicher, dass Sie diese Nachricht löschen möchten?",
"Are you sure you want to unarchive all archived chats?": "Sind Sie sicher, dass Sie alle archivierten Chats wiederherstellen möchten?", "Are you sure you want to unarchive all archived chats?": "Sind Sie sicher, dass Sie alle archivierten Chats wiederherstellen möchten?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "Sind Sie sicher, dass Sie die Rolle dieses Benutzers auf **{{ROLE}}** ändern möchten?",
"Are you sure?": "Sind Sie sicher?", "Are you sure?": "Sind Sie sicher?",
"Arena Models": "Arena-Modelle", "Arena Models": "Arena-Modelle",
"Artifacts": "Artefakte", "Artifacts": "Artefakte",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Ordner erfolgreich gelöscht", "Folder deleted successfully": "Ordner erfolgreich gelöscht",
"Folder name cannot be empty.": "Ordnername darf nicht leer sein.", "Folder name cannot be empty.": "Ordnername darf nicht leer sein.",
"Folder name updated successfully": "Ordnername erfolgreich aktualisiert", "Folder name updated successfully": "Ordnername erfolgreich aktualisiert",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Anweisungen perfekt befolgt", "Followed instructions perfectly": "Anweisungen perfekt befolgt",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Neues Passwort", "New Password": "Neues Passwort",
"New Tool": "", "New Tool": "",
"new-channel": "neuer-kanal", "new-channel": "neuer-kanal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "Kein Inhalt", "No content": "Kein Inhalt",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF-Dokument (.pdf)", "PDF document (.pdf)": "PDF-Dokument (.pdf)",
"PDF Extract Images (OCR)": "Text von Bildern aus PDFs extrahieren (OCR)", "PDF Extract Images (OCR)": "Text von Bildern aus PDFs extrahieren (OCR)",
"pending": "ausstehend", "pending": "ausstehend",
"Pending": "",
"Pending User Overlay Content": "Inhalt des Overlays 'Ausstehende Kontoaktivierung'", "Pending User Overlay Content": "Inhalt des Overlays 'Ausstehende Kontoaktivierung'",
"Pending User Overlay Title": "Titel des Overlays 'Ausstehende Kontoaktivierung'", "Pending User Overlay Title": "Titel des Overlays 'Ausstehende Kontoaktivierung'",
"Permission denied when accessing media devices": "Zugriff auf Mediengeräte verweigert", "Permission denied when accessing media devices": "Zugriff auf Mediengeräte verweigert",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Zugriff auf das Mikrofon verweigert: {{error}}", "Permission denied when accessing microphone: {{error}}": "Zugriff auf das Mikrofon verweigert: {{error}}",
"Permissions": "Berechtigungen", "Permissions": "Berechtigungen",
"Perplexity API Key": "Perplexity API-Schlüssel", "Perplexity API Key": "Perplexity API-Schlüssel",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalisierung", "Personalization": "Personalisierung",
"Pin": "Anheften", "Pin": "Anheften",
"Pinned": "Angeheftet", "Pinned": "Angeheftet",
@ -965,6 +972,7 @@
"Preview": "Vorschau", "Preview": "Vorschau",
"Previous 30 days": "Vorherige 30 Tage", "Previous 30 days": "Vorherige 30 Tage",
"Previous 7 days": "Vorherige 7 Tage", "Previous 7 days": "Vorherige 7 Tage",
"Previous message": "",
"Private": "Privat", "Private": "Privat",
"Profile Image": "Profilbild", "Profile Image": "Profilbild",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Such certainty?", "Are you sure?": "Such certainty?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "", "Followed instructions perfectly": "",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "New Barkword", "New Password": "New Barkword",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "", "PDF document (.pdf)": "",
"PDF Extract Images (OCR)": "PDF Extract Wowmages (OCR)", "PDF Extract Images (OCR)": "PDF Extract Wowmages (OCR)",
"pending": "pending", "pending": "pending",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}", "Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalization", "Personalization": "Personalization",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "", "Previous 30 days": "",
"Previous 7 days": "", "Previous 7 days": "",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "", "Profile Image": "",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "Είστε σίγουροι ότι θέλετε να απο-αρχειοθετήσετε όλες τις αρχειοθετημένες συνομιλίες;", "Are you sure you want to unarchive all archived chats?": "Είστε σίγουροι ότι θέλετε να απο-αρχειοθετήσετε όλες τις αρχειοθετημένες συνομιλίες;",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Είστε σίγουροι;", "Are you sure?": "Είστε σίγουροι;",
"Arena Models": "Μοντέλα Arena", "Arena Models": "Μοντέλα Arena",
"Artifacts": "Αρχεία", "Artifacts": "Αρχεία",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Ο φάκελος διαγράφηκε με επιτυχία", "Folder deleted successfully": "Ο φάκελος διαγράφηκε με επιτυχία",
"Folder name cannot be empty.": "Το όνομα του φακέλου δεν μπορεί να είναι κενό.", "Folder name cannot be empty.": "Το όνομα του φακέλου δεν μπορεί να είναι κενό.",
"Folder name updated successfully": "Το όνομα του φακέλου ενημερώθηκε με επιτυχία", "Folder name updated successfully": "Το όνομα του φακέλου ενημερώθηκε με επιτυχία",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Ακολούθησε τις οδηγίες τέλεια", "Followed instructions perfectly": "Ακολούθησε τις οδηγίες τέλεια",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Νέος Κωδικός", "New Password": "Νέος Κωδικός",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Έγγραφο PDF (.pdf)", "PDF document (.pdf)": "Έγγραφο PDF (.pdf)",
"PDF Extract Images (OCR)": "Εξαγωγή Εικόνων PDF (OCR)", "PDF Extract Images (OCR)": "Εξαγωγή Εικόνων PDF (OCR)",
"pending": "εκκρεμεί", "pending": "εκκρεμεί",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Άρνηση δικαιώματος κατά την πρόσβαση σε μέσα συσκευές", "Permission denied when accessing media devices": "Άρνηση δικαιώματος κατά την πρόσβαση σε μέσα συσκευές",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Άρνηση δικαιώματος κατά την πρόσβαση σε μικρόφωνο: {{error}}", "Permission denied when accessing microphone: {{error}}": "Άρνηση δικαιώματος κατά την πρόσβαση σε μικρόφωνο: {{error}}",
"Permissions": "Δικαιώματα", "Permissions": "Δικαιώματα",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Προσωποποίηση", "Personalization": "Προσωποποίηση",
"Pin": "Καρφίτσωμα", "Pin": "Καρφίτσωμα",
"Pinned": "Καρφιτσωμένο", "Pinned": "Καρφιτσωμένο",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Προηγούμενες 30 ημέρες", "Previous 30 days": "Προηγούμενες 30 ημέρες",
"Previous 7 days": "Προηγούμενες 7 ημέρες", "Previous 7 days": "Προηγούμενες 7 ημέρες",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Εικόνα Προφίλ", "Profile Image": "Εικόνα Προφίλ",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "", "Are you sure?": "",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "", "Followed instructions perfectly": "",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "", "New Password": "",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "", "PDF document (.pdf)": "",
"PDF Extract Images (OCR)": "", "PDF Extract Images (OCR)": "",
"pending": "", "pending": "",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "", "Permission denied when accessing microphone: {{error}}": "",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "", "Personalization": "",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "", "Previous 30 days": "",
"Previous 7 days": "", "Previous 7 days": "",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "", "Profile Image": "",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "", "Are you sure?": "",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "", "Followed instructions perfectly": "",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "", "New Password": "",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "Next message",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "", "PDF document (.pdf)": "",
"PDF Extract Images (OCR)": "", "PDF Extract Images (OCR)": "",
"pending": "", "pending": "",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "", "Permission denied when accessing microphone: {{error}}": "",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "", "Personalization": "",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "", "Previous 30 days": "",
"Previous 7 days": "", "Previous 7 days": "",
"Previous message": "Previous message",
"Private": "", "Private": "",
"Profile Image": "", "Profile Image": "",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "¿Seguro de que quieres eliminar este canal?", "Are you sure you want to delete this channel?": "¿Seguro de que quieres eliminar este canal?",
"Are you sure you want to delete this message?": "¿Seguro de que quieres eliminar este mensaje? ", "Are you sure you want to delete this message?": "¿Seguro de que quieres eliminar este mensaje? ",
"Are you sure you want to unarchive all archived chats?": "¿Seguro de que quieres desarchivar todos los chats archivados?", "Are you sure you want to unarchive all archived chats?": "¿Seguro de que quieres desarchivar todos los chats archivados?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "¿Estás seguro?", "Are you sure?": "¿Estás seguro?",
"Arena Models": "Arena de Modelos", "Arena Models": "Arena de Modelos",
"Artifacts": "Artefactos", "Artifacts": "Artefactos",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Carpeta eliminada correctamente", "Folder deleted successfully": "Carpeta eliminada correctamente",
"Folder name cannot be empty.": "El nombre de la carpeta no puede estar vacío", "Folder name cannot be empty.": "El nombre de la carpeta no puede estar vacío",
"Folder name updated successfully": "Nombre de la carpeta actualizado correctamente", "Folder name updated successfully": "Nombre de la carpeta actualizado correctamente",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Siguió las instrucciones perfectamente", "Followed instructions perfectly": "Siguió las instrucciones perfectamente",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nueva Contraseña", "New Password": "Nueva Contraseña",
"New Tool": "", "New Tool": "",
"new-channel": "nuevo-canal", "new-channel": "nuevo-canal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Documento PDF (.pdf)", "PDF document (.pdf)": "Documento PDF (.pdf)",
"PDF Extract Images (OCR)": "Extraer imágenes del PDF (OCR)", "PDF Extract Images (OCR)": "Extraer imágenes del PDF (OCR)",
"pending": "pendiente", "pending": "pendiente",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Permiso denegado accediendo a los dispositivos", "Permission denied when accessing media devices": "Permiso denegado accediendo a los dispositivos",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permiso denegado accediendo al micrófono: {{error}}", "Permission denied when accessing microphone: {{error}}": "Permiso denegado accediendo al micrófono: {{error}}",
"Permissions": "Permisos", "Permissions": "Permisos",
"Perplexity API Key": "Clave API de Perplexity", "Perplexity API Key": "Clave API de Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalización", "Personalization": "Personalización",
"Pin": "Fijar", "Pin": "Fijar",
"Pinned": "Fijado", "Pinned": "Fijado",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 días previos", "Previous 30 days": "30 días previos",
"Previous 7 days": "7 días previos", "Previous 7 days": "7 días previos",
"Previous message": "",
"Private": "Privado", "Private": "Privado",
"Profile Image": "Imagen del Perfil", "Profile Image": "Imagen del Perfil",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Kas olete kindel, et soovite selle kanali kustutada?", "Are you sure you want to delete this channel?": "Kas olete kindel, et soovite selle kanali kustutada?",
"Are you sure you want to delete this message?": "Kas olete kindel, et soovite selle sõnumi kustutada?", "Are you sure you want to delete this message?": "Kas olete kindel, et soovite selle sõnumi kustutada?",
"Are you sure you want to unarchive all archived chats?": "Kas olete kindel, et soovite kõik arhiveeritud vestlused arhiivist eemaldada?", "Are you sure you want to unarchive all archived chats?": "Kas olete kindel, et soovite kõik arhiveeritud vestlused arhiivist eemaldada?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Kas olete kindel?", "Are you sure?": "Kas olete kindel?",
"Arena Models": "Areena mudelid", "Arena Models": "Areena mudelid",
"Artifacts": "Tekkinud objektid", "Artifacts": "Tekkinud objektid",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Kaust edukalt kustutatud", "Folder deleted successfully": "Kaust edukalt kustutatud",
"Folder name cannot be empty.": "Kausta nimi ei saa olla tühi.", "Folder name cannot be empty.": "Kausta nimi ei saa olla tühi.",
"Folder name updated successfully": "Kausta nimi edukalt uuendatud", "Folder name updated successfully": "Kausta nimi edukalt uuendatud",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Järgis juhiseid täiuslikult", "Followed instructions perfectly": "Järgis juhiseid täiuslikult",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Uus parool", "New Password": "Uus parool",
"New Tool": "", "New Tool": "",
"new-channel": "uus-kanal", "new-channel": "uus-kanal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokument (.pdf)", "PDF document (.pdf)": "PDF dokument (.pdf)",
"PDF Extract Images (OCR)": "PDF-ist piltide väljavõtmine (OCR)", "PDF Extract Images (OCR)": "PDF-ist piltide väljavõtmine (OCR)",
"pending": "ootel", "pending": "ootel",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Juurdepääs meediumiseadmetele keelatud", "Permission denied when accessing media devices": "Juurdepääs meediumiseadmetele keelatud",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Juurdepääs mikrofonile keelatud: {{error}}", "Permission denied when accessing microphone: {{error}}": "Juurdepääs mikrofonile keelatud: {{error}}",
"Permissions": "Õigused", "Permissions": "Õigused",
"Perplexity API Key": "Perplexity API võti", "Perplexity API Key": "Perplexity API võti",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Isikupärastamine", "Personalization": "Isikupärastamine",
"Pin": "Kinnita", "Pin": "Kinnita",
"Pinned": "Kinnitatud", "Pinned": "Kinnitatud",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Eelmised 30 päeva", "Previous 30 days": "Eelmised 30 päeva",
"Previous 7 days": "Eelmised 7 päeva", "Previous 7 days": "Eelmised 7 päeva",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profiilipilt", "Profile Image": "Profiilipilt",
"Prompt": "Vihje", "Prompt": "Vihje",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "Ziur zaude artxibatutako txat guztiak desartxibatu nahi dituzula?", "Are you sure you want to unarchive all archived chats?": "Ziur zaude artxibatutako txat guztiak desartxibatu nahi dituzula?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Ziur zaude?", "Are you sure?": "Ziur zaude?",
"Arena Models": "Arena Ereduak", "Arena Models": "Arena Ereduak",
"Artifacts": "Artefaktuak", "Artifacts": "Artefaktuak",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Karpeta ongi ezabatu da", "Folder deleted successfully": "Karpeta ongi ezabatu da",
"Folder name cannot be empty.": "Karpetaren izena ezin da hutsik egon.", "Folder name cannot be empty.": "Karpetaren izena ezin da hutsik egon.",
"Folder name updated successfully": "Karpetaren izena ongi eguneratu da", "Folder name updated successfully": "Karpetaren izena ongi eguneratu da",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Jarraibideak perfektuki jarraitu ditu", "Followed instructions perfectly": "Jarraibideak perfektuki jarraitu ditu",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Pasahitz berria", "New Password": "Pasahitz berria",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokumentua (.pdf)", "PDF document (.pdf)": "PDF dokumentua (.pdf)",
"PDF Extract Images (OCR)": "PDF irudiak erauzi (OCR)", "PDF Extract Images (OCR)": "PDF irudiak erauzi (OCR)",
"pending": "zain", "pending": "zain",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Baimena ukatu da multimedia gailuak atzitzean", "Permission denied when accessing media devices": "Baimena ukatu da multimedia gailuak atzitzean",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Baimena ukatu da mikrofonoa atzitzean: {{error}}", "Permission denied when accessing microphone: {{error}}": "Baimena ukatu da mikrofonoa atzitzean: {{error}}",
"Permissions": "Baimenak", "Permissions": "Baimenak",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Pertsonalizazioa", "Personalization": "Pertsonalizazioa",
"Pin": "Ainguratu", "Pin": "Ainguratu",
"Pinned": "Ainguratuta", "Pinned": "Ainguratuta",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Aurreko 30 egunak", "Previous 30 days": "Aurreko 30 egunak",
"Previous 7 days": "Aurreko 7 egunak", "Previous 7 days": "Aurreko 7 egunak",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profil irudia", "Profile Image": "Profil irudia",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "آیا مطمئن هستید که می\u200cخواهید این کانال را حذف کنید؟", "Are you sure you want to delete this channel?": "آیا مطمئن هستید که می\u200cخواهید این کانال را حذف کنید؟",
"Are you sure you want to delete this message?": "آیا مطمئن هستید که می\u200cخواهید این پیام را حذف کنید؟", "Are you sure you want to delete this message?": "آیا مطمئن هستید که می\u200cخواهید این پیام را حذف کنید؟",
"Are you sure you want to unarchive all archived chats?": "آیا مطمئن هستید که می\u200cخواهید همه گفتگوهای بایگانی شده را از بایگانی خارج کنید؟", "Are you sure you want to unarchive all archived chats?": "آیا مطمئن هستید که می\u200cخواهید همه گفتگوهای بایگانی شده را از بایگانی خارج کنید؟",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "مطمئنید؟", "Are you sure?": "مطمئنید؟",
"Arena Models": "مدل\u200cهای آرنا", "Arena Models": "مدل\u200cهای آرنا",
"Artifacts": "مصنوعات", "Artifacts": "مصنوعات",
@ -611,6 +610,10 @@
"Folder deleted successfully": "پوشه با موفقیت حذف شد", "Folder deleted successfully": "پوشه با موفقیت حذف شد",
"Folder name cannot be empty.": "نام پوشه نمی\u200cتواند خالی باشد.", "Folder name cannot be empty.": "نام پوشه نمی\u200cتواند خالی باشد.",
"Folder name updated successfully": "نام پوشه با موفقیت به\u200cروز شد", "Folder name updated successfully": "نام پوشه با موفقیت به\u200cروز شد",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "دستورالعمل ها را کاملا دنبال کرد", "Followed instructions perfectly": "دستورالعمل ها را کاملا دنبال کرد",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "رمز عبور جدید", "New Password": "رمز عبور جدید",
"New Tool": "", "New Tool": "",
"new-channel": "کانال-جدید", "new-channel": "کانال-جدید",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF سند (.pdf)", "PDF document (.pdf)": "PDF سند (.pdf)",
"PDF Extract Images (OCR)": "استخراج تصاویر از PDF (OCR)", "PDF Extract Images (OCR)": "استخراج تصاویر از PDF (OCR)",
"pending": "در انتظار", "pending": "در انتظار",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "دسترسی به دستگاه\u200cهای رسانه رد شد", "Permission denied when accessing media devices": "دسترسی به دستگاه\u200cهای رسانه رد شد",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "هنگام دسترسی به میکروفون، اجازه داده نشد: {{error}}", "Permission denied when accessing microphone: {{error}}": "هنگام دسترسی به میکروفون، اجازه داده نشد: {{error}}",
"Permissions": "مجوزها", "Permissions": "مجوزها",
"Perplexity API Key": "کلید API پرپلکسیتی", "Perplexity API Key": "کلید API پرپلکسیتی",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "شخصی سازی", "Personalization": "شخصی سازی",
"Pin": "پین کردن", "Pin": "پین کردن",
"Pinned": "پین شده", "Pinned": "پین شده",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 روز قبل", "Previous 30 days": "30 روز قبل",
"Previous 7 days": "7 روز قبل", "Previous 7 days": "7 روز قبل",
"Previous message": "",
"Private": "خصوصی", "Private": "خصوصی",
"Profile Image": "تصویر پروفایل", "Profile Image": "تصویر پروفایل",
"Prompt": "پرامپت", "Prompt": "پرامپت",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Haluatko varmasti poistaa tämän kanavan?", "Are you sure you want to delete this channel?": "Haluatko varmasti poistaa tämän kanavan?",
"Are you sure you want to delete this message?": "Haluatko varmasti poistaa tämän viestin?", "Are you sure you want to delete this message?": "Haluatko varmasti poistaa tämän viestin?",
"Are you sure you want to unarchive all archived chats?": "Haluatko varmasti purkaa kaikkien arkistoitujen keskustelujen arkistoinnin?", "Are you sure you want to unarchive all archived chats?": "Haluatko varmasti purkaa kaikkien arkistoitujen keskustelujen arkistoinnin?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "Haluatko varmasti päivittää tämän käyttäjän roolin **{{ROLE}}** tähän?",
"Are you sure?": "Oletko varma?", "Are you sure?": "Oletko varma?",
"Arena Models": "Arena-mallit", "Arena Models": "Arena-mallit",
"Artifacts": "Artefaktit", "Artifacts": "Artefaktit",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Kansio poistettu onnistuneesti", "Folder deleted successfully": "Kansio poistettu onnistuneesti",
"Folder name cannot be empty.": "Kansion nimi ei voi olla tyhjä.", "Folder name cannot be empty.": "Kansion nimi ei voi olla tyhjä.",
"Folder name updated successfully": "Kansion nimi päivitetty onnistuneesti", "Folder name updated successfully": "Kansion nimi päivitetty onnistuneesti",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Noudatti ohjeita täydellisesti", "Followed instructions perfectly": "Noudatti ohjeita täydellisesti",
"Force OCR": "Pakota OCR", "Force OCR": "Pakota OCR",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "Pakota OCR:n käyttö kaikilla PDF-sivuilla. Tämä voi johtaa huonompiin tuloksiin jos PDF:n tekstisisältö on laadukasta. Oletusarvo, ei käytöstä.", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "Pakota OCR:n käyttö kaikilla PDF-sivuilla. Tämä voi johtaa huonompiin tuloksiin jos PDF:n tekstisisältö on laadukasta. Oletusarvo, ei käytöstä.",
@ -846,6 +849,7 @@
"New Password": "Uusi salasana", "New Password": "Uusi salasana",
"New Tool": "Uusi työkalu", "New Tool": "Uusi työkalu",
"new-channel": "uusi-kanava", "new-channel": "uusi-kanava",
"Next message": "",
"No chats found for this user.": "Käyttäjän keskusteluja ei löytynyt.", "No chats found for this user.": "Käyttäjän keskusteluja ei löytynyt.",
"No chats found.": "Keskusteluja ei löytynyt", "No chats found.": "Keskusteluja ei löytynyt",
"No content": "Ei sisältöä", "No content": "Ei sisältöä",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF-asiakirja (.pdf)", "PDF document (.pdf)": "PDF-asiakirja (.pdf)",
"PDF Extract Images (OCR)": "Poimi kuvat PDF:stä (OCR)", "PDF Extract Images (OCR)": "Poimi kuvat PDF:stä (OCR)",
"pending": "odottaa", "pending": "odottaa",
"Pending": "",
"Pending User Overlay Content": "Odottavien käyttäjien sisältö", "Pending User Overlay Content": "Odottavien käyttäjien sisältö",
"Pending User Overlay Title": "Odottavien käyttäjien otsikko", "Pending User Overlay Title": "Odottavien käyttäjien otsikko",
"Permission denied when accessing media devices": "Käyttöoikeus evätty media-laitteille", "Permission denied when accessing media devices": "Käyttöoikeus evätty media-laitteille",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Käyttöoikeus evätty mikrofonille: {{error}}", "Permission denied when accessing microphone: {{error}}": "Käyttöoikeus evätty mikrofonille: {{error}}",
"Permissions": "Käyttöoikeudet", "Permissions": "Käyttöoikeudet",
"Perplexity API Key": "Perplexity API-avain", "Perplexity API Key": "Perplexity API-avain",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personointi", "Personalization": "Personointi",
"Pin": "Kiinnitä", "Pin": "Kiinnitä",
"Pinned": "Kiinnitetty", "Pinned": "Kiinnitetty",
@ -965,6 +972,7 @@
"Preview": "Esikatselu", "Preview": "Esikatselu",
"Previous 30 days": "Edelliset 30 päivää", "Previous 30 days": "Edelliset 30 päivää",
"Previous 7 days": "Edelliset 7 päivää", "Previous 7 days": "Edelliset 7 päivää",
"Previous message": "",
"Private": "Yksityinen", "Private": "Yksityinen",
"Profile Image": "Profiilikuva", "Profile Image": "Profiilikuva",
"Prompt": "Kehote", "Prompt": "Kehote",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Êtes-vous certain ?", "Are you sure?": "Êtes-vous certain ?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "A parfaitement suivi les instructions", "Followed instructions perfectly": "A parfaitement suivi les instructions",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nouveau mot de passe", "New Password": "Nouveau mot de passe",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Document au format PDF (.pdf)", "PDF document (.pdf)": "Document au format PDF (.pdf)",
"PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)", "PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)",
"pending": "en attente", "pending": "en attente",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Accès aux appareils multimédias refusé", "Permission denied when accessing media devices": "Accès aux appareils multimédias refusé",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permission refusée lors de l'accès au microphone : {{error}}", "Permission denied when accessing microphone: {{error}}": "Permission refusée lors de l'accès au microphone : {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personnalisation", "Personalization": "Personnalisation",
"Pin": "Épingler", "Pin": "Épingler",
"Pinned": "Épinglé", "Pinned": "Épinglé",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 derniers jours", "Previous 30 days": "30 derniers jours",
"Previous 7 days": "7 derniers jours", "Previous 7 days": "7 derniers jours",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Image de profil", "Profile Image": "Image de profil",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Êtes-vous sûr de vouloir supprimer ce canal ?", "Are you sure you want to delete this channel?": "Êtes-vous sûr de vouloir supprimer ce canal ?",
"Are you sure you want to delete this message?": "Êtes-vous sûr de vouloir supprimer ce message ?", "Are you sure you want to delete this message?": "Êtes-vous sûr de vouloir supprimer ce message ?",
"Are you sure you want to unarchive all archived chats?": "Êtes-vous sûr de vouloir désarchiver toutes les conversations archivées?", "Are you sure you want to unarchive all archived chats?": "Êtes-vous sûr de vouloir désarchiver toutes les conversations archivées?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Êtes-vous certain ?", "Are you sure?": "Êtes-vous certain ?",
"Arena Models": "Modèles d'arène", "Arena Models": "Modèles d'arène",
"Artifacts": "Artéfacts", "Artifacts": "Artéfacts",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Dossier supprimé avec succès", "Folder deleted successfully": "Dossier supprimé avec succès",
"Folder name cannot be empty.": "Le nom du dossier ne peut pas être vide.", "Folder name cannot be empty.": "Le nom du dossier ne peut pas être vide.",
"Folder name updated successfully": "Le nom du dossier a été mis à jour avec succès", "Folder name updated successfully": "Le nom du dossier a été mis à jour avec succès",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "A parfaitement suivi les instructions", "Followed instructions perfectly": "A parfaitement suivi les instructions",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nouveau mot de passe", "New Password": "Nouveau mot de passe",
"New Tool": "", "New Tool": "",
"new-channel": "nouveau-canal", "new-channel": "nouveau-canal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Document au format PDF (.pdf)", "PDF document (.pdf)": "Document au format PDF (.pdf)",
"PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)", "PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)",
"pending": "en attente", "pending": "en attente",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Accès aux appareils multimédias refusé", "Permission denied when accessing media devices": "Accès aux appareils multimédias refusé",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Accès au microphone refusé : {{error}}", "Permission denied when accessing microphone: {{error}}": "Accès au microphone refusé : {{error}}",
"Permissions": "Permissions", "Permissions": "Permissions",
"Perplexity API Key": "Clé d'API de Perplexity", "Perplexity API Key": "Clé d'API de Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personnalisation", "Personalization": "Personnalisation",
"Pin": "Épingler", "Pin": "Épingler",
"Pinned": "Épinglé", "Pinned": "Épinglé",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 derniers jours", "Previous 30 days": "30 derniers jours",
"Previous 7 days": "7 derniers jours", "Previous 7 days": "7 derniers jours",
"Previous message": "",
"Private": "Privé", "Private": "Privé",
"Profile Image": "Image de profil", "Profile Image": "Image de profil",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -5,7 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(למשל `sh webui.sh --api`)", "(e.g. `sh webui.sh --api`)": "(למשל `sh webui.sh --api`)",
"(latest)": "(האחרון)", "(latest)": "(האחרון)",
"(leave blank for to use commercial endpoint)": "", "(leave blank for to use commercial endpoint)": "",
"{{ models }}": "{{ דגמים }}", "{{ models }}": "{{ מודלים }}",
"{{COUNT}} Available Tools": "", "{{COUNT}} Available Tools": "",
"{{COUNT}} hidden lines": "", "{{COUNT}} hidden lines": "",
"{{COUNT}} Replies": "", "{{COUNT}} Replies": "",
@ -17,39 +17,39 @@
"a user": "משתמש", "a user": "משתמש",
"About": "אודות", "About": "אודות",
"Accept autocomplete generation / Jump to prompt variable": "", "Accept autocomplete generation / Jump to prompt variable": "",
"Access": "", "Access": "גישה",
"Access Control": "", "Access Control": "בקרת גישה",
"Accessible to all users": "", "Accessible to all users": "",
"Account": "חשבון", "Account": "חשבון",
"Account Activation Pending": "", "Account Activation Pending": "",
"Accurate information": "מידע מדויק", "Accurate information": "מידע מדויק",
"Actions": "", "Actions": "פעולה",
"Activate": "", "Activate": "",
"Activate this command by typing \"/{{COMMAND}}\" to chat input.": "", "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "",
"Active Users": "", "Active Users": "משתמשים מחוברים",
"Add": "הוסף", "Add": "הוסף",
"Add a model ID": "", "Add a model ID": "",
"Add a short description about what this model does": "הוסף תיאור קצר אודות אופן הפעולה של מודל זה", "Add a short description about what this model does": "הוסף תיאור קצר אודות אופן הפעולה של מודל זה",
"Add a tag": "הוסף תג", "Add a tag": "הוסף תג",
"Add Arena Model": "", "Add Arena Model": "",
"Add Connection": "", "Add Connection": "",
"Add Content": "", "Add Content": "הוסף תוכן",
"Add content here": "", "Add content here": "הוסף תוכן כאן",
"Add Custom Parameter": "", "Add Custom Parameter": "",
"Add custom prompt": "הוסף פקודה מותאמת אישית", "Add custom prompt": "הוסף פקודה מותאמת אישית",
"Add Files": "הוסף קבצים", "Add Files": "הוסף קבצים",
"Add Group": "", "Add Group": "הוסף קבוצה",
"Add Memory": "הוסף זיכרון", "Add Memory": "הוסף זיכרון",
"Add Model": "הוסף מודל", "Add Model": "הוסף מודל",
"Add Reaction": "", "Add Reaction": "",
"Add Tag": "", "Add Tag": "הוסף תג",
"Add Tags": "הוסף תגים", "Add Tags": "הוסף תגים",
"Add text content": "", "Add text content": "",
"Add User": "הוסף משתמש", "Add User": "הוסף משתמש",
"Add User Group": "", "Add User Group": "",
"Adjusting these settings will apply changes universally to all users.": "התאמת הגדרות אלו תחול על כל המשתמשים.", "Adjusting these settings will apply changes universally to all users.": "התאמת הגדרות אלו תחול על כל המשתמשים.",
"admin": "מנהל", "admin": "מנהל",
"Admin": "", "Admin": "מנהל",
"Admin Panel": "לוח בקרה למנהל", "Admin Panel": "לוח בקרה למנהל",
"Admin Settings": "הגדרות מנהל", "Admin Settings": "הגדרות מנהל",
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "",
@ -57,15 +57,15 @@
"Advanced Params": "פרמטרים מתקדמים", "Advanced Params": "פרמטרים מתקדמים",
"All": "", "All": "",
"All Documents": "כל המסמכים", "All Documents": "כל המסמכים",
"All models deleted successfully": "", "All models deleted successfully": "כל המודלים נמחקו בהצלחה",
"Allow Call": "", "Allow Call": "",
"Allow Chat Controls": "", "Allow Chat Controls": "",
"Allow Chat Delete": "", "Allow Chat Delete": "",
"Allow Chat Deletion": "אפשר מחיקת צ'אט", "Allow Chat Deletion": "אפשר מחיקת צ'אט",
"Allow Chat Edit": "", "Allow Chat Edit": "אפשר עריכת צ'אט",
"Allow Chat Export": "", "Allow Chat Export": "",
"Allow Chat Share": "", "Allow Chat Share": "אפשר שיתוף צ'אט",
"Allow File Upload": "", "Allow File Upload": "אפשר העלאת קובץ",
"Allow Multiple Models in Chat": "", "Allow Multiple Models in Chat": "",
"Allow non-local voices": "", "Allow non-local voices": "",
"Allow Speech to Text": "", "Allow Speech to Text": "",
@ -78,11 +78,11 @@
"Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "", "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "",
"Already have an account?": "כבר יש לך חשבון?", "Already have an account?": "כבר יש לך חשבון?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.": "", "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.": "",
"Always": "", "Always": "תמיד",
"Always Collapse Code Blocks": "", "Always Collapse Code Blocks": "",
"Always Expand Details": "", "Always Expand Details": "",
"Always Play Notification Sound": "", "Always Play Notification Sound": "",
"Amazing": "", "Amazing": "מדהים",
"an assistant": "עוזר", "an assistant": "עוזר",
"Analyzed": "", "Analyzed": "",
"Analyzing...": "", "Analyzing...": "",
@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "האם אתה בטוח?", "Are you sure?": "האם אתה בטוח?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -124,7 +123,7 @@
"Auth": "", "Auth": "",
"Authenticate": "", "Authenticate": "",
"Authentication": "", "Authentication": "",
"Auto": "", "Auto": "אוטומטי",
"Auto-Copy Response to Clipboard": "העתקה אוטומטית של תגובה ללוח", "Auto-Copy Response to Clipboard": "העתקה אוטומטית של תגובה ללוח",
"Auto-playback response": "תגובת השמעה אוטומטית", "Auto-playback response": "תגובת השמעה אוטומטית",
"Autocomplete Generation": "", "Autocomplete Generation": "",
@ -134,7 +133,7 @@
"AUTOMATIC1111 Base URL": "כתובת URL בסיסית של AUTOMATIC1111", "AUTOMATIC1111 Base URL": "כתובת URL בסיסית של AUTOMATIC1111",
"AUTOMATIC1111 Base URL is required.": "נדרשת כתובת URL בסיסית של AUTOMATIC1111", "AUTOMATIC1111 Base URL is required.": "נדרשת כתובת URL בסיסית של AUTOMATIC1111",
"Available list": "", "Available list": "",
"Available Tools": "", "Available Tools": "כלים זמינים",
"available!": "זמין!", "available!": "זמין!",
"Awful": "", "Awful": "",
"Azure AI Speech": "", "Azure AI Speech": "",
@ -145,7 +144,7 @@
"Base Model (From)": "דגם בסיס (מ)", "Base Model (From)": "דגם בסיס (מ)",
"before": "לפני", "before": "לפני",
"Being lazy": "להיות עצלן", "Being lazy": "להיות עצלן",
"Beta": "", "Beta": "בטא",
"Bing Search V7 Endpoint": "", "Bing Search V7 Endpoint": "",
"Bing Search V7 Subscription Key": "", "Bing Search V7 Subscription Key": "",
"Bocha Search API Key": "", "Bocha Search API Key": "",
@ -155,10 +154,10 @@
"By {{name}}": "", "By {{name}}": "",
"Bypass Embedding and Retrieval": "", "Bypass Embedding and Retrieval": "",
"Bypass Web Loader": "", "Bypass Web Loader": "",
"Calendar": "", "Calendar": "לוח שנה",
"Call": "", "Call": "",
"Call feature is not supported when using Web STT engine": "", "Call feature is not supported when using Web STT engine": "",
"Camera": "", "Camera": "מצלמה",
"Cancel": "בטל", "Cancel": "בטל",
"Capabilities": "יכולות", "Capabilities": "יכולות",
"Capture": "", "Capture": "",
@ -188,18 +187,18 @@
"Ciphers": "", "Ciphers": "",
"Citation": "ציטוט", "Citation": "ציטוט",
"Citations": "", "Citations": "",
"Clear memory": "", "Clear memory": "נקה זיכרון",
"Clear Memory": "", "Clear Memory": "נקה",
"click here": "", "click here": "לחץ פה",
"Click here for filter guides.": "", "Click here for filter guides.": "",
"Click here for help.": "לחץ כאן לעזרה.", "Click here for help.": "לחץ כאן לעזרה.",
"Click here to": "לחץ כאן כדי", "Click here to": "לחץ כאן כדי",
"Click here to download user import template file.": "", "Click here to download user import template file.": "",
"Click here to learn more about faster-whisper and see the available models.": "", "Click here to learn more about faster-whisper and see the available models.": "לחץ כאן כדי ללמוד עוד על faster-whisper ולראות מודלים זמינים",
"Click here to see 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.": "לחץ כאן כדי לבחירת קובץ py",
"Click here to upload a workflow.json file.": "", "Click here to upload a workflow.json file.": "",
"click here.": "לחץ כאן.", "click here.": "לחץ כאן.",
"Click on the user role button to change a user's role.": "לחץ על כפתור תפקיד המשתמש כדי לשנות את תפקיד המשתמש.", "Click on the user role button to change a user's role.": "לחץ על כפתור תפקיד המשתמש כדי לשנות את תפקיד המשתמש.",
@ -208,9 +207,9 @@
"Clone Chat": "", "Clone Chat": "",
"Clone of {{TITLE}}": "", "Clone of {{TITLE}}": "",
"Close": "סגור", "Close": "סגור",
"Code execution": "", "Code execution": "הרצת קוד",
"Code Execution": "", "Code Execution": "הרצת קוד",
"Code Execution Engine": "", "Code Execution Engine": "מנוע הרצת קוד",
"Code Execution Timeout": "", "Code Execution Timeout": "",
"Code formatted successfully": "", "Code formatted successfully": "",
"Code Interpreter": "", "Code Interpreter": "",
@ -218,9 +217,9 @@
"Code Interpreter Prompt Template": "", "Code Interpreter Prompt Template": "",
"Collapse": "", "Collapse": "",
"Collection": "אוסף", "Collection": "אוסף",
"Color": "", "Color": "צבע",
"ComfyUI": "ComfyUI", "ComfyUI": "ComfyUI",
"ComfyUI API Key": "", "ComfyUI API Key": "מפתח API כל ComfyUI",
"ComfyUI Base URL": "כתובת URL בסיסית של ComfyUI", "ComfyUI Base URL": "כתובת URL בסיסית של ComfyUI",
"ComfyUI Base URL is required.": "נדרשת כתובת URL בסיסית של ComfyUI", "ComfyUI Base URL is required.": "נדרשת כתובת URL בסיסית של ComfyUI",
"ComfyUI Workflow": "", "ComfyUI Workflow": "",
@ -231,31 +230,31 @@
"Configure": "", "Configure": "",
"Confirm": "", "Confirm": "",
"Confirm Password": "אשר סיסמה", "Confirm Password": "אשר סיסמה",
"Confirm your action": "", "Confirm your action": "אשר את הפעולה שלך",
"Confirm your new password": "", "Confirm your new password": "אשר את הסיסמה החדשה שלך",
"Connect to your own OpenAI compatible API endpoints.": "", "Connect to your own OpenAI compatible API endpoints.": "",
"Connect to your own OpenAPI compatible external tool servers.": "", "Connect to your own OpenAPI compatible external tool servers.": "",
"Connection failed": "", "Connection failed": "החיבור נכשל",
"Connection successful": "", "Connection successful": "החיבור הצליח",
"Connection Type": "", "Connection Type": "סוג חיבור",
"Connections": "חיבורים", "Connections": "חיבורים",
"Connections saved successfully": "", "Connections saved successfully": "החיבור נשמר בהצלחה",
"Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "", "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "",
"Contact Admin for WebUI Access": "", "Contact Admin for WebUI Access": "",
"Content": "תוכן", "Content": "תוכן",
"Content Extraction Engine": "", "Content Extraction Engine": "",
"Continue Response": "המשך תגובה", "Continue Response": "המשך תגובה",
"Continue with {{provider}}": "", "Continue with {{provider}}": "המשך עם {{provider}}",
"Continue with Email": "", "Continue with Email": "המשך עם מייל",
"Continue with LDAP": "", "Continue with LDAP": "המשך עם LDAP",
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "", "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "",
"Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "", "Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "",
"Controls": "", "Controls": "",
"Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "", "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "",
"Copied": "", "Copied": "הועתק",
"Copied link to clipboard": "", "Copied link to clipboard": "",
"Copied shared chat URL to clipboard!": "העתקת כתובת URL של צ'אט משותף ללוח!", "Copied shared chat URL to clipboard!": "העתקת כתובת URL של צ'אט משותף ללוח!",
"Copied to clipboard": "", "Copied to clipboard": "הועתק ללוח",
"Copy": "העתק", "Copy": "העתק",
"Copy Formatted Text": "", "Copy Formatted Text": "",
"Copy last code block": "העתק את בלוק הקוד האחרון", "Copy last code block": "העתק את בלוק הקוד האחרון",
@ -270,11 +269,11 @@
"Create Account": "צור חשבון", "Create Account": "צור חשבון",
"Create Admin Account": "", "Create Admin Account": "",
"Create Channel": "", "Create Channel": "",
"Create Group": "", "Create Group": "יצירת קבוצה",
"Create Knowledge": "", "Create Knowledge": "",
"Create new key": "צור מפתח חדש", "Create new key": "צור מפתח חדש",
"Create new secret key": "צור מפתח סודי חדש", "Create new secret key": "צור מפתח סודי חדש",
"Create Note": "", "Create Note": "יצירת פתק",
"Create your first note by clicking on the plus button below.": "", "Create your first note by clicking on the plus button below.": "",
"Created at": "נוצר ב", "Created at": "נוצר ב",
"Created At": "נוצר ב", "Created At": "נוצר ב",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "עקב אחר ההוראות במושלמות", "Followed instructions perfectly": "עקב אחר ההוראות במושלמות",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -642,10 +645,10 @@
"Generate Image": "", "Generate Image": "",
"Generate prompt pair": "", "Generate prompt pair": "",
"Generating search query": "יצירת שאילתת חיפוש", "Generating search query": "יצירת שאילתת חיפוש",
"Generating...": "", "Generating...": "מג'נרט...",
"Get started": "", "Get started": "",
"Get started with {{WEBUI_NAME}}": "", "Get started with {{WEBUI_NAME}}": "",
"Global": "", "Global": "גלובלי",
"Good Response": "תגובה טובה", "Good Response": "תגובה טובה",
"Google Drive": "", "Google Drive": "",
"Google PSE API Key": "מפתח API של Google PSE", "Google PSE API Key": "מפתח API של Google PSE",
@ -655,7 +658,7 @@
"Group Description": "", "Group Description": "",
"Group Name": "", "Group Name": "",
"Group updated successfully": "", "Group updated successfully": "",
"Groups": "", "Groups": "קבוצות",
"Haptic Feedback": "", "Haptic Feedback": "",
"Hello, {{name}}": "שלום, {{name}}", "Hello, {{name}}": "שלום, {{name}}",
"Help": "עזרה", "Help": "עזרה",
@ -663,9 +666,9 @@
"Hex Color": "", "Hex Color": "",
"Hex Color - Leave empty for default color": "", "Hex Color - Leave empty for default color": "",
"Hide": "הסתר", "Hide": "הסתר",
"Hide Model": "", "Hide Model": "הסתר מודל",
"High Contrast Mode": "", "High Contrast Mode": "",
"Home": "", "Home": "בית",
"Host": "", "Host": "",
"How can I help you today?": "כיצד אוכל לעזור לך היום?", "How can I help you today?": "כיצד אוכל לעזור לך היום?",
"How would you rate this response?": "", "How would you rate this response?": "",
@ -676,7 +679,7 @@
"iframe Sandbox Allow Forms": "", "iframe Sandbox Allow Forms": "",
"iframe Sandbox Allow Same Origin": "", "iframe Sandbox Allow Same Origin": "",
"Ignite curiosity": "", "Ignite curiosity": "",
"Image": "", "Image": "תמונה",
"Image Compression": "", "Image Compression": "",
"Image Generation": "", "Image Generation": "",
"Image Generation (Experimental)": "יצירת תמונות (ניסיוני)", "Image Generation (Experimental)": "יצירת תמונות (ניסיוני)",
@ -692,11 +695,11 @@
"Import From Link": "", "Import From Link": "",
"Import Functions": "", "Import Functions": "",
"Import Models": "ייבוא דגמים", "Import Models": "ייבוא דגמים",
"Import Notes": "", "Import Notes": "ייבוא פתקים",
"Import Presets": "", "Import Presets": "",
"Import Prompt Suggestions": "", "Import Prompt Suggestions": "",
"Import Prompts": "יבוא פקודות", "Import Prompts": "ייבוא פקודות",
"Import Tools": "", "Import Tools": "ייבוא כלים",
"Include": "", "Include": "",
"Include `--api-auth` flag when running stable-diffusion-webui": "", "Include `--api-auth` flag when running stable-diffusion-webui": "",
"Include `--api` flag when running stable-diffusion-webui": "כלול את הדגל `--api` בעת הרצת stable-diffusion-webui", "Include `--api` flag when running stable-diffusion-webui": "כלול את הדגל `--api` בעת הרצת stable-diffusion-webui",
@ -713,7 +716,7 @@
"Invalid JSON file": "", "Invalid JSON file": "",
"Invalid JSON schema": "", "Invalid JSON schema": "",
"Invalid Tag": "תג לא חוקי", "Invalid Tag": "תג לא חוקי",
"is typing...": "", "is typing...": "מקליד...",
"January": "ינואר", "January": "ינואר",
"Jina API Key": "", "Jina API Key": "",
"join our Discord for help.": "הצטרף ל-Discord שלנו לעזרה.", "join our Discord for help.": "הצטרף ל-Discord שלנו לעזרה.",
@ -757,7 +760,7 @@
"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.": "", "Leave model field empty to use the default model.": "",
"License": "", "License": "רישיון",
"Light": "בהיר", "Light": "בהיר",
"Listening...": "", "Listening...": "",
"Llama.cpp": "", "Llama.cpp": "",
@ -795,7 +798,7 @@
"Memory updated successfully": "", "Memory updated successfully": "",
"Merge Responses": "", "Merge Responses": "",
"Merged Response": "תגובה ממוזגת", "Merged Response": "תגובה ממוזגת",
"Message rating should be enabled to use this feature": "", "Message rating should be enabled to use this feature": "דירוג הודעות צריך להיות מאופשר כדי להשתמש בפיצ'ר הזה",
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "הודעות שתשלח לאחר יצירת הקישור לא ישותפו. משתמשים עם כתובת האתר יוכלו לצפות בצ'אט המשותף.", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "הודעות שתשלח לאחר יצירת הקישור לא ישותפו. משתמשים עם כתובת האתר יוכלו לצפות בצ'אט המשותף.",
"Microsoft OneDrive": "", "Microsoft OneDrive": "",
"Microsoft OneDrive (personal)": "", "Microsoft OneDrive (personal)": "",
@ -820,9 +823,9 @@
"Model Filtering": "", "Model Filtering": "",
"Model ID": "מזהה דגם", "Model ID": "מזהה דגם",
"Model IDs": "", "Model IDs": "",
"Model Name": "", "Model Name": "שם המודל",
"Model not selected": "לא נבחר מודל", "Model not selected": "לא נבחר מודל",
"Model Params": "פרמס מודל", "Model Params": "פרמטרי המודל",
"Model Permissions": "", "Model Permissions": "",
"Model unloaded successfully": "", "Model unloaded successfully": "",
"Model updated successfully": "", "Model updated successfully": "",
@ -835,22 +838,23 @@
"Mojeek Search API Key": "", "Mojeek Search API Key": "",
"more": "", "more": "",
"More": "עוד", "More": "עוד",
"My Notes": "", "My Notes": "הפתקים שלי",
"Name": "שם", "Name": "שם",
"Name your knowledge base": "", "Name your knowledge base": "",
"Native": "", "Native": "",
"New Chat": "צ'אט חדש", "New Chat": "צ'אט חדש",
"New Folder": "", "New Folder": "תיקייה חדשה",
"New Function": "", "New Function": "פונקציה חדשה",
"New Note": "", "New Note": "פתק חדש",
"New Password": "סיסמה חדשה", "New Password": "סיסמה חדשה",
"New Tool": "", "New Tool": "כלי חדש",
"new-channel": "", "new-channel": "",
"No chats found for this user.": "", "Next message": "",
"No chats found.": "", "No chats found for this user.": "לא נמצאו צ'אטים ליוזר הזה.",
"No content": "", "No chats found.": "לא נמצאו צ'אטים",
"No content found": "", "No content": "אין תוכן",
"No content found in file.": "", "No content found": "תוכן לא נמצא",
"No content found in file.": "לא נמצא תוכן בקובץ.",
"No content to speak": "", "No content to speak": "",
"No distance available": "", "No distance available": "",
"No feedbacks found": "", "No feedbacks found": "",
@ -867,14 +871,14 @@
"No results found": "לא נמצאו תוצאות", "No results found": "לא נמצאו תוצאות",
"No search query generated": "לא נוצרה שאילתת חיפוש", "No search query generated": "לא נוצרה שאילתת חיפוש",
"No source available": "אין מקור זמין", "No source available": "אין מקור זמין",
"No users were found.": "", "No users were found.": "לא נמצאו יוזרים",
"No valves to update": "", "No valves to update": "",
"None": "ללא", "None": "ללא",
"Not factually correct": "לא נכון מבחינה עובדתית", "Not factually correct": "לא נכון מבחינה עובדתית",
"Not helpful": "", "Not helpful": "",
"Note deleted successfully": "", "Note deleted successfully": "פתק נמחק בהצלחה",
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "הערה: אם תקבע ציון מינימלי, החיפוש יחזיר רק מסמכים עם ציון שגבוה או שווה לציון המינימלי.", "Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "הערה: אם תקבע ציון מינימלי, החיפוש יחזיר רק מסמכים עם ציון שגבוה או שווה לציון המינימלי.",
"Notes": "", "Notes": "פתקים",
"Notification Sound": "", "Notification Sound": "",
"Notification Webhook": "", "Notification Webhook": "",
"Notifications": "התראות", "Notifications": "התראות",
@ -920,7 +924,7 @@
"Output format": "", "Output format": "",
"Output Format": "", "Output Format": "",
"Overview": "", "Overview": "",
"page": "", "page": "עמוד",
"Paginate": "", "Paginate": "",
"Parameters": "", "Parameters": "",
"Password": "סיסמה", "Password": "סיסמה",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "מסמך PDF (.pdf)", "PDF document (.pdf)": "מסמך PDF (.pdf)",
"PDF Extract Images (OCR)": "חילוץ תמונות מ-PDF (OCR)", "PDF Extract Images (OCR)": "חילוץ תמונות מ-PDF (OCR)",
"pending": "ממתין", "pending": "ממתין",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "ההרשאה נדחתה בעת גישה למיקרופון: {{error}}", "Permission denied when accessing microphone: {{error}}": "ההרשאה נדחתה בעת גישה למיקרופון: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "תאור", "Personalization": "תאור",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 הימים הקודמים", "Previous 30 days": "30 הימים הקודמים",
"Previous 7 days": "7 הימים הקודמים", "Previous 7 days": "7 הימים הקודמים",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "תמונת פרופיל", "Profile Image": "תמונת פרופיל",
"Prompt": "", "Prompt": "",
@ -1068,7 +1076,7 @@
"Select a model": "בחר מודל", "Select a model": "בחר מודל",
"Select a pipeline": "בחר קו צינור", "Select a pipeline": "בחר קו צינור",
"Select a pipeline url": "בחר כתובת URL של קו צינור", "Select a pipeline url": "בחר כתובת URL של קו צינור",
"Select a tool": "", "Select a tool": "בחר כלי",
"Select an auth method": "", "Select an auth method": "",
"Select an Ollama instance": "", "Select an Ollama instance": "",
"Select Engine": "", "Select Engine": "",
@ -1188,7 +1196,7 @@
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "ציון צריך להיות ערך בין 0.0 (0%) ל-1.0 (100%)", "The score should be a value between 0.0 (0%) and 1.0 (100%).": "ציון צריך להיות ערך בין 0.0 (0%) ל-1.0 (100%)",
"The temperature of the model. Increasing the temperature will make the model answer more creatively.": "", "The temperature of the model. Increasing the temperature will make the model answer more creatively.": "",
"Theme": "נושא", "Theme": "נושא",
"Thinking...": "", "Thinking...": "חושב...",
"This action cannot be undone. Do you wish to continue?": "", "This action cannot be undone. Do you wish to continue?": "",
"This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "",
"This chat wont appear in history and your messages will not be saved.": "", "This chat wont appear in history and your messages will not be saved.": "",
@ -1216,7 +1224,7 @@
"Title Auto-Generation": "יצירת שם אוטומטית", "Title Auto-Generation": "יצירת שם אוטומטית",
"Title cannot be an empty string.": "שם לא יכול להיות מחרוזת ריקה.", "Title cannot be an empty string.": "שם לא יכול להיות מחרוזת ריקה.",
"Title Generation": "", "Title Generation": "",
"Title Generation Prompt": "שאלה ליצירת שם", "Title Generation Prompt": "פרומפט ליצירת כותרת",
"TLS": "", "TLS": "",
"To access the available model names for downloading,": "כדי לגשת לשמות הדגמים הזמינים להורדה,", "To access the available model names for downloading,": "כדי לגשת לשמות הדגמים הזמינים להורדה,",
"To access the GGUF models available for downloading,": "כדי לגשת לדגמי GGUF הזמינים להורדה,", "To access the GGUF models available for downloading,": "כדי לגשת לדגמי GGUF הזמינים להורדה,",
@ -1242,7 +1250,7 @@
"Tool Name": "", "Tool Name": "",
"Tool Servers": "", "Tool Servers": "",
"Tool updated successfully": "", "Tool updated successfully": "",
"Tools": "", "Tools": "כלים",
"Tools Access": "", "Tools Access": "",
"Tools are a function calling system with arbitrary code execution": "", "Tools are a function calling system with arbitrary code execution": "",
"Tools Function Calling Prompt": "", "Tools Function Calling Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "क्या आपको यकीन है?", "Are you sure?": "क्या आपको यकीन है?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "निर्देशों का पूर्णतः पालन किया", "Followed instructions perfectly": "निर्देशों का पूर्णतः पालन किया",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "नया पासवर्ड", "New Password": "नया पासवर्ड",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF दस्तावेज़ (.pdf)", "PDF document (.pdf)": "PDF दस्तावेज़ (.pdf)",
"PDF Extract Images (OCR)": "PDF छवियाँ निकालें (OCR)", "PDF Extract Images (OCR)": "PDF छवियाँ निकालें (OCR)",
"pending": "लंबित", "pending": "लंबित",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "माइक्रोफ़ोन तक पहुँचने पर अनुमति अस्वीकृत: {{error}}", "Permission denied when accessing microphone: {{error}}": "माइक्रोफ़ोन तक पहुँचने पर अनुमति अस्वीकृत: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "पेरसनलाइज़मेंट", "Personalization": "पेरसनलाइज़मेंट",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "पिछले 30 दिन", "Previous 30 days": "पिछले 30 दिन",
"Previous 7 days": "पिछले 7 दिन", "Previous 7 days": "पिछले 7 दिन",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "प्रोफ़ाइल छवि", "Profile Image": "प्रोफ़ाइल छवि",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Jeste li sigurni?", "Are you sure?": "Jeste li sigurni?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Savršeno slijedio upute", "Followed instructions perfectly": "Savršeno slijedio upute",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nova lozinka", "New Password": "Nova lozinka",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokument (.pdf)", "PDF document (.pdf)": "PDF dokument (.pdf)",
"PDF Extract Images (OCR)": "PDF izdvajanje slika (OCR)", "PDF Extract Images (OCR)": "PDF izdvajanje slika (OCR)",
"pending": "u tijeku", "pending": "u tijeku",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Dopuštenje je odbijeno prilikom pristupa medijskim uređajima", "Permission denied when accessing media devices": "Dopuštenje je odbijeno prilikom pristupa medijskim uređajima",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Pristup mikrofonu odbijen: {{error}}", "Permission denied when accessing microphone: {{error}}": "Pristup mikrofonu odbijen: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Prilagodba", "Personalization": "Prilagodba",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Prethodnih 30 dana", "Previous 30 days": "Prethodnih 30 dana",
"Previous 7 days": "Prethodnih 7 dana", "Previous 7 days": "Prethodnih 7 dana",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profilna slika", "Profile Image": "Profilna slika",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Biztosan törölni szeretnéd ezt a csatornát?", "Are you sure you want to delete this channel?": "Biztosan törölni szeretnéd ezt a csatornát?",
"Are you sure you want to delete this message?": "Biztosan törölni szeretnéd ezt az üzenetet?", "Are you sure you want to delete this message?": "Biztosan törölni szeretnéd ezt az üzenetet?",
"Are you sure you want to unarchive all archived chats?": "Biztosan vissza szeretnéd állítani az összes archivált csevegést?", "Are you sure you want to unarchive all archived chats?": "Biztosan vissza szeretnéd állítani az összes archivált csevegést?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Biztos vagy benne?", "Are you sure?": "Biztos vagy benne?",
"Arena Models": "Arena modellek", "Arena Models": "Arena modellek",
"Artifacts": "Műtermékek", "Artifacts": "Műtermékek",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Mappa sikeresen törölve", "Folder deleted successfully": "Mappa sikeresen törölve",
"Folder name cannot be empty.": "A mappa neve nem lehet üres.", "Folder name cannot be empty.": "A mappa neve nem lehet üres.",
"Folder name updated successfully": "Mappa neve sikeresen frissítve", "Folder name updated successfully": "Mappa neve sikeresen frissítve",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Tökéletesen követte az utasításokat", "Followed instructions perfectly": "Tökéletesen követte az utasításokat",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Új jelszó", "New Password": "Új jelszó",
"New Tool": "", "New Tool": "",
"new-channel": "új csatorna", "new-channel": "új csatorna",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokumentum (.pdf)", "PDF document (.pdf)": "PDF dokumentum (.pdf)",
"PDF Extract Images (OCR)": "PDF képek kinyerése (OCR)", "PDF Extract Images (OCR)": "PDF képek kinyerése (OCR)",
"pending": "függőben", "pending": "függőben",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Hozzáférés megtagadva a médiaeszközökhöz", "Permission denied when accessing media devices": "Hozzáférés megtagadva a médiaeszközökhöz",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Hozzáférés megtagadva a mikrofonhoz: {{error}}", "Permission denied when accessing microphone: {{error}}": "Hozzáférés megtagadva a mikrofonhoz: {{error}}",
"Permissions": "Engedélyek", "Permissions": "Engedélyek",
"Perplexity API Key": "Perplexity API kulcs", "Perplexity API Key": "Perplexity API kulcs",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Személyre szabás", "Personalization": "Személyre szabás",
"Pin": "Rögzítés", "Pin": "Rögzítés",
"Pinned": "Rögzítve", "Pinned": "Rögzítve",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Előző 30 nap", "Previous 30 days": "Előző 30 nap",
"Previous 7 days": "Előző 7 nap", "Previous 7 days": "Előző 7 nap",
"Previous message": "",
"Private": "Privát", "Private": "Privát",
"Profile Image": "Profilkép", "Profile Image": "Profilkép",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Apakah Anda yakin?", "Are you sure?": "Apakah Anda yakin?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Mengikuti instruksi dengan sempurna", "Followed instructions perfectly": "Mengikuti instruksi dengan sempurna",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Kata Sandi Baru", "New Password": "Kata Sandi Baru",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Dokumen PDF (.pdf)", "PDF document (.pdf)": "Dokumen PDF (.pdf)",
"PDF Extract Images (OCR)": "Ekstrak Gambar PDF (OCR)", "PDF Extract Images (OCR)": "Ekstrak Gambar PDF (OCR)",
"pending": "tertunda", "pending": "tertunda",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Izin ditolak saat mengakses perangkat media", "Permission denied when accessing media devices": "Izin ditolak saat mengakses perangkat media",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Izin ditolak saat mengakses mikrofon: {{error}}", "Permission denied when accessing microphone: {{error}}": "Izin ditolak saat mengakses mikrofon: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalisasi", "Personalization": "Personalisasi",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 hari sebelumnya", "Previous 30 days": "30 hari sebelumnya",
"Previous 7 days": "7 hari sebelumnya", "Previous 7 days": "7 hari sebelumnya",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Gambar Profil", "Profile Image": "Gambar Profil",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "An bhfuil tú cinnte gur mhaith leat an cainéal seo a scriosadh?", "Are you sure you want to delete this channel?": "An bhfuil tú cinnte gur mhaith leat an cainéal seo a scriosadh?",
"Are you sure you want to delete this message?": "An bhfuil tú cinnte gur mhaith leat an teachtaireacht seo a scriosadh?", "Are you sure you want to delete this message?": "An bhfuil tú cinnte gur mhaith leat an teachtaireacht seo a scriosadh?",
"Are you sure you want to unarchive all archived chats?": "An bhfuil tú cinnte gur mhaith leat gach comhrá cartlainne a dhíchartlannú?", "Are you sure you want to unarchive all archived chats?": "An bhfuil tú cinnte gur mhaith leat gach comhrá cartlainne a dhíchartlannú?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "An bhfuil tú cinnte?", "Are you sure?": "An bhfuil tú cinnte?",
"Arena Models": "Múnlaí Airéine", "Arena Models": "Múnlaí Airéine",
"Artifacts": "Déantáin", "Artifacts": "Déantáin",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Scriosadh an fillteán go rathúil", "Folder deleted successfully": "Scriosadh an fillteán go rathúil",
"Folder name cannot be empty.": "Ní féidir ainm fillteáin a bheith folamh.", "Folder name cannot be empty.": "Ní féidir ainm fillteáin a bheith folamh.",
"Folder name updated successfully": "D'éirigh le hainm an fhillteáin a nuashonrú", "Folder name updated successfully": "D'éirigh le hainm an fhillteáin a nuashonrú",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Lean treoracha go foirfe", "Followed instructions perfectly": "Lean treoracha go foirfe",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Pasfhocal Nua", "New Password": "Pasfhocal Nua",
"New Tool": "", "New Tool": "",
"new-channel": "nua-chainéil", "new-channel": "nua-chainéil",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Doiciméad PDF (.pdf)", "PDF document (.pdf)": "Doiciméad PDF (.pdf)",
"PDF Extract Images (OCR)": "Íomhánna Sliocht PDF (OCR)", "PDF Extract Images (OCR)": "Íomhánna Sliocht PDF (OCR)",
"pending": "ar feitheamh", "pending": "ar feitheamh",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Cead diúltaithe nuair a bhíonn rochtain agat", "Permission denied when accessing media devices": "Cead diúltaithe nuair a bhíonn rochtain agat",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Cead diúltaithe agus tú ag teacht ar mhicreafón: {{error}}", "Permission denied when accessing microphone: {{error}}": "Cead diúltaithe agus tú ag teacht ar mhicreafón: {{error}}",
"Permissions": "Ceadanna", "Permissions": "Ceadanna",
"Perplexity API Key": "Eochair API Perplexity", "Perplexity API Key": "Eochair API Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Pearsantú", "Personalization": "Pearsantú",
"Pin": "Bioráin", "Pin": "Bioráin",
"Pinned": "Pinneáilte", "Pinned": "Pinneáilte",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 lá roimhe seo", "Previous 30 days": "30 lá roimhe seo",
"Previous 7 days": "7 lá roimhe seo", "Previous 7 days": "7 lá roimhe seo",
"Previous message": "",
"Private": "Príobháideach", "Private": "Príobháideach",
"Profile Image": "Íomhá Próifíl", "Profile Image": "Íomhá Próifíl",
"Prompt": "Leid", "Prompt": "Leid",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Sei sicuro di voler eliminare questo canale?", "Are you sure you want to delete this channel?": "Sei sicuro di voler eliminare questo canale?",
"Are you sure you want to delete this message?": "Sei sicuro di voler eliminare questo messaggio?", "Are you sure you want to delete this message?": "Sei sicuro di voler eliminare questo messaggio?",
"Are you sure you want to unarchive all archived chats?": "Sei sicuro di voler disarchiviare tutte le chat archiviate?", "Are you sure you want to unarchive all archived chats?": "Sei sicuro di voler disarchiviare tutte le chat archiviate?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "Sei sicuro di voler aggiornare il ruolo di questo utente in **{{ROLE}}**?",
"Are you sure?": "Sei sicuro?", "Are you sure?": "Sei sicuro?",
"Arena Models": "Modelli Arena", "Arena Models": "Modelli Arena",
"Artifacts": "Artefatti", "Artifacts": "Artefatti",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Cartella rimossa con successo", "Folder deleted successfully": "Cartella rimossa con successo",
"Folder name cannot be empty.": "Il nome della cartella non può essere vuoto.", "Folder name cannot be empty.": "Il nome della cartella non può essere vuoto.",
"Folder name updated successfully": "Nome cartella aggiornato con successo", "Folder name updated successfully": "Nome cartella aggiornato con successo",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Ha seguito le istruzioni alla perfezione", "Followed instructions perfectly": "Ha seguito le istruzioni alla perfezione",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nuova password", "New Password": "Nuova password",
"New Tool": "", "New Tool": "",
"new-channel": "nuovo-canale", "new-channel": "nuovo-canale",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "Nessun contenuto", "No content": "Nessun contenuto",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Documento PDF (.pdf)", "PDF document (.pdf)": "Documento PDF (.pdf)",
"PDF Extract Images (OCR)": "Estrazione Immagini PDF (OCR)", "PDF Extract Images (OCR)": "Estrazione Immagini PDF (OCR)",
"pending": "in sospeso", "pending": "in sospeso",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Autorizzazione negata durante l'accesso ai dispositivi multimediali", "Permission denied when accessing media devices": "Autorizzazione negata durante l'accesso ai dispositivi multimediali",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Autorizzazione negata durante l'accesso al microfono: {{error}}", "Permission denied when accessing microphone: {{error}}": "Autorizzazione negata durante l'accesso al microfono: {{error}}",
"Permissions": "Permessi", "Permissions": "Permessi",
"Perplexity API Key": "Chiave API Perplexity", "Perplexity API Key": "Chiave API Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizzazione", "Personalization": "Personalizzazione",
"Pin": "Fissa", "Pin": "Fissa",
"Pinned": "Fissato", "Pinned": "Fissato",
@ -965,6 +972,7 @@
"Preview": "Anteprima", "Preview": "Anteprima",
"Previous 30 days": "Ultimi 30 giorni", "Previous 30 days": "Ultimi 30 giorni",
"Previous 7 days": "Ultimi 7 giorni", "Previous 7 days": "Ultimi 7 giorni",
"Previous message": "",
"Private": "Privato", "Private": "Privato",
"Profile Image": "Immagine del Profilo", "Profile Image": "Immagine del Profilo",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "このチャンネルを削除しますか?", "Are you sure you want to delete this channel?": "このチャンネルを削除しますか?",
"Are you sure you want to delete this message?": "このメッセージを削除しますか?", "Are you sure you want to delete this message?": "このメッセージを削除しますか?",
"Are you sure you want to unarchive all archived chats?": "すべてのアーカイブされたチャットをアンアーカイブしますか?", "Are you sure you want to unarchive all archived chats?": "すべてのアーカイブされたチャットをアンアーカイブしますか?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "このユーザーの役割を **{{ROLE}}** に更新しますか?",
"Are you sure?": "よろしいですか?", "Are you sure?": "よろしいですか?",
"Arena Models": "Arenaモデル", "Arena Models": "Arenaモデル",
"Artifacts": "アーティファクト", "Artifacts": "アーティファクト",
@ -611,6 +610,10 @@
"Folder deleted successfully": "フォルダー削除が成功しました。", "Folder deleted successfully": "フォルダー削除が成功しました。",
"Folder name cannot be empty.": "フォルダー名を入力してください。", "Folder name cannot be empty.": "フォルダー名を入力してください。",
"Folder name updated successfully": "フォルダー名更新が成功しました。", "Folder name updated successfully": "フォルダー名更新が成功しました。",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "完全に指示に従った", "Followed instructions perfectly": "完全に指示に従った",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "新しいパスワード", "New Password": "新しいパスワード",
"New Tool": "", "New Tool": "",
"new-channel": "新しいチャンネル", "new-channel": "新しいチャンネル",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "内容がありません", "No content": "内容がありません",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ドキュメント (.pdf)", "PDF document (.pdf)": "PDF ドキュメント (.pdf)",
"PDF Extract Images (OCR)": "PDF 画像抽出 (OCR)", "PDF Extract Images (OCR)": "PDF 画像抽出 (OCR)",
"pending": "保留中", "pending": "保留中",
"Pending": "",
"Pending User Overlay Content": "保留中のユーザー情報オーバーレイの内容", "Pending User Overlay Content": "保留中のユーザー情報オーバーレイの内容",
"Pending User Overlay Title": "保留中のユーザー情報オーバーレイのタイトル", "Pending User Overlay Title": "保留中のユーザー情報オーバーレイのタイトル",
"Permission denied when accessing media devices": "メディアデバイスへのアクセス時に権限が拒否されました", "Permission denied when accessing media devices": "メディアデバイスへのアクセス時に権限が拒否されました",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "マイクへのアクセス時に権限が拒否されました: {{error}}", "Permission denied when accessing microphone: {{error}}": "マイクへのアクセス時に権限が拒否されました: {{error}}",
"Permissions": "許可", "Permissions": "許可",
"Perplexity API Key": "Perplexity API キー", "Perplexity API Key": "Perplexity API キー",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "個人化", "Personalization": "個人化",
"Pin": "ピン留め", "Pin": "ピン留め",
"Pinned": "ピン留めされています", "Pinned": "ピン留めされています",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "前の30日間", "Previous 30 days": "前の30日間",
"Previous 7 days": "前の7日間", "Previous 7 days": "前の7日間",
"Previous message": "",
"Private": "プライベート", "Private": "プライベート",
"Profile Image": "プロフィール画像", "Profile Image": "プロフィール画像",
"Prompt": "プロンプト", "Prompt": "プロンプト",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "დარწმუნებული ბრძანდებით?", "Are you sure?": "დარწმუნებული ბრძანდებით?",
"Arena Models": "არენის მოდელები", "Arena Models": "არენის მოდელები",
"Artifacts": "არტეფაქტები", "Artifacts": "არტეფაქტები",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "ინსტრუქციების ზუსტად მიჰყევით", "Followed instructions perfectly": "ინსტრუქციების ზუსტად მიჰყევით",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "ახალი პაროლი", "New Password": "ახალი პაროლი",
"New Tool": "", "New Tool": "",
"new-channel": "new-channel", "new-channel": "new-channel",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF დოკუმენტი (.pdf)", "PDF document (.pdf)": "PDF დოკუმენტი (.pdf)",
"PDF Extract Images (OCR)": "PDF იდან ამოღებული სურათები (OCR)", "PDF Extract Images (OCR)": "PDF იდან ამოღებული სურათები (OCR)",
"pending": "დარჩენილი", "pending": "დარჩენილი",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "ნებართვა უარყოფილია მიკროფონზე წვდომისას: {{error}}", "Permission denied when accessing microphone: {{error}}": "ნებართვა უარყოფილია მიკროფონზე წვდომისას: {{error}}",
"Permissions": "ნებართვები", "Permissions": "ნებართვები",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "პერსონალიზაცია", "Personalization": "პერსონალიზაცია",
"Pin": "მიმაგრება", "Pin": "მიმაგრება",
"Pinned": "მიმაგრებულია", "Pinned": "მიმაგრებულია",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "წინა 30 დღე", "Previous 30 days": "წინა 30 დღე",
"Previous 7 days": "წინა 7 დღე", "Previous 7 days": "წინა 7 დღე",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "პროფილის სურათი", "Profile Image": "პროფილის სურათი",
"Prompt": "ბრძანების შეყვანის შეხსენება", "Prompt": "ბრძანების შეყვანის შეხსენება",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "정말 이 채널을 삭제하시겠습니까?", "Are you sure you want to delete this channel?": "정말 이 채널을 삭제하시겠습니까?",
"Are you sure you want to delete this message?": "정말 이 메세지를 삭제하시겠습니까?", "Are you sure you want to delete this message?": "정말 이 메세지를 삭제하시겠습니까?",
"Are you sure you want to unarchive all archived chats?": "정말 보관된 모든 채팅을 보관 해제하시겠습니까?", "Are you sure you want to unarchive all archived chats?": "정말 보관된 모든 채팅을 보관 해제하시겠습니까?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "확실합니까?", "Are you sure?": "확실합니까?",
"Arena Models": "Arena 모델", "Arena Models": "Arena 모델",
"Artifacts": "아티팩트", "Artifacts": "아티팩트",
@ -611,6 +610,10 @@
"Folder deleted successfully": "성공적으로 폴터가 생성되었습니다", "Folder deleted successfully": "성공적으로 폴터가 생성되었습니다",
"Folder name cannot be empty.": "폴더 이름을 작성해주세요", "Folder name cannot be empty.": "폴더 이름을 작성해주세요",
"Folder name updated successfully": "성공적으로 폴더 이름이 저장되었습니다", "Folder name updated successfully": "성공적으로 폴더 이름이 저장되었습니다",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "명령을 완벽히 수행함", "Followed instructions perfectly": "명령을 완벽히 수행함",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "새 비밀번호", "New Password": "새 비밀번호",
"New Tool": "", "New Tool": "",
"new-channel": "새 채널", "new-channel": "새 채널",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "내용 없음", "No content": "내용 없음",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF 문서(.pdf)", "PDF document (.pdf)": "PDF 문서(.pdf)",
"PDF Extract Images (OCR)": "PDF 이미지 추출(OCR)", "PDF Extract Images (OCR)": "PDF 이미지 추출(OCR)",
"pending": "보류 중", "pending": "보류 중",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "미디어 장치 접근 권한이 거부되었습니다.", "Permission denied when accessing media devices": "미디어 장치 접근 권한이 거부되었습니다.",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "마이크 접근 권환이 거부되었습니다: {{error}}", "Permission denied when accessing microphone: {{error}}": "마이크 접근 권환이 거부되었습니다: {{error}}",
"Permissions": "권한", "Permissions": "권한",
"Perplexity API Key": "Perplexity API 키", "Perplexity API Key": "Perplexity API 키",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "개인화", "Personalization": "개인화",
"Pin": "고정", "Pin": "고정",
"Pinned": "고정됨", "Pinned": "고정됨",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "이전 30일", "Previous 30 days": "이전 30일",
"Previous 7 days": "이전 7일", "Previous 7 days": "이전 7일",
"Previous message": "",
"Private": "비공개", "Private": "비공개",
"Profile Image": "프로필 이미지", "Profile Image": "프로필 이미지",
"Prompt": "프롬프트", "Prompt": "프롬프트",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Are esate tikri?", "Are you sure?": "Are esate tikri?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Tobulai sekė instrukcijas", "Followed instructions perfectly": "Tobulai sekė instrukcijas",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Naujas slaptažodis", "New Password": "Naujas slaptažodis",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokumentas (.pdf)", "PDF document (.pdf)": "PDF dokumentas (.pdf)",
"PDF Extract Images (OCR)": "PDF paveikslėlių skaitymas (OCR)", "PDF Extract Images (OCR)": "PDF paveikslėlių skaitymas (OCR)",
"pending": "laukiama", "pending": "laukiama",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Leidimas atmestas bandant prisijungti prie medijos įrenginių", "Permission denied when accessing media devices": "Leidimas atmestas bandant prisijungti prie medijos įrenginių",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Leidimas naudoti mikrofoną atmestas: {{error}}", "Permission denied when accessing microphone: {{error}}": "Leidimas naudoti mikrofoną atmestas: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizacija", "Personalization": "Personalizacija",
"Pin": "Smeigtukas", "Pin": "Smeigtukas",
"Pinned": "Įsmeigta", "Pinned": "Įsmeigta",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Paskutinės 30 dienų", "Previous 30 days": "Paskutinės 30 dienų",
"Previous 7 days": "Paskutinės 7 dienos", "Previous 7 days": "Paskutinės 7 dienos",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profilio nuotrauka", "Profile Image": "Profilio nuotrauka",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Adakah anda pasti", "Are you sure?": "Adakah anda pasti",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Mengikut arahan dengan sempurna", "Followed instructions perfectly": "Mengikut arahan dengan sempurna",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Kata Laluan Baru", "New Password": "Kata Laluan Baru",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Dokumen PDF (.pdf)", "PDF document (.pdf)": "Dokumen PDF (.pdf)",
"PDF Extract Images (OCR)": "Imej Ekstrak PDF (OCR)", "PDF Extract Images (OCR)": "Imej Ekstrak PDF (OCR)",
"pending": "tertunda", "pending": "tertunda",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Tidak mendapat kebenaran apabila cuba mengakses peranti media", "Permission denied when accessing media devices": "Tidak mendapat kebenaran apabila cuba mengakses peranti media",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Tidak mendapat kebenaran apabila cuba mengakses mikrofon: {{error}}", "Permission denied when accessing microphone: {{error}}": "Tidak mendapat kebenaran apabila cuba mengakses mikrofon: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalisasi", "Personalization": "Personalisasi",
"Pin": "Pin", "Pin": "Pin",
"Pinned": "Disemat", "Pinned": "Disemat",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "30 hari sebelumnya", "Previous 30 days": "30 hari sebelumnya",
"Previous 7 days": "7 hari sebelumnya", "Previous 7 days": "7 hari sebelumnya",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Imej Profail", "Profile Image": "Imej Profail",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Er du sikker på at du vil slette denne kanalen?", "Are you sure you want to delete this channel?": "Er du sikker på at du vil slette denne kanalen?",
"Are you sure you want to delete this message?": "Er du sikker på at du vil slette denne meldingen?", "Are you sure you want to delete this message?": "Er du sikker på at du vil slette denne meldingen?",
"Are you sure you want to unarchive all archived chats?": "Er du sikker på at du vil oppheve arkiveringen av alle arkiverte chatter?", "Are you sure you want to unarchive all archived chats?": "Er du sikker på at du vil oppheve arkiveringen av alle arkiverte chatter?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Er du sikker?", "Are you sure?": "Er du sikker?",
"Arena Models": "Arena-modeller", "Arena Models": "Arena-modeller",
"Artifacts": "Artifakter", "Artifacts": "Artifakter",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Mappe slettet", "Folder deleted successfully": "Mappe slettet",
"Folder name cannot be empty.": "Mappenavn kan ikke være tomt.", "Folder name cannot be empty.": "Mappenavn kan ikke være tomt.",
"Folder name updated successfully": "Mappenavn oppdatert", "Folder name updated successfully": "Mappenavn oppdatert",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Fulgte instruksjonene perfekt", "Followed instructions perfectly": "Fulgte instruksjonene perfekt",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nytt passord", "New Password": "Nytt passord",
"New Tool": "", "New Tool": "",
"new-channel": "ny-kanal", "new-channel": "ny-kanal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF-dokument (.pdf)", "PDF document (.pdf)": "PDF-dokument (.pdf)",
"PDF Extract Images (OCR)": "Uthenting av PDF-bilder (OCR)", "PDF Extract Images (OCR)": "Uthenting av PDF-bilder (OCR)",
"pending": "avventer", "pending": "avventer",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Tilgang avslått ved bruk av medieenheter", "Permission denied when accessing media devices": "Tilgang avslått ved bruk av medieenheter",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Tilgang avslått ved bruk av mikrofonen: {{error}}", "Permission denied when accessing microphone: {{error}}": "Tilgang avslått ved bruk av mikrofonen: {{error}}",
"Permissions": "Tillatelser", "Permissions": "Tillatelser",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Tilpassing", "Personalization": "Tilpassing",
"Pin": "Fest", "Pin": "Fest",
"Pinned": "Festet", "Pinned": "Festet",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Siste 30 dager", "Previous 30 days": "Siste 30 dager",
"Previous 7 days": "Siste 7 dager", "Previous 7 days": "Siste 7 dager",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profilbilde", "Profile Image": "Profilbilde",
"Prompt": "Ledetekst", "Prompt": "Ledetekst",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Weet je zeker dat je dit kanaal wil verwijderen?", "Are you sure you want to delete this channel?": "Weet je zeker dat je dit kanaal wil verwijderen?",
"Are you sure you want to delete this message?": "Weet je zeker dat je dit bericht wil verwijderen?", "Are you sure you want to delete this message?": "Weet je zeker dat je dit bericht wil verwijderen?",
"Are you sure you want to unarchive all archived chats?": "Weet je zeker dat je alle gearchiveerde chats wil onarchiveren?", "Are you sure you want to unarchive all archived chats?": "Weet je zeker dat je alle gearchiveerde chats wil onarchiveren?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Weet je het zeker?", "Are you sure?": "Weet je het zeker?",
"Arena Models": "Arenamodellen", "Arena Models": "Arenamodellen",
"Artifacts": "Artefacten", "Artifacts": "Artefacten",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Map succesvol verwijderd", "Folder deleted successfully": "Map succesvol verwijderd",
"Folder name cannot be empty.": "Mapnaam kan niet leeg zijn", "Folder name cannot be empty.": "Mapnaam kan niet leeg zijn",
"Folder name updated successfully": "Mapnaam succesvol aangepast", "Folder name updated successfully": "Mapnaam succesvol aangepast",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Volgde instructies perfect", "Followed instructions perfectly": "Volgde instructies perfect",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nieuw Wachtwoord", "New Password": "Nieuw Wachtwoord",
"New Tool": "", "New Tool": "",
"new-channel": "nieuw-kanaal", "new-channel": "nieuw-kanaal",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF document (.pdf)", "PDF document (.pdf)": "PDF document (.pdf)",
"PDF Extract Images (OCR)": "PDF extraheer afbeeldingen (OCR)", "PDF Extract Images (OCR)": "PDF extraheer afbeeldingen (OCR)",
"pending": "wachtend", "pending": "wachtend",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Toegang geweigerd bij het toegang krijgen tot media-apparaten", "Permission denied when accessing media devices": "Toegang geweigerd bij het toegang krijgen tot media-apparaten",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Toestemming geweigerd bij toegang tot microfoon: {{error}}", "Permission denied when accessing microphone: {{error}}": "Toestemming geweigerd bij toegang tot microfoon: {{error}}",
"Permissions": "Toestemmingen", "Permissions": "Toestemmingen",
"Perplexity API Key": "Perplexity API-sleutel", "Perplexity API Key": "Perplexity API-sleutel",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalisatie", "Personalization": "Personalisatie",
"Pin": "Zet vast", "Pin": "Zet vast",
"Pinned": "Vastgezet", "Pinned": "Vastgezet",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Afgelopen 30 dagen", "Previous 30 days": "Afgelopen 30 dagen",
"Previous 7 days": "Afgelopen 7 dagen", "Previous 7 days": "Afgelopen 7 dagen",
"Previous message": "",
"Private": "Privé", "Private": "Privé",
"Profile Image": "Profielafbeelding", "Profile Image": "Profielafbeelding",
"Prompt": "Prompt", "Prompt": "Prompt",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "ਕੀ ਤੁਸੀਂ ਯਕੀਨਨ ਹੋ?", "Are you sure?": "ਕੀ ਤੁਸੀਂ ਯਕੀਨਨ ਹੋ?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "ਹਦਾਇਤਾਂ ਨੂੰ ਬਿਲਕੁਲ ਫਾਲੋ ਕੀਤਾ", "Followed instructions perfectly": "ਹਦਾਇਤਾਂ ਨੂੰ ਬਿਲਕੁਲ ਫਾਲੋ ਕੀਤਾ",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "ਨਵਾਂ ਪਾਸਵਰਡ", "New Password": "ਨਵਾਂ ਪਾਸਵਰਡ",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF ਡਾਕੂਮੈਂਟ (.pdf)", "PDF document (.pdf)": "PDF ਡਾਕੂਮੈਂਟ (.pdf)",
"PDF Extract Images (OCR)": "PDF ਚਿੱਤਰ ਕੱਢੋ (OCR)", "PDF Extract Images (OCR)": "PDF ਚਿੱਤਰ ਕੱਢੋ (OCR)",
"pending": "ਬਕਾਇਆ", "pending": "ਬਕਾਇਆ",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "", "Permission denied when accessing media devices": "",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚਣ ਸਮੇਂ ਆਗਿਆ ਰੱਦ ਕੀਤੀ ਗਈ: {{error}}", "Permission denied when accessing microphone: {{error}}": "ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚਣ ਸਮੇਂ ਆਗਿਆ ਰੱਦ ਕੀਤੀ ਗਈ: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "ਪਰਸੋਨਲਿਸ਼ਮ", "Personalization": "ਪਰਸੋਨਲਿਸ਼ਮ",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "ਪਿਛਲੇ 30 ਦਿਨ", "Previous 30 days": "ਪਿਛਲੇ 30 ਦਿਨ",
"Previous 7 days": "ਪਿਛਲੇ 7 ਦਿਨ", "Previous 7 days": "ਪਿਛਲੇ 7 ਦਿਨ",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "ਪ੍ਰੋਫਾਈਲ ਚਿੱਤਰ", "Profile Image": "ਪ੍ਰੋਫਾਈਲ ਚਿੱਤਰ",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Czy na pewno chcesz usunąć ten kanał?", "Are you sure you want to delete this channel?": "Czy na pewno chcesz usunąć ten kanał?",
"Are you sure you want to delete this message?": "Czy na pewno chcesz usunąć tę wiadomość?", "Are you sure you want to delete this message?": "Czy na pewno chcesz usunąć tę wiadomość?",
"Are you sure you want to unarchive all archived chats?": "Czy na pewno chcesz przywrócić wszystkie zapisane rozmowy?", "Are you sure you want to unarchive all archived chats?": "Czy na pewno chcesz przywrócić wszystkie zapisane rozmowy?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Czy jesteś pewien?", "Are you sure?": "Czy jesteś pewien?",
"Arena Models": "Modele Areny", "Arena Models": "Modele Areny",
"Artifacts": "Artefakty", "Artifacts": "Artefakty",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Folder został usunięty pomyślnie", "Folder deleted successfully": "Folder został usunięty pomyślnie",
"Folder name cannot be empty.": "Nazwa folderu nie może być pusta.", "Folder name cannot be empty.": "Nazwa folderu nie może być pusta.",
"Folder name updated successfully": "Nazwa folderu została zaktualizowana pomyślnie", "Folder name updated successfully": "Nazwa folderu została zaktualizowana pomyślnie",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Wykonał instrukcje idealnie", "Followed instructions perfectly": "Wykonał instrukcje idealnie",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nowe hasło", "New Password": "Nowe hasło",
"New Tool": "", "New Tool": "",
"new-channel": "nowy-kanał", "new-channel": "nowy-kanał",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Dokument PDF (.pdf)", "PDF document (.pdf)": "Dokument PDF (.pdf)",
"PDF Extract Images (OCR)": "PDF Ekstrahuj obrazy (OCR)", "PDF Extract Images (OCR)": "PDF Ekstrahuj obrazy (OCR)",
"pending": "oczekiwanie", "pending": "oczekiwanie",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Odmowa dostępu podczas uzyskiwania dostępu do urządzeń multimedialnych", "Permission denied when accessing media devices": "Odmowa dostępu podczas uzyskiwania dostępu do urządzeń multimedialnych",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Odmowa dostępu do mikrofonu: {{error}}", "Permission denied when accessing microphone: {{error}}": "Odmowa dostępu do mikrofonu: {{error}}",
"Permissions": "Uprawnienia", "Permissions": "Uprawnienia",
"Perplexity API Key": "Klucz API Perplexity", "Perplexity API Key": "Klucz API Perplexity",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizacja", "Personalization": "Personalizacja",
"Pin": "Przypnij", "Pin": "Przypnij",
"Pinned": "Przypięty", "Pinned": "Przypięty",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Ostatnie 30 dni", "Previous 30 days": "Ostatnie 30 dni",
"Previous 7 days": "Ostatnie 7 dni", "Previous 7 days": "Ostatnie 7 dni",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Zdjęcie profilowe", "Profile Image": "Zdjęcie profilowe",
"Prompt": "Wprowadź prompt: ", "Prompt": "Wprowadź prompt: ",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "Você tem certeza que deseja desarquivar todos os chats arquivados?", "Are you sure you want to unarchive all archived chats?": "Você tem certeza que deseja desarquivar todos os chats arquivados?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Você tem certeza?", "Are you sure?": "Você tem certeza?",
"Arena Models": "Arena de Modelos", "Arena Models": "Arena de Modelos",
"Artifacts": "Artefatos", "Artifacts": "Artefatos",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Pasta excluída com sucesso", "Folder deleted successfully": "Pasta excluída com sucesso",
"Folder name cannot be empty.": "Nome da pasta não pode estar vazio.", "Folder name cannot be empty.": "Nome da pasta não pode estar vazio.",
"Folder name updated successfully": "Nome da pasta atualizado com sucesso", "Folder name updated successfully": "Nome da pasta atualizado com sucesso",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Seguiu as instruções perfeitamente", "Followed instructions perfectly": "Seguiu as instruções perfeitamente",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nova Senha", "New Password": "Nova Senha",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Documento PDF (.pdf)", "PDF document (.pdf)": "Documento PDF (.pdf)",
"PDF Extract Images (OCR)": "Extrair Imagens do PDF (OCR)", "PDF Extract Images (OCR)": "Extrair Imagens do PDF (OCR)",
"pending": "pendente", "pending": "pendente",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Permissão negada ao acessar dispositivos de mídia", "Permission denied when accessing media devices": "Permissão negada ao acessar dispositivos de mídia",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}", "Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
"Permissions": "Permissões", "Permissions": "Permissões",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalização", "Personalization": "Personalização",
"Pin": "Fixar", "Pin": "Fixar",
"Pinned": "Fixado", "Pinned": "Fixado",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Últimos 30 dias", "Previous 30 days": "Últimos 30 dias",
"Previous 7 days": "Últimos 7 dias", "Previous 7 days": "Últimos 7 dias",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Imagem de Perfil", "Profile Image": "Imagem de Perfil",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Tem a certeza?", "Are you sure?": "Tem a certeza?",
"Arena Models": "", "Arena Models": "",
"Artifacts": "", "Artifacts": "",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Seguiu instruções perfeitamente", "Followed instructions perfectly": "Seguiu instruções perfeitamente",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nova Senha", "New Password": "Nova Senha",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Documento PDF (.pdf)", "PDF document (.pdf)": "Documento PDF (.pdf)",
"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)", "PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
"pending": "pendente", "pending": "pendente",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "A permissão foi negada ao aceder aos dispositivos de media", "Permission denied when accessing media devices": "A permissão foi negada ao aceder aos dispositivos de media",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "A permissão foi negada ao aceder o microfone: {{error}}", "Permission denied when accessing microphone: {{error}}": "A permissão foi negada ao aceder o microfone: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalização", "Personalization": "Personalização",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Últimos 30 dias", "Previous 30 days": "Últimos 30 dias",
"Previous 7 days": "Últimos 7 dias", "Previous 7 days": "Últimos 7 dias",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Imagem de Perfil", "Profile Image": "Imagem de Perfil",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Ești sigur că vrei să ștergi acest canal?", "Are you sure you want to delete this channel?": "Ești sigur că vrei să ștergi acest canal?",
"Are you sure you want to delete this message?": "Ești sigur că vrei să ștergi acest mesaj?", "Are you sure you want to delete this message?": "Ești sigur că vrei să ștergi acest mesaj?",
"Are you sure you want to unarchive all archived chats?": "Ești sigur că vrei să dezarhivezi toate conversațiile arhivate?", "Are you sure you want to unarchive all archived chats?": "Ești sigur că vrei să dezarhivezi toate conversațiile arhivate?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Ești sigur?", "Are you sure?": "Ești sigur?",
"Arena Models": "Arena Models", "Arena Models": "Arena Models",
"Artifacts": "Artefacte", "Artifacts": "Artefacte",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Folder șters cu succes", "Folder deleted successfully": "Folder șters cu succes",
"Folder name cannot be empty.": "Numele folderului nu poate fi gol.", "Folder name cannot be empty.": "Numele folderului nu poate fi gol.",
"Folder name updated successfully": "Numele folderului a fost actualizat cu succes", "Folder name updated successfully": "Numele folderului a fost actualizat cu succes",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "A urmat instrucțiunile perfect", "Followed instructions perfectly": "A urmat instrucțiunile perfect",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Parolă Nouă", "New Password": "Parolă Nouă",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "Document PDF (.pdf)", "PDF document (.pdf)": "Document PDF (.pdf)",
"PDF Extract Images (OCR)": "Extrage Imagini PDF (OCR)", "PDF Extract Images (OCR)": "Extrage Imagini PDF (OCR)",
"pending": "în așteptare", "pending": "în așteptare",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Permisiunea refuzată la accesarea dispozitivelor media", "Permission denied when accessing media devices": "Permisiunea refuzată la accesarea dispozitivelor media",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Permisiunea refuzată la accesarea microfonului: {{error}}", "Permission denied when accessing microphone: {{error}}": "Permisiunea refuzată la accesarea microfonului: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizare", "Personalization": "Personalizare",
"Pin": "Fixează", "Pin": "Fixează",
"Pinned": "Fixat", "Pinned": "Fixat",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Ultimele 30 de zile", "Previous 30 days": "Ultimele 30 de zile",
"Previous 7 days": "Ultimele 7 zile", "Previous 7 days": "Ultimele 7 zile",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Imagine de Profil", "Profile Image": "Imagine de Profil",
"Prompt": "", "Prompt": "",

View file

@ -35,7 +35,7 @@
"Add Connection": "Добавить соединение", "Add Connection": "Добавить соединение",
"Add Content": "Добавить контент", "Add Content": "Добавить контент",
"Add content here": "Добавить контент сюда", "Add content here": "Добавить контент сюда",
"Add Custom Parameter": "", "Add Custom Parameter": "Добавить пользовательский параметр",
"Add custom prompt": "Добавьте пользовательский промпт", "Add custom prompt": "Добавьте пользовательский промпт",
"Add Files": "Добавить файлы", "Add Files": "Добавить файлы",
"Add Group": "Добавить группу", "Add Group": "Добавить группу",
@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Вы уверены, что хотите удалить этот канал?", "Are you sure you want to delete this channel?": "Вы уверены, что хотите удалить этот канал?",
"Are you sure you want to delete this message?": "Вы уверены, что хотите удалить это сообщение?", "Are you sure you want to delete this message?": "Вы уверены, что хотите удалить это сообщение?",
"Are you sure you want to unarchive all archived chats?": "Вы уверены, что хотите разархивировать все заархивированные чаты?", "Are you sure you want to unarchive all archived chats?": "Вы уверены, что хотите разархивировать все заархивированные чаты?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "Вы уверены, что хотите изменить роль этого пользователя на **{{ROLE}}**?",
"Are you sure?": "Вы уверены?", "Are you sure?": "Вы уверены?",
"Arena Models": "Арена моделей", "Arena Models": "Арена моделей",
"Artifacts": "Артефакты", "Artifacts": "Артефакты",
@ -284,18 +283,18 @@
"Current Model": "Текущая модель", "Current Model": "Текущая модель",
"Current Password": "Текущий пароль", "Current Password": "Текущий пароль",
"Custom": "Пользовательский", "Custom": "Пользовательский",
"Custom Parameter Name": "", "Custom Parameter Name": "Название пользовательского параметра",
"Custom Parameter Value": "", "Custom Parameter Value": "Значение пользовательского параметра",
"Danger Zone": "Опасная зона", "Danger Zone": "Опасная зона",
"Dark": "Темная", "Dark": "Темная",
"Database": "База данных", "Database": "База данных",
"Datalab Marker API": "", "Datalab Marker API": "",
"Datalab Marker API Key required.": "", "Datalab Marker API Key required.": "Требуется API-ключ Datalab Marker.",
"December": "Декабрь", "December": "Декабрь",
"Default": "По умолчанию", "Default": "По умолчанию",
"Default (Open AI)": "По умолчанию (Open AI)", "Default (Open AI)": "По умолчанию (Open AI)",
"Default (SentenceTransformers)": "По умолчанию (SentenceTransformers)", "Default (SentenceTransformers)": "По умолчанию (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.": "Режим по умолчанию работает с более широким спектром моделей, вызывая инструменты один раз перед выполнением. Режим Native использует встроенные в модель возможности вызова инструментов, но требует, чтобы модель изначально поддерживала эту функцию.", "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 Model": "Модель по умолчанию", "Default Model": "Модель по умолчанию",
"Default model updated": "Модель по умолчанию обновлена", "Default model updated": "Модель по умолчанию обновлена",
"Default Models": "Модели по умолчанию", "Default Models": "Модели по умолчанию",
@ -325,7 +324,7 @@
"Deleted {{deleteModelTag}}": "Удалено {{deleteModelTag}}", "Deleted {{deleteModelTag}}": "Удалено {{deleteModelTag}}",
"Deleted {{name}}": "Удалено {{name}}", "Deleted {{name}}": "Удалено {{name}}",
"Deleted User": "Удалённый пользователь", "Deleted User": "Удалённый пользователь",
"Deployment names are required for Azure OpenAI": "Для Azure OpenAI требуются имена развертываний", "Deployment names are required for Azure OpenAI": "Для Azure OpenAI требуются названия развертываний",
"Describe Pictures in Documents": "Опишите изображения в документах", "Describe Pictures in Documents": "Опишите изображения в документах",
"Describe your knowledge base and objectives": "Опишите свою базу знаний и цели", "Describe your knowledge base and objectives": "Опишите свою базу знаний и цели",
"Description": "Описание", "Description": "Описание",
@ -337,8 +336,8 @@
"Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Прямые подключения позволяют пользователям подключаться к своим собственным конечным точкам API, совместимым с OpenAI.", "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Прямые подключения позволяют пользователям подключаться к своим собственным конечным точкам API, совместимым с OpenAI.",
"Direct Connections settings updated": "Настройки прямых подключений обновлены", "Direct Connections settings updated": "Настройки прямых подключений обновлены",
"Direct Tool Servers": "Доступ к серверам инструментов", "Direct Tool Servers": "Доступ к серверам инструментов",
"Disable Image Extraction": "", "Disable Image Extraction": "Отключить извлечение изображений",
"Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "", "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "Отключить извлечение изображений из PDF. Если включена параметр Использовать LLM, изображения будут подписаны автоматически. По умолчанию установлено значение Выкл.",
"Disabled": "Отключено", "Disabled": "Отключено",
"Discover a function": "Найти функцию", "Discover a function": "Найти функцию",
"Discover a model": "Найти модель", "Discover a model": "Найти модель",
@ -393,7 +392,7 @@
"e.g., 3, 4, 5 (leave blank for default)": "например, 3, 4, 5 (оставьте поле пустым по умолчанию)", "e.g., 3, 4, 5 (leave blank for default)": "например, 3, 4, 5 (оставьте поле пустым по умолчанию)",
"e.g., en-US,ja-JP (leave blank for auto-detect)": "например, en-US,ja-JP (оставьте поле пустым для автоматического определения)", "e.g., en-US,ja-JP (leave blank for auto-detect)": "например, en-US,ja-JP (оставьте поле пустым для автоматического определения)",
"e.g., westus (leave blank for eastus)": "например, западный (оставьте пустым для восточного)", "e.g., westus (leave blank for eastus)": "например, западный (оставьте пустым для восточного)",
"e.g.) en,fr,de": "", "e.g.) en,fr,de": "например) en,fr,de",
"Edit": "Редактировать", "Edit": "Редактировать",
"Edit Arena Model": "Изменить модель арены", "Edit Arena Model": "Изменить модель арены",
"Edit Channel": "Редактировать канал", "Edit Channel": "Редактировать канал",
@ -428,7 +427,7 @@
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Убедитесь, что ваш CSV-файл включает в себя 4 столбца в следующем порядке: Имя, Электронная почта, Пароль, Роль.", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Убедитесь, что ваш CSV-файл включает в себя 4 столбца в следующем порядке: Имя, Электронная почта, Пароль, Роль.",
"Enter {{role}} message here": "Введите сообщение {{role}} здесь", "Enter {{role}} message here": "Введите сообщение {{role}} здесь",
"Enter a detail about yourself for your LLMs to recall": "Введите детали о себе, чтобы LLMs могли запомнить", "Enter a detail about yourself for your LLMs to recall": "Введите детали о себе, чтобы LLMs могли запомнить",
"Enter a title for the pending user info overlay. Leave empty for default.": "Введите заголовок для ожидаемого отображения информации о пользователе. Оставьте поле пустым для параметра по умолчанию.", "Enter a title for the pending user info overlay. Leave empty for default.": "Введите заголовок информационного оверлея для ожидающего пользователя. Оставьте поле пустым для параметра по умолчанию.",
"Enter a watermark for the response. Leave empty for none.": "Укажите водяной знак для ответа. Оставьте пустым чтобы не было никакого.", "Enter a watermark for the response. Leave empty for none.": "Укажите водяной знак для ответа. Оставьте пустым чтобы не было никакого.",
"Enter api auth string (e.g. username:password)": "Введите строку авторизации api (например, username:password)", "Enter api auth string (e.g. username:password)": "Введите строку авторизации api (например, username:password)",
"Enter Application DN": "Введите ND приложения", "Enter Application DN": "Введите ND приложения",
@ -443,8 +442,8 @@
"Enter Chunk Overlap": "Введите перекрытие фрагмента", "Enter Chunk Overlap": "Введите перекрытие фрагмента",
"Enter Chunk Size": "Введите размер фрагмента", "Enter Chunk Size": "Введите размер фрагмента",
"Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Введите пары \"token:bias_value\", разделенные запятыми (пример: 5432:100, 413:-100).", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Введите пары \"token:bias_value\", разделенные запятыми (пример: 5432:100, 413:-100).",
"Enter content for the pending user info overlay. Leave empty for default.": "Введите содержимое для отложенного отображения информации о пользователе. Оставьте поле пустым для параметра по умолчанию.", "Enter content for the pending user info overlay. Leave empty for default.": "Введите содержимое информационного оверлея для ожидающего пользователя. Оставьте поле пустым для параметра по умолчанию.",
"Enter Datalab Marker API Key": "", "Enter Datalab Marker API Key": "Введите API-ключ Datalab Marker",
"Enter description": "Введите описание", "Enter description": "Введите описание",
"Enter Docling OCR Engine": "Введите Docling OCR Engine", "Enter Docling OCR Engine": "Введите Docling OCR Engine",
"Enter Docling OCR Language(s)": "Введите языки для Docling OCR", "Enter Docling OCR Language(s)": "Введите языки для Docling OCR",
@ -476,7 +475,7 @@
"Enter Model ID": "Введите ID модели", "Enter Model ID": "Введите ID модели",
"Enter model tag (e.g. {{modelTag}})": "Введите тег модели (например, {{modelTag}})", "Enter model tag (e.g. {{modelTag}})": "Введите тег модели (например, {{modelTag}})",
"Enter Mojeek Search API Key": "Введите ключ API поиска Mojeek", "Enter Mojeek Search API Key": "Введите ключ API поиска Mojeek",
"Enter name": "Введите название", "Enter name": "Введите имя",
"Enter New Password": "Введите новый пароль", "Enter New Password": "Введите новый пароль",
"Enter Number of Steps (e.g. 50)": "Введите количество шагов (например, 50)", "Enter Number of Steps (e.g. 50)": "Введите количество шагов (например, 50)",
"Enter Perplexity API Key": "Введите ключ API Perplexity", "Enter Perplexity API Key": "Введите ключ API Perplexity",
@ -508,7 +507,7 @@
"Enter Tavily Extract Depth": "Укажите глубину извлечения Tavily", "Enter Tavily Extract Depth": "Укажите глубину извлечения Tavily",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Введите общедоступный URL вашего WebUI. Этот URL будет использоваться для создания ссылок в уведомлениях.", "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Введите общедоступный URL вашего WebUI. Этот URL будет использоваться для создания ссылок в уведомлениях.",
"Enter the URL of the function to import": "Введите URL-адрес функции для импорта", "Enter the URL of the function to import": "Введите URL-адрес функции для импорта",
"Enter the URL to import": "", "Enter the URL to import": "Введите URL-адрес для импорта",
"Enter Tika Server URL": "Введите URL-адрес сервера Tika", "Enter Tika Server URL": "Введите URL-адрес сервера Tika",
"Enter timeout in seconds": "Введите время ожидания в секундах", "Enter timeout in seconds": "Введите время ожидания в секундах",
"Enter to Send": "Enter для отправки", "Enter to Send": "Enter для отправки",
@ -609,11 +608,15 @@
"Fluidly stream large external response chunks": "Плавная потоковая передача больших фрагментов внешних ответов", "Fluidly stream large external response chunks": "Плавная потоковая передача больших фрагментов внешних ответов",
"Focus chat input": "Фокус ввода чата", "Focus chat input": "Фокус ввода чата",
"Folder deleted successfully": "Папка успешно удалена", "Folder deleted successfully": "Папка успешно удалена",
"Folder name cannot be empty.": "Имя папки не может быть пустым.", "Folder name cannot be empty.": "Название папки не может быть пустым.",
"Folder name updated successfully": "Имя папки успешно обновлено", "Folder name updated successfully": "Название папки успешно обновлено",
"Followed instructions perfectly": "Идеально соответствует инструкциям", "Follow up": "Продолжить",
"Force OCR": "", "Follow Up Generation": "Генерация продолжения",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Follow Up Generation Prompt": "Промпт генерации продолжения",
"Follow-Up Auto-Generation": "Автоматическая генерация продолжения",
"Followed instructions perfectly": "В точности следовал инструкциям",
"Force OCR": "Принудительное OCR",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "Принудительное OCR на всех страницах PDF-файла. Это может привести к ухудшению результатов, если в ваших PDF-файлах есть хороший текст. По умолчанию установлено значение Выкл.",
"Forge new paths": "Прокладывайте новые пути", "Forge new paths": "Прокладывайте новые пути",
"Form": "Форма", "Form": "Форма",
"Format your variables using brackets like this:": "Отформатируйте переменные, используя такие : скобки", "Format your variables using brackets like this:": "Отформатируйте переменные, используя такие : скобки",
@ -625,10 +628,10 @@
"Function deleted successfully": "Функция успешно удалена", "Function deleted successfully": "Функция успешно удалена",
"Function Description": "Описание Функции", "Function Description": "Описание Функции",
"Function ID": "ID Функции", "Function ID": "ID Функции",
"Function imported successfully": "", "Function imported successfully": "Функция успешно импортирована",
"Function is now globally disabled": "Функция теперь глобально отключена", "Function is now globally disabled": "Функция теперь глобально отключена",
"Function is now globally enabled": "Функция теперь глобально включена", "Function is now globally enabled": "Функция теперь глобально включена",
"Function Name": "Имя Функции", "Function Name": "Название Функции",
"Function updated successfully": "Функция успешно обновлена", "Function updated successfully": "Функция успешно обновлена",
"Functions": "Функции", "Functions": "Функции",
"Functions allow arbitrary code execution.": "Функции позволяют выполнять произвольный код.", "Functions allow arbitrary code execution.": "Функции позволяют выполнять произвольный код.",
@ -742,7 +745,7 @@
"Landing Page Mode": "Режим целевой страницы", "Landing Page Mode": "Режим целевой страницы",
"Language": "Язык", "Language": "Язык",
"Language Locales": "Языковые особенности", "Language Locales": "Языковые особенности",
"Languages": "", "Languages": "Языки",
"Last Active": "Последняя активность", "Last Active": "Последняя активность",
"Last Modified": "Последнее изменение", "Last Modified": "Последнее изменение",
"Last reply": "Последний ответ", "Last reply": "Последний ответ",
@ -820,7 +823,7 @@
"Model Filtering": "Фильтрация Моделей", "Model Filtering": "Фильтрация Моделей",
"Model ID": "ID Модели", "Model ID": "ID Модели",
"Model IDs": "IDs Модели", "Model IDs": "IDs Модели",
"Model Name": "Имя Модели", "Model Name": "Название Модели",
"Model not selected": "Модель не выбрана", "Model not selected": "Модель не выбрана",
"Model Params": "Параметры модели", "Model Params": "Параметры модели",
"Model Permissions": "Разрешения Модели", "Model Permissions": "Разрешения Модели",
@ -844,8 +847,9 @@
"New Function": "Новая функция", "New Function": "Новая функция",
"New Note": "Новая заметка", "New Note": "Новая заметка",
"New Password": "Новый пароль", "New Password": "Новый пароль",
"New Tool": "", "New Tool": "Новый инструмент",
"new-channel": "", "new-channel": "",
"Next message": "Следующее сообщение",
"No chats found for this user.": "Для этого пользователя не найдено ни одного чата.", "No chats found for this user.": "Для этого пользователя не найдено ни одного чата.",
"No chats found.": "Не найдено ни одного чата", "No chats found.": "Не найдено ни одного чата",
"No content": "Нет контента", "No content": "Нет контента",
@ -918,23 +922,26 @@
"Other": "Прочее", "Other": "Прочее",
"OUTPUT": "", "OUTPUT": "",
"Output format": "Формат вывода", "Output format": "Формат вывода",
"Output Format": "", "Output Format": "Формат Вывода",
"Overview": "Обзор", "Overview": "Обзор",
"page": "страница", "page": "страница",
"Paginate": "", "Paginate": "Разбивка на страницы",
"Parameters": "Параметры", "Parameters": "Параметры",
"Password": "Пароль", "Password": "Пароль",
"Paste Large Text as File": "Вставить большой текст как файл", "Paste Large Text as File": "Вставить большой текст как файл",
"PDF document (.pdf)": "PDF-документ (.pdf)", "PDF document (.pdf)": "PDF-документ (.pdf)",
"PDF Extract Images (OCR)": "Извлечение изображений из PDF (OCR)", "PDF Extract Images (OCR)": "Извлечение изображений из PDF (OCR)",
"pending": "ожидающий", "pending": "ожидающий",
"Pending User Overlay Content": "Ожидание контента пользовательского оверлея", "Pending": "Ожидающий",
"Pending User Overlay Title": "Ожидание заголовка пользовательского оверлея", "Pending User Overlay Content": "Содержимое оверлея ожидающего пользователя",
"Pending User Overlay Title": "Заголовк оверлея ожидающего пользователя",
"Permission denied when accessing media devices": "Отказано в разрешении на доступ к мультимедийным устройствам", "Permission denied when accessing media devices": "Отказано в разрешении на доступ к мультимедийным устройствам",
"Permission denied when accessing microphone": "Отказано в разрешении на доступ к микрофону", "Permission denied when accessing microphone": "Отказано в разрешении на доступ к микрофону",
"Permission denied when accessing microphone: {{error}}": "Отказано в разрешении на доступ к микрофону: {{error}}", "Permission denied when accessing microphone: {{error}}": "Отказано в разрешении на доступ к микрофону: {{error}}",
"Permissions": "Разрешения", "Permissions": "Разрешения",
"Perplexity API Key": "Ключ API для Perplexity", "Perplexity API Key": "Ключ API для Perplexity",
"Perplexity Model": "Модель Perplexity",
"Perplexity Search Context Usage": "Использование контекста поиска Perplexity",
"Personalization": "Персонализация", "Personalization": "Персонализация",
"Pin": "Закрепить", "Pin": "Закрепить",
"Pinned": "Закреплено", "Pinned": "Закреплено",
@ -965,6 +972,7 @@
"Preview": "Предпросмотр", "Preview": "Предпросмотр",
"Previous 30 days": "Предыдущие 30 дней", "Previous 30 days": "Предыдущие 30 дней",
"Previous 7 days": "Предыдущие 7 дней", "Previous 7 days": "Предыдущие 7 дней",
"Previous message": "Предыдущее сообщение",
"Private": "Частное", "Private": "Частное",
"Profile Image": "Изображение профиля", "Profile Image": "Изображение профиля",
"Prompt": "Промпт", "Prompt": "Промпт",
@ -986,7 +994,7 @@
"Re-rank models by topic similarity": "Повторное ранжирование моделей по сходству тем", "Re-rank models by topic similarity": "Повторное ранжирование моделей по сходству тем",
"Read": "Прочитать", "Read": "Прочитать",
"Read Aloud": "Прочитать вслух", "Read Aloud": "Прочитать вслух",
"Reasoning Effort": "Усилие рассуждения", "Reasoning Effort": "",
"Record": "Запись", "Record": "Запись",
"Record voice": "Записать голос", "Record voice": "Записать голос",
"Redirecting you to Open WebUI Community": "Перенаправляем вас в сообщество OpenWebUI", "Redirecting you to Open WebUI Community": "Перенаправляем вас в сообщество OpenWebUI",
@ -1060,7 +1068,7 @@
"Searxng Query URL": "URL-адрес запроса Searxng", "Searxng Query URL": "URL-адрес запроса Searxng",
"See readme.md for instructions": "Смотрите readme.md для инструкций", "See readme.md for instructions": "Смотрите readme.md для инструкций",
"See what's new": "Посмотреть, что нового", "See what's new": "Посмотреть, что нового",
"Seed": "Сид", "Seed": "",
"Select a base model": "Выберите базовую модель", "Select a base model": "Выберите базовую модель",
"Select a engine": "Выберите движок", "Select a engine": "Выберите движок",
"Select a function": "Выберите функцию", "Select a function": "Выберите функцию",
@ -1128,11 +1136,11 @@
"Sign Out": "Выйти", "Sign Out": "Выйти",
"Sign up": "Зарегистрироваться", "Sign up": "Зарегистрироваться",
"Sign up to {{WEBUI_NAME}}": "Регистрация в {{WEBUI_NAME}}", "Sign up to {{WEBUI_NAME}}": "Регистрация в {{WEBUI_NAME}}",
"Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to True.": "", "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to True.": "Значительно повышает точность за счет использования LLM для улучшения работы с таблицами, формами, встроенной математикой и распознавания макета. Увеличивает задержку. По умолчанию установлено значение Вкл.",
"Signing in to {{WEBUI_NAME}}": "Зарегистрироваться в {{WEBUI_NAME}}", "Signing in to {{WEBUI_NAME}}": "Зарегистрироваться в {{WEBUI_NAME}}",
"sk-1234": "", "sk-1234": "",
"Skip Cache": "", "Skip Cache": "Пропустить кэширование",
"Skip the cache and re-run the inference. Defaults to False.": "", "Skip the cache and re-run the inference. Defaults to False.": "Пропустить кэширование и перезапустить вывод. По умолчанию установлено значение Выкл.",
"Sougou Search API sID": "", "Sougou Search API sID": "",
"Sougou Search API SK": "", "Sougou Search API SK": "",
"Source": "Источник", "Source": "Источник",
@ -1140,10 +1148,10 @@
"Speech recognition error: {{error}}": "Ошибка распознавания речи: {{error}}", "Speech recognition error: {{error}}": "Ошибка распознавания речи: {{error}}",
"Speech-to-Text Engine": "Система распознавания речи", "Speech-to-Text Engine": "Система распознавания речи",
"Stop": "Остановить", "Stop": "Остановить",
"Stop Sequence": "Последовательность остановки", "Stop Sequence": "",
"Stream Chat Response": "Потоковый вывод ответа", "Stream Chat Response": "Потоковый вывод ответа",
"Strip Existing OCR": "", "Strip Existing OCR": "Удалять существующие OCR",
"Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "", "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "Удалять существующий текст OCR из PDF и перезапустить OCR. Игнорируется если Принудительное OCR включено. По умолчанию установлено значение Выкл.",
"STT Model": "Модель распознавания речи", "STT Model": "Модель распознавания речи",
"STT Settings": "Настройки распознавания речи", "STT Settings": "Настройки распознавания речи",
"Stylized PDF Export": "Стилизованный экспорт в формате PDF", "Stylized PDF Export": "Стилизованный экспорт в формате PDF",
@ -1168,7 +1176,7 @@
"Tavily API Key": "Ключ API Tavily", "Tavily API Key": "Ключ API Tavily",
"Tavily Extract Depth": "Глубина извлечения Tavily", "Tavily Extract Depth": "Глубина извлечения Tavily",
"Tell us more:": "Пожалуйста, расскажите нам больше:", "Tell us more:": "Пожалуйста, расскажите нам больше:",
"Temperature": "Температура", "Temperature": "",
"Temporary Chat": "Временный чат", "Temporary Chat": "Временный чат",
"Text Splitter": "Разделитель текста", "Text Splitter": "Разделитель текста",
"Text-to-Speech Engine": "Система синтеза речи", "Text-to-Speech Engine": "Система синтеза речи",
@ -1184,7 +1192,7 @@
"The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "В настоящее время таблица лидеров находится в стадии бета-тестирования, и мы можем скорректировать расчеты рейтинга по мере доработки алгоритма.", "The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "В настоящее время таблица лидеров находится в стадии бета-тестирования, и мы можем скорректировать расчеты рейтинга по мере доработки алгоритма.",
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Максимальный размер файла в МБ. Если размер файла превысит это ограничение, файл не будет загружен.", "The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Максимальный размер файла в МБ. Если размер файла превысит это ограничение, файл не будет загружен.",
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "Максимальное количество файлов, которые могут быть использованы одновременно в чате. Если количество файлов превысит это ограничение, файлы не будут загружены.", "The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "Максимальное количество файлов, которые могут быть использованы одновременно в чате. Если количество файлов превысит это ограничение, файлы не будут загружены.",
"The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'.": "", "The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'.": "Формат вывода текста. Может быть 'json', 'markdown', или 'html'. По умолчанию 'markdown'.",
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Оценка должна быть значением между 0,0 (0%) и 1,0 (100%).", "The score should be a value between 0.0 (0%) and 1.0 (100%).": "Оценка должна быть значением между 0,0 (0%) и 1,0 (100%).",
"The temperature of the model. Increasing the temperature will make the model answer more creatively.": "Температура модели. При повышении температуры модель будет отвечать более творчески.", "The temperature of the model. Increasing the temperature will make the model answer more creatively.": "Температура модели. При повышении температуры модель будет отвечать более творчески.",
"Theme": "Тема", "Theme": "Тема",
@ -1206,7 +1214,7 @@
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Это сбросит базу знаний и синхронизирует все файлы. Хотите продолжить?", "This will reset the knowledge base and sync all files. Do you wish to continue?": "Это сбросит базу знаний и синхронизирует все файлы. Хотите продолжить?",
"Thorough explanation": "Подробное объяснение", "Thorough explanation": "Подробное объяснение",
"Thought for {{DURATION}}": "Рассуждаю {{DURATION}}", "Thought for {{DURATION}}": "Рассуждаю {{DURATION}}",
"Thought for {{DURATION}} seconds": "Рассуждал {{DURATION}} секунд(ы)", "Thought for {{DURATION}} seconds": "Рассуждение заняло {{DURATION}} секунд(ы)",
"Tika": "Tika", "Tika": "Tika",
"Tika Server URL required.": "Требуется URL-адрес сервера Tika.", "Tika Server URL required.": "Требуется URL-адрес сервера Tika.",
"Tiktoken": "", "Tiktoken": "",
@ -1218,7 +1226,7 @@
"Title Generation": "Генерация заголовка", "Title Generation": "Генерация заголовка",
"Title Generation Prompt": "Промпт для генерации заголовка", "Title Generation Prompt": "Промпт для генерации заголовка",
"TLS": "", "TLS": "",
"To access the available model names for downloading,": "Чтобы получить доступ к доступным для загрузки именам моделей,", "To access the available model names for downloading,": "Чтобы получить доступ к доступным для загрузки названиям моделей,",
"To access the GGUF models available for downloading,": "Чтобы получить доступ к моделям GGUF, доступным для загрузки,", "To access the GGUF models available for downloading,": "Чтобы получить доступ к моделям GGUF, доступным для загрузки,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Чтобы получить доступ к WebUI, пожалуйста, обратитесь к администратору. Администраторы могут управлять статусами пользователей из панели администратора.", "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Чтобы получить доступ к WebUI, пожалуйста, обратитесь к администратору. Администраторы могут управлять статусами пользователей из панели администратора.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Чтобы прикрепить сюда базу знаний, сначала добавьте её в \"Знания\" рабочего пространства.", "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Чтобы прикрепить сюда базу знаний, сначала добавьте её в \"Знания\" рабочего пространства.",
@ -1239,7 +1247,7 @@
"Tool Description": "Описание Инструмента", "Tool Description": "Описание Инструмента",
"Tool ID": "ID Инструмента", "Tool ID": "ID Инструмента",
"Tool imported successfully": "Инструмент успешно импортирован", "Tool imported successfully": "Инструмент успешно импортирован",
"Tool Name": "Имя Инструмента", "Tool Name": "Название Инструмента",
"Tool Servers": "Сервер Инструмента", "Tool Servers": "Сервер Инструмента",
"Tool updated successfully": "Инструмент успешно обновлен", "Tool updated successfully": "Инструмент успешно обновлен",
"Tools": "Инструменты", "Tools": "Инструменты",
@ -1292,7 +1300,7 @@
"Use Gravatar": "Использовать Gravatar", "Use Gravatar": "Использовать Gravatar",
"Use groups to group your users and assign permissions.": "Используйте группы, чтобы группировать пользователей и назначать разрешения.", "Use groups to group your users and assign permissions.": "Используйте группы, чтобы группировать пользователей и назначать разрешения.",
"Use Initials": "Использовать инициалы", "Use Initials": "Использовать инициалы",
"Use LLM": "", "Use LLM": "Использовать LLM",
"Use no proxy to fetch page contents.": "Не используйте прокси-сервер для получения содержимого страницы.", "Use no proxy to fetch page contents.": "Не используйте прокси-сервер для получения содержимого страницы.",
"Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "Используйте прокси-сервер, обозначенный переменными окружения http_proxy и https_proxy, для получения содержимого страницы.", "Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "Используйте прокси-сервер, обозначенный переменными окружения http_proxy и https_proxy, для получения содержимого страницы.",
"user": "пользователь", "user": "пользователь",
@ -1343,8 +1351,8 @@
"What are you working on?": "Над чем вы работаете?", "What are you working on?": "Над чем вы работаете?",
"Whats New in": "Что нового в", "Whats New in": "Что нового в",
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Если эта функция включена, модель будет отвечать на каждое сообщение чата в режиме реального времени, генерируя ответ, как только пользователь отправит сообщение. Этот режим полезен для приложений живого чата, но может повлиять на производительность на более медленном оборудовании.", "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Если эта функция включена, модель будет отвечать на каждое сообщение чата в режиме реального времени, генерируя ответ, как только пользователь отправит сообщение. Этот режим полезен для приложений живого чата, но может повлиять на производительность на более медленном оборудовании.",
"wherever you are": "где бы ты ни был", "wherever you are": "где бы вы ни были",
"Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Следует ли разбивать выходные данные на страницы. Каждая страница будет разделена горизонтальной линией и номером страницы. По умолчанию установлено значение Выкл.",
"Whisper (Local)": "Whisper (Локально)", "Whisper (Local)": "Whisper (Локально)",
"Why?": "Почему?", "Why?": "Почему?",
"Widescreen Mode": "Широкоэкранный режим", "Widescreen Mode": "Широкоэкранный режим",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "", "Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "", "Are you sure you want to delete this message?": "",
"Are you sure you want to unarchive all archived chats?": "", "Are you sure you want to unarchive all archived chats?": "",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Ste si istý?", "Are you sure?": "Ste si istý?",
"Arena Models": "Arena modely", "Arena Models": "Arena modely",
"Artifacts": "Artefakty", "Artifacts": "Artefakty",
@ -611,6 +610,10 @@
"Folder deleted successfully": "Priečinok bol úspešne vymazaný", "Folder deleted successfully": "Priečinok bol úspešne vymazaný",
"Folder name cannot be empty.": "Názov priečinka nesmie byť prázdny.", "Folder name cannot be empty.": "Názov priečinka nesmie byť prázdny.",
"Folder name updated successfully": "Názov priečinka bol úspešne aktualizovaný.", "Folder name updated successfully": "Názov priečinka bol úspešne aktualizovaný.",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Dodržal pokyny dokonale.", "Followed instructions perfectly": "Dodržal pokyny dokonale.",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Nové heslo", "New Password": "Nové heslo",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF dokument (.pdf)", "PDF document (.pdf)": "PDF dokument (.pdf)",
"PDF Extract Images (OCR)": "Extrahovanie obrázkov z PDF (OCR)", "PDF Extract Images (OCR)": "Extrahovanie obrázkov z PDF (OCR)",
"pending": "čaká na vybavenie", "pending": "čaká na vybavenie",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Odmietnutie povolenia pri prístupe k mediálnym zariadeniam", "Permission denied when accessing media devices": "Odmietnutie povolenia pri prístupe k mediálnym zariadeniam",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Oprávnenie zamietnuté pri prístupe k mikrofónu: {{error}}", "Permission denied when accessing microphone: {{error}}": "Oprávnenie zamietnuté pri prístupe k mikrofónu: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Personalizácia", "Personalization": "Personalizácia",
"Pin": "", "Pin": "",
"Pinned": "", "Pinned": "",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Predchádzajúcich 30 dní", "Previous 30 days": "Predchádzajúcich 30 dní",
"Previous 7 days": "Predchádzajúcich 7 dní", "Previous 7 days": "Predchádzajúcich 7 dní",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Profilový obrázok", "Profile Image": "Profilový obrázok",
"Prompt": "", "Prompt": "",

View file

@ -108,7 +108,6 @@
"Are you sure you want to delete this channel?": "Да ли сигурно желите обрисати овај канал?", "Are you sure you want to delete this channel?": "Да ли сигурно желите обрисати овај канал?",
"Are you sure you want to delete this message?": "Да ли сигурно желите обрисати ову поруку?", "Are you sure you want to delete this message?": "Да ли сигурно желите обрисати ову поруку?",
"Are you sure you want to unarchive all archived chats?": "Да ли сигурно желите деархивирати све архиве?", "Are you sure you want to unarchive all archived chats?": "Да ли сигурно желите деархивирати све архиве?",
"Are you sure you want to update this user's role to **{{ROLE}}**?": "",
"Are you sure?": "Да ли сте сигурни?", "Are you sure?": "Да ли сте сигурни?",
"Arena Models": "Модели са Арене", "Arena Models": "Модели са Арене",
"Artifacts": "Артефакти", "Artifacts": "Артефакти",
@ -611,6 +610,10 @@
"Folder deleted successfully": "", "Folder deleted successfully": "",
"Folder name cannot be empty.": "", "Folder name cannot be empty.": "",
"Folder name updated successfully": "", "Folder name updated successfully": "",
"Follow up": "",
"Follow Up Generation": "",
"Follow Up Generation Prompt": "",
"Follow-Up Auto-Generation": "",
"Followed instructions perfectly": "Упутства су савршено праћена", "Followed instructions perfectly": "Упутства су савршено праћена",
"Force OCR": "", "Force OCR": "",
"Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "",
@ -846,6 +849,7 @@
"New Password": "Нова лозинка", "New Password": "Нова лозинка",
"New Tool": "", "New Tool": "",
"new-channel": "", "new-channel": "",
"Next message": "",
"No chats found for this user.": "", "No chats found for this user.": "",
"No chats found.": "", "No chats found.": "",
"No content": "", "No content": "",
@ -928,6 +932,7 @@
"PDF document (.pdf)": "PDF документ (.pdf)", "PDF document (.pdf)": "PDF документ (.pdf)",
"PDF Extract Images (OCR)": "Извлачење PDF слика (OCR)", "PDF Extract Images (OCR)": "Извлачење PDF слика (OCR)",
"pending": "на чекању", "pending": "на чекању",
"Pending": "",
"Pending User Overlay Content": "", "Pending User Overlay Content": "",
"Pending User Overlay Title": "", "Pending User Overlay Title": "",
"Permission denied when accessing media devices": "Приступ медијским уређајима одбијен", "Permission denied when accessing media devices": "Приступ медијским уређајима одбијен",
@ -935,6 +940,8 @@
"Permission denied when accessing microphone: {{error}}": "Приступ микрофону је одбијен: {{error}}", "Permission denied when accessing microphone: {{error}}": "Приступ микрофону је одбијен: {{error}}",
"Permissions": "", "Permissions": "",
"Perplexity API Key": "", "Perplexity API Key": "",
"Perplexity Model": "",
"Perplexity Search Context Usage": "",
"Personalization": "Прилагођавање", "Personalization": "Прилагођавање",
"Pin": "Закачи", "Pin": "Закачи",
"Pinned": "Закачено", "Pinned": "Закачено",
@ -965,6 +972,7 @@
"Preview": "", "Preview": "",
"Previous 30 days": "Претходних 30 дана", "Previous 30 days": "Претходних 30 дана",
"Previous 7 days": "Претходних 7 дана", "Previous 7 days": "Претходних 7 дана",
"Previous message": "",
"Private": "", "Private": "",
"Profile Image": "Слика профила", "Profile Image": "Слика профила",
"Prompt": "", "Prompt": "",

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